Learn to build JAX-RS 2.0 HATEOAS links in REST resources using it’s javax.ws.rs.core.Link
, javax.ws.rs.core.UriBuilder
and javax.ws.rs.core.UriInfo
classes. RESTEasy 3.1.2.Final is used as reference implementation for JAX-RS 2.0.
Table of Contents Usage of UriInfo, UriBuilder and Link Classes Add Link.JaxbAdapter in model classes Injecting links in resource representations Demo
Usage of UriInfo, UriBuilder and Link Classes
HATEOAS structure itself is under discussions in lots of forums and different people suggest different approaches to build links in REST resource representations. JAX-RS 2.0 also does not have any direct support to build these links. Though you can use it’s helper classes to build the links, the way you want.
-
javax.ws.rs.core.UriBuilder
The
UriBuilder
class allows you to construct a URI step by step using builder pattern. The values can contain template parameters i.e./resource/{id}
. Hereid
is template parameter.The
build()
methods create the actual URI. Before building the URI, though, any template parameters you have defined must be filled in. -
javax.ws.rs.core.UriInfo
Many times you will not know the base URI or relative URI where your resource will be present. In this case, you can use
UriInfo
class.UriInfo
instances are pre-initialized with the base URI and the URI used to invoke the current HTTP request. -
javax.ws.rs.core.Link
JAX-RS 2.0 introduces
Link
class, which serves as a representation of Web Link defined in RFC 5988. It helps inimplementing HATEOAS using JAX-RS 2.0
. It’s parameters such as rel or type provide additional meta-data about link.
Add Link.JaxbAdapter in model classes
To add a link in resource representation, you need to add Link
element in model class.
Configurations.java
@XmlRootElement(name = "configurations") @XmlAccessorType(XmlAccessType.FIELD) public class Configurations { @XmlAttribute private Integer size; @XmlJavaTypeAdapter(Link.JaxbAdapter.class) @XmlElement private Link link; @XmlElement private List<Configuration> configurations; //Getters and Setters are removed for limiting the text. Add them when running the code.
Configuration.java
@XmlRootElement(name="configuration") @XmlAccessorType(XmlAccessType.FIELD) public class Configuration { @XmlAttribute private Integer id; @XmlJavaTypeAdapter(Link.JaxbAdapter.class) @XmlElement private Link link; @XmlElement private String content; @XmlElement private Status status; //Getters and Setters are removed for limiting the text. }
Link.JaxbAdapter
is an implementation of JAXB XmlAdapter
that maps the JAX-RS Link
type to a value that can be marshalled and unmarshalled by JAXB.
Injecting HATEOAS links in resource representations
Now, you need to build and inject the links in these resource representations or model classes.
package net.restfulapi.app.rest.service; import java.util.List; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.Link; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; import net.restfulapi.app.dao.ConfigurationDB; import net.restfulapi.app.rest.domain.Configuration; import net.restfulapi.app.rest.domain.Configurations; import net.restfulapi.app.rest.domain.common.Status; @Path("/configurations") @Produces("application/xml") public class ConfigurationResource { @Context UriInfo uriInfo; @GET public Configurations getConfigurations() { List<Configuration> list = ConfigurationDB.getAllConfigurations(); Configurations configurations = new Configurations(); configurations.setConfigurations(list); configurations.setSize(list.size()); //Set link for primary collection Link link = Link.fromUri(uriInfo.getPath()).rel("uri").build(); configurations.setLink(link); //Set links in configuration items for(Configuration c: list){ Link lnk = Link.fromUri(uriInfo.getPath() + "/" + c.getId()).rel("self").build(); c.setLink(lnk); } return configurations; } @GET @Path("/{id}") public Configuration getConfigurationById(@PathParam("id") Integer id){ Configuration config = ConfigurationDB.getConfiguration(id); if(config != null){ UriBuilder builder = UriBuilder.fromResource(ConfigurationResource.class) .path(ConfigurationResource.class, "getConfigurationById"); Link link = Link.fromUri(builder.build(id)).rel("self").build(); config.setLink(link); } return config; } static { ConfigurationDB.createConfiguration("Some Content", Status.ACTIVE); ConfigurationDB.createConfiguration("Some More Content", Status.INACTIVE); } }
Demo
Hit the URL: http://localhost:8080/NetworkManagement/network-management/configurations

Hit the URL: http://localhost:8080/NetworkManagement/network-management/configurations/1

Drop me your questions in comments section.
Happy Learning !!
Comments