bly
bly

Reputation: 1592

REST Summary Object with JAX-RS

I'm writing a RESTful interface using JAX-RS. Currently writing an index resource to see what objects are available in the system.

My problem is that returning the full representation of a movie object is expensive and unnecessary until the user selects the actual object in question.

My question:

Is there a way to control the JSON serialisation process to provide a 'short' version of this object as well as a long one - or would I better off creating a viewmodel-esque class to represent the shorter form?

Using a movie database as a worked example of my problem:

@GET
@Path("/api/movie/")
@Produces(MediaType.APPLICATION_JSON)
public List<Movie> ListMovies() {
    return entityManager.createQuery("FROM Movie", Movie.class).getResultList();
}

@GET
@Path("/api/movie/{movieId}")
@Produces(MediaType.APPLICATION_JSON)
public Movie GetMovie( @PathParam("movieId") Integer movieId ) {
    return entityManager.find(Movie.class,movieId);
}

The first route /api/movie I would like to return a shorter form of the object only containing the ID, Title, and YearProduced properties - whilst the second route would return the full object.

I expect this is easily solved, however I'm not a Java guy by trade and was hoping there are annotations or some kind of helper to assist with that.

Edit: If there isn't, I suspect the easiest way will be to create a summary class (ie: MovieSummary) and return that instead.

Upvotes: 1

Views: 377

Answers (1)

miguelcobain
miguelcobain

Reputation: 4754

I think your suggestion is good. You can create an auxiliary object that represents what your API will return. This is called a DTO. You can create several DTO's to just one entity object, and I think this is your case. Return a MovieSummaryDTO on the index and MovieDTO everywhere else, for example.

Moreover, you can put in this new object all the annotations and generally any "stuff" that doesn't belong to the data access layer. So, to some extent, this helps to separate the concerns and keep your entity objects very clean.

However, this introduces a new problem: now you must convert between Entities and DTO's.

This can either be done:

  • Manually - You create objects that do these mappings, or just create them directly using constructors
  • Automatically/generically - There are some libraries that map one object to another through the reflection API. I would advise these:

I would just like to add that it is possible to ignore certain properties when serializing. If you're using Jackson (which you should) you can annotate a property with @JsonIgnore, and that property does not get serialized. However, I think this isn't what you need, because sometimes you want to ignore the extra properties, but sometimes you don't.

Hope this helped. Happy coding!

Upvotes: 2

Related Questions