users@jersey.java.net

[Jersey] Re: Entity Manipulation Prior to REST Implementation Call

From: Kevin Duffey <andjarnic_at_yahoo.com>
Date: Sun, 18 Sep 2011 17:43:37 -0700 (PDT)

I don't know if anyone else has done this the way I have... I like probably many have a similar need as yours. We have some sort of domain entity that contains more than what we want to expose via the REST API.

The first thing I realized is I want to build a Java SDK that client side Java developers can use to use my REST API. What I didn't want to do was have EJB entity beans, then copy them to a 2nd set of objects that had "less" properties in them (to expose them via the API), and also, I needed to bundle up the same set of objects in the SDK so that they could be used between the jersey client SDK and the jersey REST API server. Instead of using an XSD file, I wrote my own Representation classes that expose via getXxx() methods only what I want to allow exposed.


One issue I found when using entity beans, and then copying them to pojo models of almost identical properties (for example, a User entity bean had getSocialSecurityNumber(), but I didn't want to make that available in the REST API, so the intermediary user object I copied entity properties to did not have a setSocialSecurityNumber() or getSocialSecurityNumber() methods in it). The problem I cam across is that I am basically doubling my objects in memory for almost the same data.


So knowing that EJB entity beans can use either property or method annotations, I thought, why not use a single pojo that is shared, passed around all tiers, and use method delegation in the entity and representation classes. In this way the entity beans use get/set methods to read/write to the database, and the REST representation classes use the delegation to the same pojo to expose only what I want. I have something like this:

public class User {
  private String username;
  private String name;
  private String socialSecurity;

  ... // get/set methods ...
}

@Entity
@Table(name="user")

public class UserEntity {
  private User model = null;
  public UserEntity(User model){
    this.model = model;
  }
  public UserEntity(){
    this.model = new User();
  }
  public User fetchModel(){
    return this.model;
  }

  public String getUserName(){
    return (null != model ? model.getUserName() : null);
  }
  public void setUserName(String userName){
    if (null != model){
      model.setUserName(userName);
    }
  }
  ../ rest of methods ../
}

@Stateless
public class UserBean {    @PersistenceContext(name = "someConfiguredPU")
    EntityManager em;

  public int createUser(User user){
    UserEntity ue = new UserEntity(user);
    em.persiste(ue);
    em.flush();
    em.refresh(ue);
    return ue.getId();
  }
}


@XmlRootElement(name = "user")
public class UserRepresentation {
  private User = null;
  public UserRepresentation(User model){
    this.model = model;
  }
  public UserRepresentation(){
    this.model = new User();
  }
  public User fetchModel(){
    return thise.model;
  }
  .. / same as above in entity.. method delegation to model methods ../
}



The above bit of code allows me to do a few things. First, in the Representation classes, since the Jersey/JAxB stuff uses get/set signature methods via reflection, by using fetchModel to get the model, it is NOT exposed in the API. The same is true for EJB entity beans.. the fetchModel() does not result in a table column called user (the result type of fetchModel).. it's thusly ignored.

Now, a jersey rest method that makes use of this would be like this:

@Path("user")
@Stateless
public class UserResource {
    @EJB
    UserBean userBean;
  @Post
  public Response createUser(UserRepresentation newUser){
    int id userBean.createUser(newUser.fetchModel());
    return Response.created(new URI(... + id).build();
  }
}

So, the point of all this is to use a single pojo model object within the incoming REST call, pass the underlying model (via fetchModel()) to the session bean, that then creates a new entity bean passing the same object into the constructor that is set as the entity beans model. In other words, a single object, completely pojo, passed from the front to the back, and even can come back after the persist() call and used in the response Representation.


Even nicer is that I can bundle up these pojos into my client side SDK, and now it is very easy for a JAva client side to use the exact same pojo objects to make REST calls that work perfectly. No worries about a StringBuilder and building up the right XML and getting any xml parse issues.. or in the case of REST, if you have invalid XML no method is called at all and you can't easily track down why this happens.


This is working for me nicely. Before I did this, I used separate entitiy beans, a intermedialy object and a representation object.. 3.. and couldn't easily build the client side SDK either. This has cut my memory consumption by 2/3s with regards to the objects used, and thus with less object creation has increased my performance as well.


Not sure if this addresses any of your questions though.. I thought I'd share at lest how I handle the part of what methods you expose via your REST API compared to what your entity bean may actually have with it.

I also like this because it allows me to modularize my code a bit more.. there is the representation and resource classes, the session and entity beans, the SDK classes, and then the pojos that are shared by all three. I've actually broken my pojos out into a separate project because I have another deployed app project that uses them.. I used REST to communicate between a couple of web apps deployed in different locations as opposed to dealing with JMS and configuration issues. It works very nicely and with the shared pojos and also shared representation classes, my work is minimal on adding communication between distributed deployed web apps.





>________________________________
>From: "webron_at_gmail.com" <webron_at_gmail.com>
>To: users_at_jersey.java.net
>Sent: Saturday, September 17, 2011 5:56 AM
>Subject: [Jersey] Entity Manipulation Prior to REST Implementation Call
>
>Hi everyone,
>
>I hope this haven't been asked and answered before - I wasn't sure
>exactly what to look for.
>
>Brief description of our architecture:
>We have an entity-management Spring-based system. The system consisted
>of several entities - all JAXB annotated. Those entities are used both
>with our DB ORM framework and by our REST API implementation. The
>entities are sent to the REST API in JSON format.
>
>Currently, when the client invoke an API call, it needs to send the
>whole JSON/entity.
>For example, assume the following API declaration:
>
>@PUT
>@Path("/entity")
>@Consumes({MediaType.APPLICATION_JSON})
>public void updateEntity(FooEntity fooEntity) { ... }
>
>What I'd like to do is allow the client to send only parts of the
>entity, and somehow add a hook before the actual updateEntity(...)
>invocation. In that hook, I would read the actual entity from the
>database (or whichever source), and modify only the fields received
>from the client, and only then invoke the updateEntity(...) with the
>newly created entity. I would probably want to put some extra
>security-checks logic in that hook.
>
>Is there any way to do it? If there's more than one way, I'd like to
>hear the options out there (with pros and cons if willing).
>
>Thanks,
>Ron
>
>
>