Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I include types in Jersey WADL while also returning Response

The Situation

I have a Jersey 2.18 API endpoint that returns a User object. My stakeholders need the API to generate a WADL file that reflects not only the API path, but also the object type being returned.

This is covered by Jersey out of the box as of 2015, by using the following endpoint definition:

@GET
@Path("/")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public User getExampleUser() {
    User exampleUser = new User();
    return exampleUser;
}

The resulting WADL file generated by jersey properly contains the endpoint, as well as the return type:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
    <doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 2.18 2015-06-05 02:28:21"/>
    <doc xmlns:jersey="http://jersey.java.net/" jersey:hint="This is simplified WADL with user and core resources only. To get full WADL with extended resources use the query parameter detail. Link: http://localhost:8080/example/api/v3/application.wadl?detail=true"/>
    <grammars>
        <include href="application.wadl/xsd0.xsd">
            <doc title="Generated" xml:lang="en"/>
        </include>
    </grammars>
    <resources base="http://localhost:8080/example/api/v3/">
        <resource path="/">
            <method id="getExampleUser" name="GET">
                <request>
                </request>
                <response>
                    <ns2:representation xmlns:ns2="http://wadl.dev.java.net/2009/02" xmlns="" element="user" mediaType="application/json"/>
                    <ns2:representation xmlns:ns2="http://wadl.dev.java.net/2009/02" xmlns="" element="user" mediaType="application/xml"/>
                </response>
            </method>
        </resource>    
    </resources>
</application>

But most of the Jersey community seems to have endpoints return a more generic Response object, which allows for all sorts of nice things up to and including E-TAG caching, HTTP status code manipulation, error messaging, and more.

For instance:

@GET
@Path("/")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response getExampleUser()  {
    User exampleUser = new User();
    return Response.ok(exampleUser).build();
}

The WADL generated looks the same, but the response section now shows no evidence of the return type and schema.

<response>
    <representation mediaType="application/json"/>
    <representation mediaType="application/xml"/>
</response>

My Question

Is it possible to benefit from rich auto-generated WADL files while also being able to have my endpoints return the more flexible Response object?

Alternatively, how can I handle redirection, caching, and other basic API features while still returning the specific object type from my endpoint definition?

like image 836
slifty Avatar asked Mar 25 '16 00:03

slifty


1 Answers

I had the exact same problem, and was able to solve it like this:

  • All my entities had to be annotated with @XmlRootElement and sent in to a dummy rest endpoint in order for them to show up in application.wadl/xsd0.xsd.
  • I included Swagger in my project and used it for generating documentation containing the response codes and response objects.
  • I then ran the existing wadl generation tool, application.wadl.
  • The last step was to write a method that inserts the response codes and objects from the Swagger file into the wadl file.

The three last steps were put together in a rest service. The result is that the wadl is generated automatically by calling the rest service, and you can continue to use Response as before.

like image 78
Johanne Avatar answered Oct 15 '22 16:10

Johanne