Saturday, December 1, 2012

REST web service



Why REST (Representational state transfer) web service?


  • simpler to implement & maintain than WSDL contract-based SOAP web services (e.g. less namespace headache)
  • use http method appropriately for CRUD operations (e.g. GET method for retrieving data) thus better semantic compared with SOAP (that use POST method for everything) and match better with web cache infrastructure (thus improving performance & scalability)
  • performance reason: REST webservice is more lightweight than SOAP web services, so it runs faster
  • stateless thus easier to implement (e.g. avoid problems with distributed cache), less performance/scalability risk
  • the directory structure of URI path is intuitive & self documented
  • its payload is not limited to SOAP XML but can vary from XML, JSON, XHTML.
  • easy interface, easy to use by service consumers so REST gets more popular / fast penetration among internet users (e.g. for Open Data movement).
However REST has also several disadvantages compared with SOAP such as:
  • missing self documentation feature of WSDL
  • missing (security) standards such as in the SOAP web service community (WS-Security and other WS-* standards.
  • missing input/output validation using WSDL, an important  security feature 
Nevertheless for many applications, its advantages are outweigh the disadvantages, because of this many companies expose their services using REST, such as Google, Facebook, Amazon.

Request examples

Retrieving a resource:

Http request:
GET /products/10 HTTP/1.1

Response:
HTTP/1.1 200 OK
<products>
 <product id="10">
  <name>sock</name>
 </product>
...
</products>

Another request example with query parameters
GET /orders?minprice=10&minsize=5 HTTP/1.1

Creating a resource:
POST /orders
<order>
<company>asockbuyer</company>
...
</order>

Modifying a resource:
PUT /HRdept/employees/77
<employee>
<name>Allamaraju</name>
<note>favourite author</note>
...
</employee>

Deleting a resource:
DELETE /orders/13


How to implement a REST provider in Java

Basically a REST webservice is just a servlet. First you detect which web method (e.g. GET, POST) sent by the client to decide with operation your webservice need to perform (e.g. a GET method means a query/read operation). Then you extract (& tokenize) the query parameters from the URL (e.g. employeeid) and feed them to the backend (e.g. request to a SOAP web service, or SQL query to a database). Then transform the response from the backend (e.g. to XML if your REST response is XML) and pass it to the output stream of your servlet.

Using JAX-RS API the implementation is even easier using annotations, for example:

@GET
@Path("products/{id}")
@Produces("application/xml")
public StreamingOutput getProduct(@PathParam("id") int id) {
  final Product  aproduct = AtomicProductDBService.get(id);
  return new StreamingOutput() {
      public void write(OutputStream outputStream)  throws IOException, WebApplicationException {
         produceOutputStream(outputStream, aproduct);
     }
  }
}

Here you specify the REST operation using @GET, specify the output format (XML) using @Produces, specify the URI path using @Path and query parameter (id) using @PathParam.

Implementation references:
  • Java Servlet in WebLogic http://docs.oracle.com/cd/E17904_01/web.1111/e13734/rest.htm#WSADV572
  • JAX-RS, read RESTful Java with Jax-RS by Burke.
  • Java CXF framework, read Developing Web Services with Apache CXF and Axis2 by Tong
  • Oracle OSB (using http transport to extract the query parameters and map these parameters to the service call out to the backend web services), read Oracle Service Bus 11g Development Cookbook by Schmutz et.al.

REST web service Security

In principle to protect REST web services you use the same security methods as other web applications:

TLS Basic authentication
GET /employee HTTP/1.1
Host: www.mycompany.org
Authorization: Basic theBase64EncodingOfLogin:Password

TLS digest authentication
GET /employee HTTP/1.1
Host: www.mycompany.org
Authorization: Digest username="employeeapp.001", realm="Employee app", nonce="anonce",
uri="/salarymanag", response="computedresponse",
cnonce="anothernonce", nc=00000001, qop="auth"
The basic idea is to hide the authentication id & password from the attackers. The response is computed using hash of the combination of userid, realm, password, request method, URI and the nonce. The nonces are used to prevent replay attack.

Protect the query parameters with signature
GET /salarymanagement?employeeid=...&signature=... HTTP/1.1
Host: www.mycompany.org

Protect the query parameters with encryption
GET /salarymanagement?encryptedqueryparams HTTP/1.1
Host: www.mycompany.org

Others web application security mechanism applicable for REST for example:
  • Client certificate (2-way) authentication (https) & SSL Encryption: see the guidelines of your specific web server.
  • OAuth
  • SSO (e.g. Shibolleth, Kerberos)

Best practices & guidelines



Source: Steve's blogs http://soa-java.blogspot.com/

Any comments are welcome :)




References:



Developing Web Services with Apache CXF and Axis2 by Tong


Oracle Service Bus 11g Development Cookbook by Schmutz et.al.

RESTful Web Services Cookbook by Allamaraju

RESTful Java with Jax-RS by Burke



No comments: