{"id":88889,"date":"2019-02-26T07:00:47","date_gmt":"2019-02-26T05:00:47","guid":{"rendered":"https:\/\/www.javacodegeeks.com\/?p=88889"},"modified":"2019-02-25T12:06:48","modified_gmt":"2019-02-25T10:06:48","slug":"hypermedia-apis-support-jax-rs-openapi","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html","title":{"rendered":"The Hypermedia APIs support in JAX-RS and OpenAPI: a long way to go"},"content":{"rendered":"<p>Sooner or later, most of the developers who actively work on <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST(ful)<\/a> web services and APIs stumble upon this truly extraterrestrial thing called <a href=\"https:\/\/en.wikipedia.org\/wiki\/HATEOAS\">HATEOAS<\/a>: <b>Hypertext As The Engine Of Application State<\/b>. The curiosity of what <a href=\"https:\/\/en.wikipedia.org\/wiki\/HATEOAS\">HATEOAS<\/a> is and how it relates to <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST<\/a> would eventually lead to discovery of the <a href=\"https:\/\/martinfowler.com\/articles\/richardsonMaturityModel.html\">Richardson Maturity Model<\/a> which demystifies the industry definitions of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">RESTful<\/a>. The latter comes as an enlightenment, raising the question however: have we been doing <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST<\/a> wrong all these years?<\/p>\n<p>Let us try to answer this question from the different perspectives. The <a href=\"https:\/\/en.wikipedia.org\/wiki\/HATEOAS\">HATEOAS<\/a> is one of the core <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST<\/a> architectural constraints. From this perspective, the answer is &#8220;yes&#8221;, in order to claim <a href=\"https:\/\/en.wikipedia.org\/wiki\/Representational_state_transfer\">REST<\/a> compliance, the web service or API should support that. Nonetheless, if you look around (or even consult your past or present experience), you may find out that the majority of the web services and APIs are just <a href=\"https:\/\/en.wikipedia.org\/wiki\/Create,_read,_update_and_delete\">CRUD<\/a> wrappers around the domain models, with no <a href=\"https:\/\/en.wikipedia.org\/wiki\/HATEOAS\">HATEOAS<\/a> support whatsoever. Why is that? Probably, there is more than one reason, but from the developer&#8217;s toolbox perspective, the backing of <a href=\"https:\/\/en.wikipedia.org\/wiki\/HATEOAS\">HATEOAS<\/a> is not that great.<\/p>\n<p>In today&#8217;s post we are going to talk about what <a href=\"https:\/\/jcp.org\/aboutJava\/communityprocess\/final\/jsr370\/index.html\">JAX-RS 2.x<\/a> has to offer with respect to <a href=\"https:\/\/en.wikipedia.org\/wiki\/HATEOAS\">HATEOAS<\/a>, how to use that from the server and client perspectives, and how to augment the <a href=\"https:\/\/github.com\/OAI\/OpenAPI-Specification\/blob\/master\/versions\/3.0.0.md\">OpenAPI v3.0.x specification<\/a> to expose hypermedia as part of the contract. If you are excited, let us get started.<\/p>\n<p>So our <a href=\"https:\/\/jcp.org\/aboutJava\/communityprocess\/final\/jsr370\/index.html\">JAX-RS<\/a> web APIs are going to be built around managing companies and their staff. The foundation is <a href=\"https:\/\/spring.io\/projects\/spring-boot\">Spring Boot<\/a> and <a href=\"http:\/\/cxf.apache.org\/\">Apache CXF<\/a>, with <a href=\"https:\/\/swagger.io\/\">Swagger<\/a> as <a href=\"https:\/\/github.com\/OAI\/OpenAPI-Specification\/blob\/master\/versions\/3.0.0.md\">OpenAPI<\/a> specification implementation. The <b>AppConfig<\/b> is the only piece of configuration we need to define in order to get the application up and running (thanks to <a href=\"https:\/\/spring.io\/projects\/spring-boot\">Spring Boot<\/a> auto-configuration capabilities).<\/p>\n<div>\n<div id=\"highlighter_684235\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java color1\">@SpringBootConfiguration<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">class<\/code> <code class=\"java plain\">AppConfig {<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java color1\">@Bean<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">OpenApiFeature createOpenApiFeature() {<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java keyword\">final<\/code> <code class=\"java plain\">OpenApiFeature openApiFeature = <\/code><code class=\"java keyword\">new<\/code> <code class=\"java plain\">OpenApiFeature();<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">openApiFeature.setSwaggerUiConfig(<\/code><code class=\"java keyword\">new<\/code> <code class=\"java plain\">SwaggerUiConfig().url(<\/code><code class=\"java string\">\"\/api\/openapi.json\"<\/code><code class=\"java plain\">));<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java keyword\">return<\/code> <code class=\"java plain\">openApiFeature;<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code>&nbsp;<\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java color1\">@Bean<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">JacksonJsonProvider jacksonJsonProvider() {<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java keyword\">return<\/code> <code class=\"java keyword\">new<\/code> <code class=\"java plain\">JacksonJsonProvider();<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>The model is very simple, <b>Company<\/b> and <b>Person<\/b> (please notice that there is no direct relationships between these two classes, purposely).<\/p>\n<div>\n<div id=\"highlighter_403534\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">class<\/code> <code class=\"java plain\">Company {<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java keyword\">private<\/code> <code class=\"java plain\">String id;<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java keyword\">private<\/code> <code class=\"java plain\">String name;<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number5 index4 alt2\">&nbsp;<\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">class<\/code> <code class=\"java plain\">Person {<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java keyword\">private<\/code> <code class=\"java plain\">String id;<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java keyword\">private<\/code> <code class=\"java plain\">String email;<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java keyword\">private<\/code> <code class=\"java plain\">String firstName;<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java keyword\">private<\/code> <code class=\"java plain\">String lastName;<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>This model is exposed through <b>CompanyResource<\/b>, a typical <a href=\"https:\/\/jcp.org\/aboutJava\/communityprocess\/final\/jsr370\/index.html\">JAX-RS<\/a> resource class annotated with <b>@Path<\/b>, and additionally with <a href=\"https:\/\/github.com\/OAI\/OpenAPI-Specification\/blob\/master\/versions\/3.0.0.md\">OpenAPI<\/a>&#8216;s <b>@Tag<\/b> annotation.<\/p>\n<div>\n<div id=\"highlighter_400751\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<div class=\"line number3 index2 alt2\">3<\/div>\n<div class=\"line number4 index3 alt1\">4<\/div>\n<div class=\"line number5 index4 alt2\">5<\/div>\n<div class=\"line number6 index5 alt1\">6<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java color1\">@Component<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java color1\">@Path<\/code><code class=\"java plain\">( <\/code><code class=\"java string\">\"\/companies\"<\/code> <code class=\"java plain\">) <\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java color1\">@Tag<\/code><code class=\"java plain\">(name = <\/code><code class=\"java string\">\"companies\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java keyword\">public<\/code> <code class=\"java keyword\">class<\/code> <code class=\"java plain\">CompanyResource {<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java color1\">@Autowired<\/code> <code class=\"java keyword\">private<\/code> <code class=\"java plain\">CompanyService service;<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>Great, the resource class has no endpoints defined yet, so let us beef it up. Our first endpoint would lookup the company by identifier and return its representation in <a href=\"https:\/\/www.json.org\/\">JSON<\/a> format. But since we do not incorporate any staff-related details, it would be awesome to hint the consumer (web UI or any other client) where to look it up. There are multiple ways to do that but since we stick to <a href=\"https:\/\/jcp.org\/aboutJava\/communityprocess\/final\/jsr370\/index.html\">JAX-RS<\/a>, we could use <a href=\"https:\/\/tools.ietf.org\/html\/rfc5988\">Web Linking<\/a> (<a href=\"https:\/\/tools.ietf.org\/html\/rfc5988\">RFC-5988<\/a>) which is supported out of the box. The code snippet is worth thousand words.<\/p>\n<div>\n<div id=\"highlighter_947713\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<div class=\"line number22 index21 alt1\">22<\/div>\n<div class=\"line number23 index22 alt2\">23<\/div>\n<div class=\"line number24 index23 alt1\">24<\/div>\n<div class=\"line number25 index24 alt2\">25<\/div>\n<div class=\"line number26 index25 alt1\">26<\/div>\n<div class=\"line number27 index26 alt2\">27<\/div>\n<div class=\"line number28 index27 alt1\">28<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java color1\">@Produces<\/code><code class=\"java plain\">(MediaType.APPLICATION_JSON)<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java color1\">@GET<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java color1\">@Path<\/code><code class=\"java plain\">(<\/code><code class=\"java string\">\"{id}\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java keyword\">public<\/code> <code class=\"java plain\">Response getCompanyById(<\/code><code class=\"java color1\">@Context<\/code> <code class=\"java plain\">UriInfo uriInfo, <\/code><code class=\"java color1\">@PathParam<\/code><code class=\"java plain\">(<\/code><code class=\"java string\">\"id\"<\/code><code class=\"java plain\">) String id) {<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java keyword\">return<\/code> <code class=\"java plain\">service<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.findCompanyById(id)<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.map(company -&gt; Response<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.ok(company)<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.links(<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">Link.fromUriBuilder(uriInfo<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.getRequestUriBuilder())<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.rel(<\/code><code class=\"java string\">\"self\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.build(),<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">Link.fromUriBuilder(uriInfo<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.getBaseUriBuilder()<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.path(CompanyResource.<\/code><code class=\"java keyword\">class<\/code><code class=\"java plain\">))<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.rel(<\/code><code class=\"java string\">\"collection\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.build(),<\/code><\/div>\n<div class=\"line number19 index18 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">Link.fromUriBuilder(uriInfo<\/code><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.getBaseUriBuilder()<\/code><\/div>\n<div class=\"line number21 index20 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.path(CompanyResource.<\/code><code class=\"java keyword\">class<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number22 index21 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.path(CompanyResource.<\/code><code class=\"java keyword\">class<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"getStaff\"<\/code><code class=\"java plain\">))<\/code><\/div>\n<div class=\"line number23 index22 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.rel(<\/code><code class=\"java string\">\"staff\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number24 index23 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.build(id)<\/code><\/div>\n<div class=\"line number25 index24 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number26 index25 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.build())<\/code><\/div>\n<div class=\"line number27 index26 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.orElseThrow(() -&gt; <\/code><code class=\"java keyword\">new<\/code> <code class=\"java plain\">NotFoundException(<\/code><code class=\"java string\">\"The company with id '\"<\/code> <code class=\"java plain\">+ id + <\/code><code class=\"java string\">\"' does not exists\"<\/code><code class=\"java plain\">));<\/code><\/div>\n<div class=\"line number28 index27 alt1\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>There are few things happening here. The one we care about is usage of the <b>ResponseBuilder::links<\/b> method where we supply three links. The first is <b>self<\/b>, which is essentially the link context (defined as part of <a href=\"https:\/\/tools.ietf.org\/html\/rfc5988#section-6.2.2\">RFC-5988<\/a>). The second one, <b>collection<\/b>, is pointing out to the <b>CompanyResource<\/b> endpoint which returns the list of companies (also is included into standard relations registry). And lastly, the third one is our own <b>staff<\/b> relation which we assemble from another <b>CompanyResource<\/b> endpoint implemented by the method with the name <b>getStaff<\/b> (we are going to see it shortly). These links are going to be delivered in the <b>Link<\/b> response header and guide the client where to go next. Let us see it in action by running the application.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<div>\n<div id=\"highlighter_513222\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">1<\/div>\n<div class=\"line number2 index1 alt1\">2<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java plain\">$ mvn clean <\/code><code class=\"java keyword\">package<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java plain\">$ java -jar target\/jax-rs-<\/code><code class=\"java value\">2.1<\/code><code class=\"java plain\">-hateaos-<\/code><code class=\"java value\">0.0<\/code><code class=\"java plain\">.<\/code><code class=\"java value\">1<\/code><code class=\"java plain\">-SNAPSHOT.jar<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>And inspect the response from this resource endpoint using <b>curl<\/b> (the unnecessary details have been filtered out).<\/p>\n<div>\n<div id=\"highlighter_592305\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java plain\">$ curl -v http:<\/code><code class=\"java comments\">\/\/localhost:8080\/api\/companies\/1<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java plain\">&gt; GET \/api\/companies\/<\/code><code class=\"java value\">1<\/code> <code class=\"java plain\">HTTP\/<\/code><code class=\"java value\">1.1<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java plain\">&gt; Host: localhost:<\/code><code class=\"java value\">8080<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java plain\">&gt; User-Agent: curl\/<\/code><code class=\"java value\">7.47<\/code><code class=\"java plain\">.<\/code><code class=\"java value\">1<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java plain\">&gt; Accept: *\/*<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java plain\">&gt;<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java plain\">&lt; HTTP\/<\/code><code class=\"java value\">1.1<\/code> <code class=\"java value\">200<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java plain\">&lt; Link: &lt;http:<\/code><code class=\"java comments\">\/\/localhost:8080\/api\/companies\/1&gt;;rel=\"self\"<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java plain\">&lt; Link: &lt;http:<\/code><code class=\"java comments\">\/\/localhost:8080\/api\/companies\/1\/staff&gt;;rel=\"staff\"<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java plain\">&lt; Link: &lt;http:<\/code><code class=\"java comments\">\/\/localhost:8080\/api\/companies&gt;;rel=\"collection\"<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java plain\">&lt; Content-Type: application\/json<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java plain\">&lt; Transfer-Encoding: chunked<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java plain\">&lt;<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"java plain\">{<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;<\/code><code class=\"java string\">\"id\"<\/code><code class=\"java plain\">:<\/code><code class=\"java string\">\"1\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;<\/code><code class=\"java string\">\"name\"<\/code><code class=\"java plain\">:<\/code><code class=\"java string\">\"HATEOAS, Inc.\"<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>The <b>Link<\/b> header is there, referring to other endpoints of interest. From the client perspective, the things are looking pretty straightforward as well. The <b>Response<\/b> class provides dedicated <b>getLinks<\/b> method to wrap around the access to <b>Link<\/b> response header, for example:<\/p>\n<div>\n<div id=\"highlighter_548990\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java keyword\">final<\/code> <code class=\"java plain\">Client client = ClientBuilder.newClient();<\/code><\/div>\n<div class=\"line number2 index1 alt1\">&nbsp;<\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java keyword\">try<\/code> <code class=\"java plain\">(<\/code><code class=\"java keyword\">final<\/code> <code class=\"java plain\">Response response = client<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.target(<\/code><code class=\"java string\">\"<a href=\"http:\/\/localhost:8080\/api\/companies\/\">http:\/\/localhost:8080\/api\/companies\/<\/a>{id}\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.resolveTemplate(<\/code><code class=\"java string\">\"id\"<\/code><code class=\"java plain\">, <\/code><code class=\"java string\">\"1\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.request()<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.accept(MediaType.APPLICATION_JSON)<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.get()) {<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code>&nbsp;<\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java keyword\">final<\/code> <code class=\"java plain\">Optional&nbsp; staff = response<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.getLinks()<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.stream()<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.filter(link -&gt; Objects.equals(link.getRel(), <\/code><code class=\"java string\">\"staff\"<\/code><code class=\"java plain\">))<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.findFirst();<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code>&nbsp;<\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">staff.ifPresent(link -&gt; {<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java comments\">\/\/ follow the link here <\/code><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">});&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/code><\/div>\n<div class=\"line number19 index18 alt2\"><code class=\"java plain\">} <\/code><code class=\"java keyword\">finally<\/code> <code class=\"java plain\">{<\/code><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">client.close();<\/code><\/div>\n<div class=\"line number21 index20 alt2\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>So far so good. Moving forward, since <a href=\"https:\/\/en.wikipedia.org\/wiki\/HATEOAS\">HATEOAS<\/a> is essentially a part of the web APIs contract, let us find out what <a href=\"https:\/\/github.com\/OAI\/OpenAPI-Specification\/blob\/master\/versions\/3.0.0.md\">OpenAPI<\/a> specification has for it on the table. Unfortunately, <a href=\"https:\/\/en.wikipedia.org\/wiki\/HATEOAS\">HATEOAS<\/a> is <a href=\"https:\/\/github.com\/OAI\/OpenAPI-Specification\/issues\/577\">not supported as of now<\/a>, but on the bright side, there is a notion of <a href=\"https:\/\/swagger.io\/docs\/specification\/links\/\">links<\/a> (although they should not be confused with <a href=\"https:\/\/tools.ietf.org\/html\/rfc5988\">Web Linking<\/a>, they are somewhat similar but not the same). To illustrate the usage of the links as part of the <a href=\"https:\/\/github.com\/OAI\/OpenAPI-Specification\/blob\/master\/versions\/3.0.0.md\">OpenAPI<\/a> specification, let us decorate the endpoint with <a href=\"https:\/\/swagger.io\/\">Swagger<\/a> annotations.<\/p>\n<div>\n<div id=\"highlighter_953867\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<div class=\"line number22 index21 alt1\">22<\/div>\n<div class=\"line number23 index22 alt2\">23<\/div>\n<div class=\"line number24 index23 alt1\">24<\/div>\n<div class=\"line number25 index24 alt2\">25<\/div>\n<div class=\"line number26 index25 alt1\">26<\/div>\n<div class=\"line number27 index26 alt2\">27<\/div>\n<div class=\"line number28 index27 alt1\">28<\/div>\n<div class=\"line number29 index28 alt2\">29<\/div>\n<div class=\"line number30 index29 alt1\">30<\/div>\n<div class=\"line number31 index30 alt2\">31<\/div>\n<div class=\"line number32 index31 alt1\">32<\/div>\n<div class=\"line number33 index32 alt2\">33<\/div>\n<div class=\"line number34 index33 alt1\">34<\/div>\n<div class=\"line number35 index34 alt2\">35<\/div>\n<div class=\"line number36 index35 alt1\">36<\/div>\n<div class=\"line number37 index36 alt2\">37<\/div>\n<div class=\"line number38 index37 alt1\">38<\/div>\n<div class=\"line number39 index38 alt2\">39<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java color1\">@Operation<\/code><code class=\"java plain\">(<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">description = <\/code><code class=\"java string\">\"Find Company by Id\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">responses = {<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java color1\">@ApiResponse<\/code><code class=\"java plain\">(<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">content = <\/code><code class=\"java color1\">@Content<\/code><code class=\"java plain\">(schema = <\/code><code class=\"java color1\">@Schema<\/code><code class=\"java plain\">(implementation = Company.<\/code><code class=\"java keyword\">class<\/code><code class=\"java plain\">)),<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">links = {<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java color1\">@io<\/code><code class=\"java plain\">.swagger.v3.oas.annotations.links.Link(<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">name = <\/code><code class=\"java string\">\"self\"<\/code><code class=\"java plain\">, <\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">operationRef = <\/code><code class=\"java string\">\"#\/paths\/~1companies~1{id}\/get\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">description = <\/code><code class=\"java string\">\"Find Company\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">parameters = <\/code><code class=\"java color1\">@LinkParameter<\/code><code class=\"java plain\">(name = <\/code><code class=\"java string\">\"id\"<\/code><code class=\"java plain\">, expression = <\/code><code class=\"java string\">\"$response.body#\/id\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">),<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java color1\">@io<\/code><code class=\"java plain\">.swagger.v3.oas.annotations.links.Link(<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">name = <\/code><code class=\"java string\">\"staff\"<\/code><code class=\"java plain\">, <\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">operationRef = <\/code><code class=\"java string\">\"#\/paths\/~1companies~1{id}~1staff\/get\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">description = <\/code><code class=\"java string\">\"Get Company Staff\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">parameters = <\/code><code class=\"java color1\">@LinkParameter<\/code><code class=\"java plain\">(name = <\/code><code class=\"java string\">\"id\"<\/code><code class=\"java plain\">, expression = <\/code><code class=\"java string\">\"$response.body#\/id\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">),<\/code><\/div>\n<div class=\"line number19 index18 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java color1\">@io<\/code><code class=\"java plain\">.swagger.v3.oas.annotations.links.Link(<\/code><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">name = <\/code><code class=\"java string\">\"collection\"<\/code><code class=\"java plain\">, <\/code><\/div>\n<div class=\"line number21 index20 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">operationRef = <\/code><code class=\"java string\">\"#\/paths\/~1companies\/get\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number22 index21 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">description = <\/code><code class=\"java string\">\"List Companies\"<\/code><\/div>\n<div class=\"line number23 index22 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number24 index23 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">},<\/code><\/div>\n<div class=\"line number25 index24 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">description = <\/code><code class=\"java string\">\"Company details\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number26 index25 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">responseCode = <\/code><code class=\"java string\">\"200\"<\/code><\/div>\n<div class=\"line number27 index26 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">),<\/code><\/div>\n<div class=\"line number28 index27 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java color1\">@ApiResponse<\/code><code class=\"java plain\">(<\/code><\/div>\n<div class=\"line number29 index28 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">description = <\/code><code class=\"java string\">\"Company does not exist\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number30 index29 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">responseCode = <\/code><code class=\"java string\">\"404\"<\/code><\/div>\n<div class=\"line number31 index30 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number32 index31 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number33 index32 alt2\"><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number34 index33 alt1\"><code class=\"java color1\">@Produces<\/code><code class=\"java plain\">(MediaType.APPLICATION_JSON)<\/code><\/div>\n<div class=\"line number35 index34 alt2\"><code class=\"java color1\">@GET<\/code><\/div>\n<div class=\"line number36 index35 alt1\"><code class=\"java color1\">@Path<\/code><code class=\"java plain\">(<\/code><code class=\"java string\">\"{id}\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number37 index36 alt2\"><code class=\"java keyword\">public<\/code> <code class=\"java plain\">Response getCompanyById(<\/code><code class=\"java color1\">@Context<\/code> <code class=\"java plain\">UriInfo uriInfo, <\/code><code class=\"java color1\">@PathParam<\/code><code class=\"java plain\">(<\/code><code class=\"java string\">\"id\"<\/code><code class=\"java plain\">) String id) {<\/code><\/div>\n<div class=\"line number38 index37 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;<\/code><code class=\"java comments\">\/\/ ...<\/code><\/div>\n<div class=\"line number39 index38 alt2\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>If we run the application and navigate to the <a href=\"http:\/\/localhost:8080\/api\/api-docs\">http:\/\/localhost:8080\/api\/api-docs<\/a> in the browser (this is where <a href=\"https:\/\/github.com\/swagger-api\/swagger-ui\">Swagger UI<\/a> is hosted), we would be able to see the links section along each response.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/02\/find-company-by-id-1024x746.png\" alt=\"Hypermedia APIs \" class=\"wp-image-88900\" width=\"768\" height=\"560\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/02\/find-company-by-id-1024x746.png 1024w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/02\/find-company-by-id-300x219.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/02\/find-company-by-id-768x560.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2019\/02\/find-company-by-id.png 1420w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n<\/div>\n<p>But besides that &#8230; not much you could do with the links there (please watch for <a href=\"https:\/\/github.com\/swagger-api\/swagger-ui\/issues\/3641\">this issue<\/a> if you are interested in the subject). The resource endpoint to get the company&#8217;s staff is looking quite similar.<\/p>\n<div>\n<div id=\"highlighter_835352\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<div class=\"line number22 index21 alt1\">22<\/div>\n<div class=\"line number23 index22 alt2\">23<\/div>\n<div class=\"line number24 index23 alt1\">24<\/div>\n<div class=\"line number25 index24 alt2\">25<\/div>\n<div class=\"line number26 index25 alt1\">26<\/div>\n<div class=\"line number27 index26 alt2\">27<\/div>\n<div class=\"line number28 index27 alt1\">28<\/div>\n<div class=\"line number29 index28 alt2\">29<\/div>\n<div class=\"line number30 index29 alt1\">30<\/div>\n<div class=\"line number31 index30 alt2\">31<\/div>\n<div class=\"line number32 index31 alt1\">32<\/div>\n<div class=\"line number33 index32 alt2\">33<\/div>\n<div class=\"line number34 index33 alt1\">34<\/div>\n<div class=\"line number35 index34 alt2\">35<\/div>\n<div class=\"line number36 index35 alt1\">36<\/div>\n<div class=\"line number37 index36 alt2\">37<\/div>\n<div class=\"line number38 index37 alt1\">38<\/div>\n<div class=\"line number39 index38 alt2\">39<\/div>\n<div class=\"line number40 index39 alt1\">40<\/div>\n<div class=\"line number41 index40 alt2\">41<\/div>\n<div class=\"line number42 index41 alt1\">42<\/div>\n<div class=\"line number43 index42 alt2\">43<\/div>\n<div class=\"line number44 index43 alt1\">44<\/div>\n<div class=\"line number45 index44 alt2\">45<\/div>\n<div class=\"line number46 index45 alt1\">46<\/div>\n<div class=\"line number47 index46 alt2\">47<\/div>\n<div class=\"line number48 index47 alt1\">48<\/div>\n<div class=\"line number49 index48 alt2\">49<\/div>\n<div class=\"line number50 index49 alt1\">50<\/div>\n<div class=\"line number51 index50 alt2\">51<\/div>\n<div class=\"line number52 index51 alt1\">52<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java color1\">@Operation<\/code><code class=\"java plain\">(<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">description = <\/code><code class=\"java string\">\"Get Company Staff\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">responses = {<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java color1\">@ApiResponse<\/code><code class=\"java plain\">(<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">content = <\/code><code class=\"java color1\">@Content<\/code><code class=\"java plain\">(array = <\/code><code class=\"java color1\">@ArraySchema<\/code><code class=\"java plain\">(schema = <\/code><code class=\"java color1\">@Schema<\/code><code class=\"java plain\">(implementation = Person.<\/code><code class=\"java keyword\">class<\/code><code class=\"java plain\">))),<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">links = {<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java color1\">@io<\/code><code class=\"java plain\">.swagger.v3.oas.annotations.links.Link(<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">name = <\/code><code class=\"java string\">\"self\"<\/code><code class=\"java plain\">, <\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">operationRef = <\/code><code class=\"java string\">\"#\/paths\/~1companies~1{id}~1staff\/get\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">description = <\/code><code class=\"java string\">\"Staff\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">parameters = <\/code><code class=\"java color1\">@LinkParameter<\/code><code class=\"java plain\">(name = <\/code><code class=\"java string\">\"id\"<\/code><code class=\"java plain\">, expression = <\/code><code class=\"java string\">\"$response.body#\/id\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">),<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java color1\">@io<\/code><code class=\"java plain\">.swagger.v3.oas.annotations.links.Link(<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">name = <\/code><code class=\"java string\">\"company\"<\/code><code class=\"java plain\">, <\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">operationRef = <\/code><code class=\"java string\">\"#\/paths\/~1companies~1{id}\/get\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">description = <\/code><code class=\"java string\">\"Company\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">parameters = <\/code><code class=\"java color1\">@LinkParameter<\/code><code class=\"java plain\">(name = <\/code><code class=\"java string\">\"id\"<\/code><code class=\"java plain\">, expression = <\/code><code class=\"java string\">\"$response.body#\/id\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number19 index18 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">},<\/code><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">description = <\/code><code class=\"java string\">\"The Staff of the Company\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number21 index20 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">responseCode = <\/code><code class=\"java string\">\"200\"<\/code><\/div>\n<div class=\"line number22 index21 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">),<\/code><\/div>\n<div class=\"line number23 index22 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java color1\">@ApiResponse<\/code><code class=\"java plain\">(<\/code><\/div>\n<div class=\"line number24 index23 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">description = <\/code><code class=\"java string\">\"Company does not exist\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number25 index24 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">responseCode = <\/code><code class=\"java string\">\"404\"<\/code><\/div>\n<div class=\"line number26 index25 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number27 index26 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number28 index27 alt1\"><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number29 index28 alt2\"><code class=\"java color1\">@Produces<\/code><code class=\"java plain\">(MediaType.APPLICATION_JSON)<\/code><\/div>\n<div class=\"line number30 index29 alt1\"><code class=\"java color1\">@GET<\/code><\/div>\n<div class=\"line number31 index30 alt2\"><code class=\"java color1\">@Path<\/code><code class=\"java plain\">(<\/code><code class=\"java string\">\"{id}\/staff\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number32 index31 alt1\"><code class=\"java keyword\">public<\/code> <code class=\"java plain\">Response getStaff(<\/code><code class=\"java color1\">@Context<\/code> <code class=\"java plain\">UriInfo uriInfo, <\/code><code class=\"java color1\">@PathParam<\/code><code class=\"java plain\">(<\/code><code class=\"java string\">\"id\"<\/code><code class=\"java plain\">) String id) {<\/code><\/div>\n<div class=\"line number33 index32 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java keyword\">return<\/code> <code class=\"java plain\">service<\/code><\/div>\n<div class=\"line number34 index33 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.findCompanyById(id)<\/code><\/div>\n<div class=\"line number35 index34 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.map(c -&gt; service.getStaff(c))<\/code><\/div>\n<div class=\"line number36 index35 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.map(staff -&gt; Response<\/code><\/div>\n<div class=\"line number37 index36 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.ok(staff)<\/code><\/div>\n<div class=\"line number38 index37 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.links(<\/code><\/div>\n<div class=\"line number39 index38 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">Link.fromUriBuilder(uriInfo<\/code><\/div>\n<div class=\"line number40 index39 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.getRequestUriBuilder())<\/code><\/div>\n<div class=\"line number41 index40 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.rel(<\/code><code class=\"java string\">\"self\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number42 index41 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.build(),<\/code><\/div>\n<div class=\"line number43 index42 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">Link.fromUriBuilder(uriInfo<\/code><\/div>\n<div class=\"line number44 index43 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.getBaseUriBuilder()<\/code><\/div>\n<div class=\"line number45 index44 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.path(CompanyResource.<\/code><code class=\"java keyword\">class<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number46 index45 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.path(id))<\/code><\/div>\n<div class=\"line number47 index46 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.rel(<\/code><code class=\"java string\">\"company\"<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number48 index47 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.build()<\/code><\/div>\n<div class=\"line number49 index48 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">)<\/code><\/div>\n<div class=\"line number50 index49 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.build())<\/code><\/div>\n<div class=\"line number51 index50 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">.orElseThrow(() -&gt; <\/code><code class=\"java keyword\">new<\/code> <code class=\"java plain\">NotFoundException(<\/code><code class=\"java string\">\"The company with id '\"<\/code> <code class=\"java plain\">+ id + <\/code><code class=\"java string\">\"' does not exists\"<\/code><code class=\"java plain\">));<\/code><\/div>\n<div class=\"line number52 index51 alt1\"><code class=\"java plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>As you might expect, beside the link to <b>self<\/b>, it also includes the link to the company. When we try it out using <b>curl<\/b>, the expected response headers are returned back.<\/p>\n<div>\n<div id=\"highlighter_216334\" class=\"syntaxhighlighter  java\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"gutter\">\n<div class=\"line number1 index0 alt2\">01<\/div>\n<div class=\"line number2 index1 alt1\">02<\/div>\n<div class=\"line number3 index2 alt2\">03<\/div>\n<div class=\"line number4 index3 alt1\">04<\/div>\n<div class=\"line number5 index4 alt2\">05<\/div>\n<div class=\"line number6 index5 alt1\">06<\/div>\n<div class=\"line number7 index6 alt2\">07<\/div>\n<div class=\"line number8 index7 alt1\">08<\/div>\n<div class=\"line number9 index8 alt2\">09<\/div>\n<div class=\"line number10 index9 alt1\">10<\/div>\n<div class=\"line number11 index10 alt2\">11<\/div>\n<div class=\"line number12 index11 alt1\">12<\/div>\n<div class=\"line number13 index12 alt2\">13<\/div>\n<div class=\"line number14 index13 alt1\">14<\/div>\n<div class=\"line number15 index14 alt2\">15<\/div>\n<div class=\"line number16 index15 alt1\">16<\/div>\n<div class=\"line number17 index16 alt2\">17<\/div>\n<div class=\"line number18 index17 alt1\">18<\/div>\n<div class=\"line number19 index18 alt2\">19<\/div>\n<div class=\"line number20 index19 alt1\">20<\/div>\n<div class=\"line number21 index20 alt2\">21<\/div>\n<div class=\"line number22 index21 alt1\">22<\/div>\n<div class=\"line number23 index22 alt2\">23<\/div>\n<div class=\"line number24 index23 alt1\">24<\/div>\n<div class=\"line number25 index24 alt2\">25<\/div>\n<div class=\"line number26 index25 alt1\">26<\/div>\n<\/td>\n<td class=\"code\">\n<div class=\"container\">\n<div class=\"line number1 index0 alt2\"><code class=\"java plain\">$ curl -v http:<\/code><code class=\"java comments\">\/\/localhost:8080\/api\/companies\/1\/staff<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"java plain\">&gt; GET \/api\/companies\/<\/code><code class=\"java value\">1<\/code><code class=\"java plain\">\/staff HTTP\/<\/code><code class=\"java value\">1.1<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"java plain\">&gt; Host: localhost:<\/code><code class=\"java value\">8080<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"java plain\">&gt; User-Agent: curl\/<\/code><code class=\"java value\">7.47<\/code><code class=\"java plain\">.<\/code><code class=\"java value\">1<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"java plain\">&gt; Accept: *\/*<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"java plain\">&gt;<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"java plain\">&lt; HTTP\/<\/code><code class=\"java value\">1.1<\/code> <code class=\"java value\">200<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"java plain\">&lt; Link: &lt;http:<\/code><code class=\"java comments\">\/\/localhost:8080\/api\/companies\/1\/staff&gt;;rel=\"self\"<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"java plain\">&lt; Link: &lt;http:<\/code><code class=\"java comments\">\/\/localhost:8080\/api\/companies\/1&gt;;rel=\"company\"<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"java plain\">&lt; Content-Type: application\/json<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"java plain\">&lt; Transfer-Encoding: chunked<\/code><\/div>\n<div class=\"line number12 index11 alt1\"><code class=\"java plain\">&lt;<\/code><\/div>\n<div class=\"line number13 index12 alt2\"><code class=\"java plain\">[<\/code><\/div>\n<div class=\"line number14 index13 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">{<\/code><\/div>\n<div class=\"line number15 index14 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java string\">\"id\"<\/code><code class=\"java plain\">:<\/code><code class=\"java string\">\"1\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number16 index15 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java string\">\"email\"<\/code><code class=\"java plain\">:<\/code><code class=\"java string\">\"john@smith.com\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number17 index16 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java string\">\"firstName\"<\/code><code class=\"java plain\">:<\/code><code class=\"java string\">\"John\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number18 index17 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java string\">\"lastName\"<\/code><code class=\"java plain\">:<\/code><code class=\"java string\">\"Smith\"<\/code><\/div>\n<div class=\"line number19 index18 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">},<\/code><\/div>\n<div class=\"line number20 index19 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">{<\/code><\/div>\n<div class=\"line number21 index20 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java string\">\"id\"<\/code><code class=\"java plain\">:<\/code><code class=\"java string\">\"2\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number22 index21 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java string\">\"email\"<\/code><code class=\"java plain\">:<\/code><code class=\"java string\">\"bob@smith.com\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number23 index22 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java string\">\"firstName\"<\/code><code class=\"java plain\">:<\/code><code class=\"java string\">\"Bob\"<\/code><code class=\"java plain\">,<\/code><\/div>\n<div class=\"line number24 index23 alt1\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java string\">\"lastName\"<\/code><code class=\"java plain\">:<\/code><code class=\"java string\">\"Smith\"<\/code><\/div>\n<div class=\"line number25 index24 alt2\"><code class=\"java spaces\">&nbsp;&nbsp;&nbsp;&nbsp;<\/code><code class=\"java plain\">}<\/code><\/div>\n<div class=\"line number26 index25 alt1\"><code class=\"java plain\">]<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>So what kind of conclusions we can draw from that? <a href=\"https:\/\/en.wikipedia.org\/wiki\/HATEOAS\">HATEOAS<\/a> indeed unifies the interaction model between web API providers and consumers by dynamically driving the conversations. This is very powerful, but most of the frameworks and tools out there either have pretty basic support of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/HATEOAS\">HATEOAS<\/a> (for example, <a href=\"https:\/\/tools.ietf.org\/html\/rfc5988\">Web Linking<\/a>) or none at all.<\/p>\n<p>There are many use cases when usage of the <a href=\"https:\/\/tools.ietf.org\/html\/rfc5988\">Web Linking<\/a> is sufficient (the examples we have seen so far, paging, navigation, &#8230;), but what about let say creating, editing or patching the existing resources? What about enriching with hypermedia the individual elements which are returned in the collection (described in <a href=\"https:\/\/tools.ietf.org\/html\/rfc6573\">RFC-6537<\/a>)? Is <a href=\"https:\/\/en.wikipedia.org\/wiki\/HATEOAS\">HATEOAS<\/a> worth all this efforts?<\/p>\n<p>As always, the answer is &#8220;it depends&#8221;, may be we should look beyond the <a href=\"https:\/\/jcp.org\/aboutJava\/communityprocess\/final\/jsr370\/index.html\">JAX-RS<\/a>? In the next post(s_ we are going to continue figuring things out.<\/p>\n<p>The complete source code is available on <a href=\"https:\/\/github.com\/reta\/jax-rs-2.1-hateaos\">Github<\/a>.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td>\n<p>Published on Java Code Geeks with permission by Andrey Redko, partner at our <a href=\"\/\/www.javacodegeeks.com\/join-us\/jcg\/\" target=\"_blank\" rel=\"noopener noreferrer\">JCG program<\/a>. See the original article here: <a href=\"http:\/\/aredko.blogspot.com\/2019\/02\/the-hypermedia-apis-support-in-jax-rs.html\" target=\"_blank\" rel=\"noopener noreferrer\">The Hypermedia APIs support in JAX-RS and OpenAPI: a long way to go<\/a><\/p>\n<p>Opinions expressed by Java Code Geeks contributors are their own.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Sooner or later, most of the developers who actively work on REST(ful) web services and APIs stumble upon this truly extraterrestrial thing called HATEOAS: Hypertext As The Engine Of Application State. The curiosity of what HATEOAS is and how it relates to REST would eventually lead to discovery of the Richardson Maturity Model which demystifies &hellip;<\/p>\n","protected":false},"author":141,"featured_media":148,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[1821,439,1859,30,854],"class_list":["post-88889","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-java-11","tag-jax-rs","tag-jax-rs-2-1","tag-spring","tag-spring-boot"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>The Hypermedia APIs support in JAX-RS and OpenAPI: a long way to go - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Interested to learn about Hypermedia APIs ? Check our article explaining the Hypermedia APIs support in JAX-RS and OpenAPI\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The Hypermedia APIs support in JAX-RS and OpenAPI: a long way to go - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Interested to learn about Hypermedia APIs ? Check our article explaining the Hypermedia APIs support in JAX-RS and OpenAPI\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2019-02-26T05:00:47+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Andrey Redko\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andrey Redko\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html\"},\"author\":{\"name\":\"Andrey Redko\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/771a6504862edc45322776832cbce413\"},\"headline\":\"The Hypermedia APIs support in JAX-RS and OpenAPI: a long way to go\",\"datePublished\":\"2019-02-26T05:00:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html\"},\"wordCount\":1016,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"keywords\":[\"Java 11\",\"JAX-RS\",\"jax-rs 2.1\",\"Spring\",\"Spring Boot\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html\",\"name\":\"The Hypermedia APIs support in JAX-RS and OpenAPI: a long way to go - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"datePublished\":\"2019-02-26T05:00:47+00:00\",\"description\":\"Interested to learn about Hypermedia APIs ? Check our article explaining the Hypermedia APIs support in JAX-RS and OpenAPI\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/java-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2019\\\/02\\\/hypermedia-apis-support-jax-rs-openapi.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"The Hypermedia APIs support in JAX-RS and OpenAPI: a long way to go\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/771a6504862edc45322776832cbce413\",\"name\":\"Andrey Redko\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g\",\"caption\":\"Andrey Redko\"},\"description\":\"Andriy is a well-grounded software developer with more then 12 years of practical experience using Java\\\/EE, C#\\\/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostgreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).\",\"sameAs\":[\"http:\\\/\\\/aredko.blogspot.com\\\/\",\"http:\\\/\\\/ca.linkedin.com\\\/in\\\/aredko\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/andrey-redko\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The Hypermedia APIs support in JAX-RS and OpenAPI: a long way to go - Java Code Geeks","description":"Interested to learn about Hypermedia APIs ? Check our article explaining the Hypermedia APIs support in JAX-RS and OpenAPI","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html","og_locale":"en_US","og_type":"article","og_title":"The Hypermedia APIs support in JAX-RS and OpenAPI: a long way to go - Java Code Geeks","og_description":"Interested to learn about Hypermedia APIs ? Check our article explaining the Hypermedia APIs support in JAX-RS and OpenAPI","og_url":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2019-02-26T05:00:47+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","type":"image\/jpeg"}],"author":"Andrey Redko","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Andrey Redko","Est. reading time":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html"},"author":{"name":"Andrey Redko","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/771a6504862edc45322776832cbce413"},"headline":"The Hypermedia APIs support in JAX-RS and OpenAPI: a long way to go","datePublished":"2019-02-26T05:00:47+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html"},"wordCount":1016,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","keywords":["Java 11","JAX-RS","jax-rs 2.1","Spring","Spring Boot"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html","url":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html","name":"The Hypermedia APIs support in JAX-RS and OpenAPI: a long way to go - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","datePublished":"2019-02-26T05:00:47+00:00","description":"Interested to learn about Hypermedia APIs ? Check our article explaining the Hypermedia APIs support in JAX-RS and OpenAPI","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/java-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2019\/02\/hypermedia-apis-support-jax-rs-openapi.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"The Hypermedia APIs support in JAX-RS and OpenAPI: a long way to go"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/771a6504862edc45322776832cbce413","name":"Andrey Redko","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/16419ce8394173028eddaeb992859862bab50cfcf74589fa9bb9a3dd8bb27518?s=96&d=mm&r=g","caption":"Andrey Redko"},"description":"Andriy is a well-grounded software developer with more then 12 years of practical experience using Java\/EE, C#\/.NET, C++, Groovy, Ruby, functional programming (Scala), databases (MySQL, PostgreSQL, Oracle) and NoSQL solutions (MongoDB, Redis).","sameAs":["http:\/\/aredko.blogspot.com\/","http:\/\/ca.linkedin.com\/in\/aredko"],"url":"https:\/\/www.javacodegeeks.com\/author\/andrey-redko"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/88889","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/141"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=88889"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/88889\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/148"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=88889"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=88889"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=88889"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}