3
votes

If a method of a JAX-RS application would return a domain object, the representation (say JSON) would contain all attributes of this object - right? But what if this object would contain "private" data, that shouldn't be exposed to the web?

And what is about the other direction from outside in: how could be prevented that private fields are overridden?

The only solution to this seems to create data transfer objects (dto).

To use an "automapper" wouldn't be the solution unless one can not specify what fields to map.

So, forces JAX-RS the developer to create DTOs? Or is there another solution?

3

3 Answers

3
votes

For transparent marshalling and unmarshalling to and from XML of your entity, annotate it with JAXB annotations (a class can be annotated with both JPA and JAXB annotations and, this way, give an XML representation as well as be persisted in a database).

@Entity
@XmlRootElement
public class MyEntity implements Serializable {

    @Id @GeneratedValue
    private Long id;

    ....

}

In the above example I use only one JAXB annotation @XmlRootElement. Now, let's say that you don't want the id property in the serialized XML. Simply add the JAXB annotation @XmlTransient to it:

@Entity
@XmlRootElement
public class MyEntity implements Serializable {

    @XmlTransient
    @Id @GeneratedValue
    private Long id;

    ....

}

So, no, there is no strict need for DTOs (and the boilerplate code to map them to and from entities).

2
votes

I think it is better to say JAX-RS requires you to use representations.

My Foo domain object has no idea that it is being used in a RESTful manner. It only knows of Bar (another aggregate root) and whatever entities it can navigate from via that Bar. In fact, I also have a command-line interface to this application that doesn't use REST or even HTTP.

My RESTful interface wraps Foo/Bar in to representations that link to each other via URIs. I guess you can call these DTOs, but if you (like stated in other answers) just annotate your domain model with what is required to marshal and unmarshal them then I think you're coding yourself in to a corner that prohibits HATEOAS.

This is also apparent when you have a collection. If Foo->*Bar are you going to return all of the Bar items in their unmarshalled form? Why not just a URI and maybe some other minimal data, e.g.

GET foo/fff

<foo>
  <link rel="self" uri="uri="foo/fff" />
  <bar uri="bar/abc123">
    <status="Active" />
  </bar>
  <bar uri="bar/qqq">
    <status="Inactive" />
  </bar>
</foo>

If the client wants to know more about a given Bar, it can

GET bar/abc123

<bar>
  <link rel="self" uri="bar/abc123" />
  <foo uri="foo/fff" />
  <status>Active</status>
  <title>Some Bar</title>
  ...
</bar>
1
votes

@XmlTransient (or a corresponding annotation) instructs the mappers/marshallers not to include the annotated property in the serialized output.