Sunday, March 6, 2011

Create REST using Basic J2EE

    We have already seen what a REST Web Service looks like. Let us try to create a sample for the same. Consider an Order Service example for a company ABC Inc. which needs a service (OrderService) for its clients. In its most basic form, it will have 2 operations

  1. To retrieve an order when an order id is passed. (HTTP GET)
  2. To store an order. (HTTP POST)
Any client who wishes to know the details of a particular order can just pass the order id and retrieve the order xml which contains all the order data. Alternatively if we need to create a new order or update an existing order, we can "POST" the data (the complete order xml) and save it. ABC Inc has decided to implement such a service using REST owing to the simplicity of the service.

In a true REST service, all data is viewed as resources. Thus each order (i.e. the order xml) is a unique xml which is identified by a unique URL. (eg. http://localhost:8080/RestOrderService/order/123 corresponds to the order xml against the order id 123, while http://localhost:8080/RestOrderService/order/456 will correspond to the order xml against the order id 456). Depending on the HTTP method (GET/POST/DELETE/PUT) we will either retrieve (GET) or store (POST) the data.

    Thus the service endpoint can be implemented as a Servlet (com.abc.orderservice.RestEndpoint) targeting all requests with /order/* URL. The Servlet overrides 2 methods the doGet method and doPost method. The doGet method is used to retrieve the XML from the database and stream back to the user. The doPost method is used to send the new order xml to the service. The order xml is contained in the HTTP Body, where it is read and then stored in the database. The sample code is given below.

 public class RestEndpoint extends HttpServlet {  
      @Override // This method is for the get verb.  
      protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
                throws ServletException, IOException {  
           String orderId = req.getPathTranslated();   
 // Authenticate User  
           // retrieve file from DB using id = orderId  
           OutputStream out = resp.getOutputStream();  
           out.write("<?xml version=\"1.0\" > <order><id>1234</id><custId>2122</custId></order>".getBytes());  
           // stream back the response retrieved from DB.  
      }  
      @Override // this method is for the post verb  
      protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
                throws ServletException, IOException {  
           String orderId = req.getPathTranslated();  
           InputStream orderXML = req.getInputStream();  
 // Validate Incoming XML  
           //store orderXML stream in DB against the orderId.   
      }  
 }  

Looks simple right? It is. However before we actually "publish" this service, we need to add a few features like

  1. Validation of incoming XML data
  2. Authentication of User
  3. Buffered streaming of data
  4. Exception Handling
And as our service functionality expands we land up repeating a large part of the code in multiple places (all the above mentioned code). Thus we actually spend a large amount of time in actually performing repetitive tasks like those listed above instead of concentrating on business logic. What if this code, commonly known as "boilerplate code", could be extracted out into an API and we could have someone else do the job for us using either configuration metadata or interceptors. (We can achieve the same by actually ourselves doing the same job however one should realize that it would take more time than writing the business logic itself). This is where toolkits like JAX-WS, Axis and Spring-WS come in. They help us provide the boilerplate code that we need to provide for our service and make our lives simpler. We look at another example using SOAP in the next article where we actually see how hugely repetitive tasks are extracted and moved into frameworks (or toolkits) to make web service development easier.


 

2 comments:

  1. Good Rest tutorial.You can share some more examples simulating a small real project scenario using Axis.
    ex. we can have a tutorial on"implementing Rest using axis ,eclipse and tomcat". That would be more helpful for acolytes like us. Keep up the good work .

    ReplyDelete
  2. Thanks for the appreciation Ashish.
    As for the tutorial, Axis (1.x) has no support for REST. However in one of my lined up articles I will be covering REST using JAX-WS. So hopefully that can help you.

    ReplyDelete