Saturday, December 3, 2011

GWT with JAX-RS (aka RPC/REST) Part 1


Come unto me all ye who are weary of heavy-laden clients and I will give you REST.

Continued from GWT with JAX-RS (aka RPC/REST) Part 0 (preamble ramble)


JAX-RS REST with GWT is equivalent in mechanism to GWT-RPC. The similarity lies in the requirement for
  • a common Data Transfer Object interface (DTO) between client and server
  • a common Remote Procedure API, using the shared DTO definitions are arguments, between client and server;
    where REST calls it Remote Service API (rSAPI), GWT-RPC calls it Remote Procedure Call.
    where the Remote Service API specifies a return type;
  • server implementation which follows the rSAPI interface.
  • a client version of the service API (cSAPI) which includes a callback; where return_type is the return type specified in the rSAPI; so that the cSAPI returns void, translating return_type as an argument to the callback
  • client implementation which follows the cSAPI interface.

RPC over REST
JAX-RS had been invented/concocted as a server-side API definition facility. I heard that JAX-RS 2.0 is under formulation to address JAX-RS being used as a client-side facility too.

However, this series of articles centre on sharing JAX-RS definition between the client and server, using currently available frameworks, allowing the client to use REST as the RPC mechanism. Hence, if you are completely comfortable with GWT-RPC, you would also be completely comfortable with GWT-REST-RPC.

In http://h2g2java.blessedgeek.com/2009/08/gwt-rpc.html, I discussed that GWT-RPC is technically RPC over HTTP. REST is SOA embedded in HTTP transported over HTTP. (Whilst SOAP is SOA transported over http without being embedded with HTTP). Therefore,

GWT+JAX-RS = RPC over REST{SOA over HTTP}.

Frameworks involved
The frameworks involved in making RPC/REST possible are
  • JAX-RS, aka JSR-311, aka Java API for RESTful Web Services
  • JAX-B, aka JSR-222, aka Java Architecture for XML Binding
  • Jackson JSON Object schema
  • RestyGWT

JAX-RS presents two layers of API.
  • The URL schema
  • The Java API layer, which is the enabling feature for RPC over REST.

JAX-RS provides a Java annotation convention that maps the REST URL API to its Java API. There are two implementations of JAX-RS.

What is REST
REST = Representational state transfer. What's that? Never bother, just call it REST. Like SOAP, nice sounding short-form, incongruent long-form.

In a short but not too complete description REST mandates that
  • All communication with a web application should be made through a set of unique URLs.
  • That set of unique URLs is known as the API of the web service offered by the web application as a communication facade.
  • You are allowed to use the HTTP Methods of GET, POST, PUT, DELETE.
  • You are allowed to pass data either as form parameters, URL path parameters, QueryString parameters, as content or as HTTP header values.
JAX-RS is a Java language formalisation of REST.
  • @Path annotation to a class, interface, or method to map a set of URL API to their respective Java API.
    The server implementation is to monitor for requests through those URL paths to call their respective Java API method to process the request.
  • @GET, @POST, @PUT, @DELETE annotations to signify HTTP method through which a particular API should accept request.
  • The arguments to the Java API is mapped to the HTTP parameters using parametric annotations such as @PathParam, @QueryParam, @MatrixParam, @FormParam, as well as through HTTP content which are unannotated arguments.
  • @Path annotation combined with the parametric arguments and HTTP method annotation defines the unique polymorphic signature of the API.

The following are two different unique polymorphic API signatures.
  • @Path ("/services/greet")
    @GET

  • @Path ("/services/greet")
    @POST
because one accepts GET while the other accepts POST.

Again, the following are two different unique polymorphic signatures
  • @Path ("/services/greet/{userName}")
    @GET
    String getGreeting(@PathParam String userName);

  • @Path ("/services/greet/{userName}")
    @GET
    String getGreeting(@QueryParam int count, @PathParam String userName);