Reputation: 519
I'm looking for a way to export some JPA entities to a REST API, but instead of sending the whole entity every time I want to share just some specific fields depending of the entry point. Here's a small example:
Say we have an Author
class with few fields:
@Entity
public class Author implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = SEQUENCE)
private Long id;
@NotNull
@Size(min = 1, message = "{required.field}")
private String name;
@NotNull
@Size(min = 1, message = "{required.field}")
private String country;
private LocalDate birthDate;
// getters and setters
}
And say we have this REST service (just two methods):
@Path("authors")
public class AuthorREST {
@Inject
private AuthorBC bc;
@GET
@Produces("application/json")
public List<Author> find(@QueryParam("q") String query) throws Exception {
List<Author> result;
if (Strings.isEmpty(query)) {
result = bc.findAll();
} else {
result = bc.find(query);
}
return result;
}
@GET
@Path("{id}")
@Produces("application/json")
public Author load(@PathParam("id") Long id) throws Exception {
Author result = bc.load(id);
if (result == null) {
throw new NotFoundException();
}
return result;
}
}
Now, this way, I'll always have the 4 fields when my API is called.
I understand that if I use Jackson I can set an @JsonIgnore
to fields I want to ignore, and they will always be ignored.
But what if I want that, in some cases, my whole entity is returned by one service, and in other service (or other method in the same service), only 2 or 3 fields are returned?
Is there a way to do it?
Upvotes: 5
Views: 5912
Reputation: 9492
If you want to decouple the parsing from your JPA entities and return only certain attributes you can always use Mixins for this purpose. http://www.cowtowncoder.com/blog/archives/2009/08/entry_305.html https://github.com/FasterXML/jackson-docs/wiki/JacksonMixInAnnotations
One more thing. If you want things to be dynamic in one service to return one representation in another to return another representation. Your option is to write a custom JSON serializer! Check this post for how to create a customer serializer: How do I use a custom Serializer with Jackson?
Upvotes: 3
Reputation: 1108
I would use Spring Data REST and then use the ApiModel annotation to hide the attributes you do not want exposed.
Upvotes: 0
Reputation: 131187
You already know you can use annotations such as @JsonIgnore
and @JsonIgnoreProperties
to make Jackson ignore some properties.
You also could check the @JsonView
annotation. For some details on how to use @JsonView
with JAX-RS, have a look here.
If modifying the JPA entities is not an option, consider mix-in annotations as described in this answer.
Data Transfer Object (DTO) is a pattern that was created with a very well defined purpose: transfer data to remote interfaces, just like webservices. This pattern fits very well in REST APIs and using DTOs you'll have more flexibility in the long run. You can have tailored classes for your needs, once the REST resource representations don't need to have the same attributes as the persistence objects.
To avoid boilerplate code, you can use mapping frameworks such as MapStruct to map your REST API DTOs from/to your persistence objects.
For details on the benefits of using DTOs, check the following answers:
To give better names to your DTOs, check the following answer:
Upvotes: 5
Reputation: 1430
For myself I found it quite suitable to use @JsonView annotation. So you can define fields to be rendered in specific view. You can find more info here http://wiki.fasterxml.com/JacksonJsonViews
Upvotes: 1
Reputation: 331
I think you can write a custom MessageBodyWriter using Jersey framework and you can control the response payload the way you want. Here you have to write few lines of code in-order to manage the response payload. For more information please visit https://jersey.java.net/documentation/latest/message-body-workers.html#d0e6826
Upvotes: 0