Enterprise Integration Zone is brought to you in partnership with:

I've been writing software since about 1993, spanning several different domains and programming languages. Always on the look for better and more fun ways to program. I spent much of my youth fencing, and recently I returned to the sport as a coach. Borislav is a DZone MVB and is not an employee of DZone and has posted 14 posts at DZone. You can read more from them at their website. View Full User Profile

A Busy Developer's Guide to RESTful Services in Java

10.28.2012
| 44131 views |
  • submit to reddit
The Internet doesn't lack expositions on REST architecture, RESTful services, and their implementation in Java. But, here is another one. Why? Because I couldn't find something concise enough to point readers of the eValhalla blog series.

What is REST?
The acronym stands for Representational State Transfer. It refers to an architectural style (or pattern) thought up by one of the main authors of the HTTP protocol. Don't try to infer what the phrase "representational state transfer" could possibly mean. It sounds like there's some transfer of state that's going on between systems, but that's a bit of a stretch. Mostly, there's transfer of resources between clients and servers. The clients initiate requests and get back responses. The responses are resources in some standard media type such as XML  or JSON or HTML. But, and that's a crucial aspect of the paradigm, the interaction itself is stateless. That's a major architectural departure from the classic client-server model of the 90s. Unlike classic client-server, there's no notion of a client session here. 

REST is offered not as a procotol, but as an architectural paradigm. However, in reality we are pretty much talking about HTTP of which REST is an abstraction. The core aspects of the architecture are (1) resource identifiers (i.e. URIs);  (2) different possible representations of resources, or internet media types (e.g. application/json); (3) CRUD operations support for resources like the HTTP methods  GET, PUT, POST and DEL. 

Resources are in principle decoupled from their identifiers. That means the environment can deliver a cached version or it can load balance somehow to fulfill the request. In practice, we all know URIs are actually addresses that resolve to particular domains so there's at least that level of coupling.  In addition, resources are decoupled from their representation. A server may be asked to return HTML or XML or something else. There's content negotiation going on where the server may offer the desired representation or not. The CRUD operations have constraints on their semantics that may or may not appear obvious to you. The GET, PUT and DEL operations require that a resource be identified while POST is supposed to create a new resource.
 
The GET operation must not have side-effects. So all other things being equal, one should be able to invoke GET many times and get back the same result.  PUT updates a resource, DEL removes it and therefore they both have side-effects just like POST. On the other hand, just like GET, PUT may be repeated multiple times always to the same effect. In practice, those semantics are roughly followed. The main exception is the POST method which is frequently used to send data to the server for some processing, but without necessarily expecting it to create a new resource. 

Implementing RESTful services revolves around implementing those CRUD operations for various resources. This can be done in Java with the help of a Java standard API called JAX-RS.

REST in Java = JAX-RS = JSR 311
In the Java world, when it comes to REST, we have the wonderful JAX-RS. And I'm not being sarcastic! This is one of those technologies that the Java Community Process actually got right, unlike so many other screw ups. The API is defined as JSR 311 and it is at version 1.1, with work on version 2.0 under way. 

The beauty of JAX-RS is that it is almost entirely driven by annotations. This means you can turn almost any class into a RESTful service. You can simply turn a POJO into a REST endpoint by annotating it with JSR 311 annotations. Such an annotated POJOs is called a resource class in JAX-RS terms.

Some of the JAX-RS annotations are at the class level, some at the method level and others at the method parameter level. Some are available both at class and method levels. Ultimately the annotations combine to make a given Java method into a RESTful endpoint accessible at an HTTP-based URL. The annotations must specify the following elements:

  • The relative path of the Java method - this is accomplished with @Path annotation.
  • What the HTTP verb is, i.e. what CRUD operation is being performed - this is done by specifying one of @GET, @PUT, @POST or @DELETE annotations. 
  • The media type accepted (i.e. the representation format) - @Consumes annotation.
  • The media type returned - @Produces annotation.


The two last ones are optional. If omitted, then all media types are assumed possible. Let's look at a simple example and take it apart:

import javax.ws.rs.*;

@Path("/mail")
@Produces("application/json")
public class EmailService
{
    @POST
    @Path("/new")
    public String sendEmail(@FormParam("subject") String subject,
                            @FormParam("to") String to,
                            @FormParam("body") String body)  {
        return "new email sent";
    }
    
    @GET
    @Path("/new")
    public String getUnread()  {
        return "[]";
    }
   
    @DELETE
    @Path("/{id}")
    public String deleteEmail(@PathParam("id") int emailid)  {
        return "delete " + id;
    }
    
    @GET
    @Path("/export")
    @Produces("text/html")
    public String exportHtml(@QueryParam("searchString") 
                             @DefaultValue("") String search) {
        return "<table><tr>...</tr></table>";
    }
}

The class define a RESTful interface for a hypothetical HTTP-based email service. The top-level path mail is relative to the root application path. The root application path is associated with the JAX-RS javax.ws.rs.core.Application  that you extend to plugin into the runtime environment. Then we've declared with the @Produces annotation that all methods in that service produce JSON. This is just a class-default that one can override for individual methods like we've done in the exportHtml method. The sendMail method defines a typical HTTP post where the content is sent as an HTML form. The intent here would be to post to http://myserver.com/mail/new a form for a new email that should be sent out. As you can see, the API allows you to bind each separate form field to a method parameter. Note also that you have a different method for the exact same path.

If you do an HTTP get at /mail/new, the Java method annotated with @GET will be called instead. Presumably the semantics of get /mail/new would be to obtain the list of unread emails. Next, note how the path of the deleteEmail method is parametarized by an integer id of the email to delete. The curly braces indicate that "id" is actually a parameter. The value of that parameter is bound to the whatever is annotated with  @PathParam("id"). Thus if we do an HTTP delete at http://myserver.com/mail/453 we would be calling the deleteEmail method with argument emailid=453. Finally, the exportHtml method demonstrates how we can get a handle on query parameters. When you annotate a parameter with @QueryParam("x") the value is taken from the HTTP query parameter named x. The @DefaultValue annotation provides a default in case that query parameter is missing. So, calling http://myserver.org/mail/export?searchString=RESTful will call the exportHtml method with a parameter search="RESTful".

To expose this service, first we need to write an implementation of javax.ws.rs.core.Application. That's just a few lines:

public class MyRestApp extends javax.ws.rs.core.Application {
   public Set>Class> getClasses() {
      HashSet S = new HashSet();
      S.add(EmailService.class);
      return S;
   }
}

How this gets plugged into your server depends on your JAX-RS implementation. Before we leave the API, I should mentioned that there's more to it. You do have access to a Request and Response objects. You have annotations to access other contextual information and metadata like HTTP headers, cookies etc. And you can provide custom serialization and deserialization between media types and Java objects.

RESTful vs Web Services
Web services (SOAP, WSDL) were heavily promoted in the past decade, but they didn't become as ubiquitous as their fans had hoped. Blame XML. Blame the rigidity of the XML Schema strong typing. Blame the tremendous overhead, the complexity of deploying and managing a web service. Or, blame the frequent compatibility nightmares between implementations. Reasons are not hard to find and the end result is that RESTful services are much easier to develop and use. But there is a flip side!

The simplicity of RESTful services means that one has less guidance in how to map application logic to a REST API. One of the issues is that instead of the programmatic types we have in programming languages, we have the Java primitives and media types. Fortunately, JAX-RS allows to implement whatever conversions we want between actual Java method arguments and what gets sent on the wire.  The other issue is the limited set of operations that a REST service can offer. While with web services, you define the operation and its semantics just as in a general purpose programming language, with RESTful you're stuck with get, put, post and delete. So, free from the type mismatch nightmare, but tied into only 4 possible operations. This is not as bad as it seems if you view those operations as abstract, meta operations.

The key point when designing RESTful services, whether you are exposing existing application logic or creating a new one, is to think in terms of data resources. That's not so hard since most of what common business applications do is manipulate data. First, because every single thing is identified as a resource, one must come up with an appropriate naming schema. Because URIs are hierarchical, it is easy to devise a nested structure like /productcategory/productname/version/partno. Second, one must decide what kinds of representations are to be supported, both in output and input. For a modern AJAX webpp, we'd mostly use JSON. I would recommend JSON over XML even in a B2B setting where servers talk to each other.

Finally, one must categorize business operation as one of GET, PUT, POST and DELETE. This is probably a bit less intuitive, but it's just a matter of getting used to. For example, instead of thinking about a "Checkout Shopping Cart" operation, think about POSTing a new order. Instead of thinking about a "Login User" operation think about GETing an authentication token. In general, every business operation manipulates some data in some way. Therefore, every business operation can fit into this crude CRUD model. Clearly, most read-only operations should be a GET. However, sometimes you have to send a large chunk of data to the server in which case you should use POST. For example you could post some very time consuming query that require a lot of text to specify. Then the resource you are creating is for example the query result. Another way to decide if you should POST or no is if you have a unique resource identifier. If not, then use POST. Obviously, operations that cause some data to be removed should be a DELETE. The operations that "store" data are PUT and again POST. Deciding between those two is easy: use PUT whenever you are modifying an existing resource for which you have an identifier. Otherwise, use POST. 

Implementations & Resources
There are several implementations to choose from. Since, I haven't tried them all, I can't offer specific comments. Most of them used to require a servlet containers. The Restlet framework by Jerome Louvel never did, and that's why I liked it. Its documentation leaves to be desired and if you look at its code, it's over-architected to a comical degree, but then what ambitious Java framework isn't. Another newcomer that is strictly about REST and seems lightweight is Wink, an Apache incubated project. I haven't tried it, but it looks promising. And of course, one should not forget the reference implementation Jersey. Jersey has the advantage of being the most up-to-date with the spec at any given time. Originally it was dependent on Tomcat. Nowadays, it seems it can run standalone so it's on par with Restlet which I mentioned first because that's what I have mostly used. 

Here are some further reading resources, may their representational state be transferred to your brain and properly encoded from HTML/PDF to a compact and efficient neural net:
  1. The Wikipedia article on REST is not in very good shape, but still a starting point if you want to dig deeper into the conceptual framework. 
  2. Refcard from Dzone.com: http://refcardz.dzone.com/refcardz/rest-foundations-restful#refcard-download-social-buttons-display 
  3. Wink's User Guide seems well written. Since it's an implementation of JAX-RS, it's a good documentation of that technology.
  4. http://java.dzone.com/articles/putting-java-rest: A fairly good show-and-tell introduction to the JAX-RS API, with a link in there to a more in-depth description of REST concepts by the same author. Worth the read. 
  5.  http://jcp.org/en/jsr/detail?id=311: The official JSR 311 page. Download the specification and API Javadocs from there.
  6. http://jsr311.java.net/nonav/javadoc/index.html: Online access of JSR 311 Javadocs.
If you know of something better, something nice, please post it in a comment and I'll include in this list.

PS: I'm curious if people start new projects with Servlets, JSP/JSF these days? I would be curious as to what the rationale would be to pick those over AJAX + RESTful services communication via JSON. As I said above, this entry is intended to help readers of the eValhalla blogs series which chronicles the development of the eValhalla project following precisely the AJAX+REST model.

 

Published at DZone with permission of Borislav Iordanov, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Romain Manni-bucau replied on Mon, 2012/10/29 - 1:59am

Think you forgot cxf as implementation which is really good

Billy Clark replied on Wed, 2012/10/31 - 7:16am

Thanks for distilling things, really appreciated!

Your distinction between PUT's and POST's seems both counterintuitive and contrary to specs...I thought PUT's represent the creation of new data and POST's represent a change to existing data.

Is something shifting in those concepts or did you simply get them mixed up?

 

Again, thanks for taking the time to hit the high points!

Borislav Iordanov replied on Wed, 2012/10/31 - 10:03am in response to: Billy Clark

Hi Billy,

Thanks for the nice comments. However, I'd have to disagree that I've mixed up PUT and POST. If something must be added, it's that PUT can be used for creation when the ID of the resource is known. According to the HTTP spec, which is the closest I know to a spec we have for REST,  POST creates and PUT updates or creates. The key difference being that in the case of PUT (1) you have to supply the full identifier of the identity being update (or created) and (2) the operation is idempotent which means it can be repeated to the same effect. Both (1) and (2) are important in choosing between PUT and POST. From the, it follows the PUT will create a new resource with the supplied id if one doesn't already exist, and it will do an update of a resource if one already exists. In a POST, on the other hand, usually the identifier of the enclosing resource is specified (e.g. a collection of entities) and if repeated it's not expected to be idempotent. I guess POST can be used to update, yes, for example by updating multiple "child" resources.

In sum, while the distinction may be a bit fuzzy in some cases, in general, given constraints (1) and (2) above, it seems to me that logically PUT is the U while POST is the C of CRUD. 

Boris

Borislav Iordanov replied on Wed, 2012/10/31 - 10:53am in response to: Romain Manni-bucau

Hi Romain, 

Thanks for mentioning that implementation. I believe I'd seen before, but I forget about it when I was writing that post.

Jorge Simao replied on Wed, 2012/10/31 - 11:15am

Answer: AJAX assumes JavaScript...If you don't want to assume that -- i.e. make the webapp work from the functional point-of-view (even if without some sexy features). than doing the work on the server side is better. That is, if you want the application to "degrade gracefully" without JavaScript, or conversely to be "progressively enhanced" with JavaScript.

Good article...

Comparison between different frameworks would also be great..

Cheers,

Jorge.

Billy Clark replied on Wed, 2012/10/31 - 11:39am in response to: Borislav Iordanov

I appreciate you're using the HTTP spec and understand the fuzziness better now, I'm onboard with your reason more, thanks for the clarifying!

Richard Youngkin replied on Wed, 2012/10/31 - 8:44pm in response to: Borislav Iordanov

Here is an excellent article describing the semantics of PUT vs. POST - http://jcalcote.wordpress.com/2008/10/16/put-or-post-the-rest-of-the-story.

To elaborate on your explanation a little bit, PUT is a complete replacement of a resource whereas POST can be used to update part of a resource and does not have to be a full replacement.  There are also implications WRT web behaviors specified by the HTTP protocol such as caching.  But the article above covers all that...

Cheers,
Rich

Omos Aziegbe replied on Thu, 2012/11/01 - 5:09am

Thanks a lot for this article. I thoroughly enjoyed reading this.

Javier Benek replied on Tue, 2012/11/06 - 1:45am

For Groovy you can take a look at Ratpack, it's still in beta but is awesome.

Claude Lalyre replied on Fri, 2012/11/09 - 11:15am

 Thanks for sharing this big picture view of REST !

Sanjay Srinivas replied on Wed, 2012/11/21 - 11:21am

Thank you for this article. Really helpful!

Henry Kuhl replied on Wed, 2013/01/09 - 10:47am

Hi Borislav!

Nice article on Restful services. I've been reading random stuff about REST during the last weeks. And in almost every talk and every article, the "architects" state, that HYPERMEDIA aka HATEOAS   is one of the key-constraints when designing REST-Services.

Did you miss that point on purpose?

Kind regards

Henry

Borislav Iordanov replied on Wed, 2013/01/09 - 11:31am in response to: Henry Kuhl

Hi Henry,

I don't really understand that constraint. When you are designing a REST interface, what do you do to satisfy it? If you retrieve a resource representation in, say, XML that contains some information about another resource not necessarily in the form of a URI, but enough so that the client can construct a URI, does that qualify as hypermedia? In the readings and talks that you've come across, is there an example of a design that doesn't follow the practice and explains how that's bad, then shows the correct version with a good argument why it's better?

Cheers,

Boris

Henry Kuhl replied on Wed, 2013/01/09 - 1:06pm in response to: Borislav Iordanov

Hi Boris,

the main idea of HATEOAS IMHO (this looks funny :-) is: you're not hard coding the client against fixed URI's but against relations/resources. These are provided by the server in the header of the response. Applying this to your example, the GET-request to the "/new"-URI would provide information, what other operations are possible from that node.

Watch this talk  by Oliver Gierke...it's getting the hypermedia-constraint pretty straight forward.

Additionally, there is something going on regarding an architecture, that is not only RESTful but resource-oriented even on the client side! Here: ROCA-style 


Kind regards

Henry

Michael Zaikin replied on Sat, 2013/01/12 - 5:11am

Can you recommend some good book about REST?

Borislav Iordanov replied on Sat, 2013/01/12 - 12:42pm

Sorry, I haven't come across a book that I would recommend. I think there is very good information around the internet :) Good luck!

Victor Homyakov replied on Wed, 2013/01/16 - 4:00am

Typo in code example:

public Set>Class> getClasses()

should be:

public Set<Class> getClasses()

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.