11

I have some REST services (consuming and producing application/json) and I use @TypeHint to generate documentation.

Now I have something like this:

import javax.ws.rs.core.Response;
...

@Path("/path")
public class MyClass {

    @GET
    @TypeHint(MyResponse.class)
    public Response getIt() {

        MyResponse resp = ... ;
        return MyBuilder.build(resp);
    }
}

but MyResponse is a wrapper over List<MyType>.

My build method from MyResponse looks like this:

public static Response build(Serializable payload) {
    return Response.ok(msr).header(...).build();
}

I want to use directly List<MyType> instead of MyResponse. Which is the best way to use TypeHint in the following code?

    @GET
    @TypeHint(/* TODO */)
    public Response getIt() {

        List<MyType> myList = ... ;
        return MyBuilder.build(myList);
    }

I was thinking to the following options:

  1. @TypeHint(List.class)
  2. @TypeHint(MyType.class)
  3. @TypeHint(List<MyType>.class) -> unfortunately this doesn't work because of Java type erasure.

Question:

Is there a valid alternative for number 3?


Even if the type is a List, number 1 is not useful because my own type has to be annotated with @XmlRootElement and that List is unchangeable (it is from JDK).

There is a workaround for number 2, but it's not quite perfect:

  • Use number 2 (just to have an available example in the generated HTML documentation - a description for an element that is contained in that list)
  • Specify that it is a List in Javadoc (E.g.: after the @return word) (it can be emphasized using bold, colors, italics, etc. via HTML tags)

    E.g.:

    /**
     * ...
     * @return <strong><font color="blue">List&lt;MyType&gt;</font></strong>
     */
    

Details:

  • enunciate.version = 1.30.1
  • Java 7
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199

2 Answers2

5

I have opted for using MyType[].class when using TypeHint instead of List.class. This way the documentation will state "array of MyType" which for my rest-api with json is true.

@TypeHint(value = MyType[].class)
1

As you know TypeHint is used to give Enunciate a hint about what a JAX-RS resource method returns or accepts as an input parameter.

In your case the return type is being described.

I assume that the ClassReturnedByMyBuildersBuildMethod is a subclass of the javax.ws.rs.core.Response abstract class. For the code as you showed it what you need to use is the class returned by MyBuilder's build method - @TypeHint(ClassReturnedByMyBuildersBuildMethod.class).

Options 2 @TypeHint(MyType.class) makes no sense. It is not a return type nor an input parameter.

Update 1: with your workaround it can make some sense :)

If you add an input parameter to the getIt method - something like public Response getIt(List<MyType> myList){... you would use option 1(@TypeHint(List.class)) because as you know the org.codehaus.enunciate.jaxrs.TypeHint annotation type element declaration has a Class return type (Class<?> value();) and you cannot use a parameterized type beacuse of the erasure of generic types (the paramterized type share the same class at runtime in this case - List).

But changing the input parameter to getIt(List<MyType> myList) is probably not viable because the list would have to be obtained from the URI ( with javax.ws.rs's @QueryParam or @Context UriInfo ). This question addresses best practices when using list of parameters as input if it may concern you.

Update 2: Option 1 becomes is less viable because of your XmlRootElement constraint.

Update 3: I see no valid alternative for option 3 using the TypeHint annotation as it is.

You will have to go with your custom option 2 workaround.

Community
  • 1
  • 1
Laurentiu L.
  • 6,566
  • 1
  • 34
  • 60
  • 1) I agree with your first sentences. 2) Yes, my builder returns a `Response` 3) I've never tried to use that `Response` type for `TypeHint` because it worked perfectly (according to what I wanted to achieve) when I used the type that was "wrapped" into that response. 4) I don't use that `List` as a parameter for my function. It is wrapped into the returned result. I need to have some attempts according to your suggestions before I can say if your answer is useful or not. – ROMANIA_engineer Jun 09 '15 at 18:35
  • It didn't work. Value for `element` is seen as `(custom)` instead of a hyperlink that goes to a JSON sample. So, it is not better than my workaround described in the question. – ROMANIA_engineer Jun 10 '15 at 10:16