Friday, October 11, 2013

Understanding REST

The following is excerpted from: http://rest.elkstein.org
What is REST?
REST stands for Representational State Transfer. It relies on a stateless, client-server, cacheable communications protocol -- mostly, the HTTP protocol is used. REST is an architecture style for designing networked applications. The idea is that, rather than using complex mechanisms such as CORBA, RPC or SOAP to connect between machines, simple HTTP is used to make calls between machines. REST uses HTTP for all four CRUD (Create/Read/Update/Delete) operations. Thus, REST is a lightweight alternative to mechanisms like RPC (Remote Procedure Calls) and Web Services (SOAP, WSDL, et al.).

The notion of REST was created in the PhD dissertation of Roy T. Fielding.

Benefits:
REST architecture has all the benefits of Web Service:
  • Platform-independent (you don't care if the server is Unix, the client is a Mac, or anything else),
  • Language-independent (C# can talk to Java, etc.),
  • Standards-based (runs on top of HTTP), and
  • Can easily be used in the presence of firewalls.

Like Web Services, REST offers no built-in security features, encryption, session management, QoS guarantees, etc. But also as with Web Services, these can be added by building on top of HTTP (like use https and use of basic auth etc).

One thing that is not part of a good REST design is cookies: The "ST" in "REST" stands for "State Transfer", and indeed, in a good REST design operations are self-contained, and each request carries with it (transfers) all the information (state) that the server needs in order to complete it.

Example: 

To lookup a user by ID, REST URI is: 

http://www.acme.com/phonebook/UserDetails/12345?firstName=John&lastName=Doe

This URL is sent to the server using a simpler GET request, and the HTTP reply is the raw result data. If you need to pass long parameters, or binary ones, you'd normally use HTTP POST requests, and include the parameters in the POST body.

It is a common convention in REST design to use nouns rather than verbs to denote simple resources.

Real- world REST API docs:
1. Twitter - https://dev.twitter.com/docs/api - They use only GET and POST (used for create/update/delete).

  • For create - https://api.twitter.com/1.1/direct_messages/new.json
  • For Delete - https://api.twitter.com/1.1/direct_messages/destroy.json

2. Amazon S3 - http://docs.aws.amazon.com/AmazonS3/2006-03-01/API/APIRest.html
3. Google Glass' Mirror API - http://www.youtube.com/watch?feature=player_embedded&v=JpWmGX55a40
4. Facebook - https://developers.facebook.com/docs/reference/apis/
5. LinkedIn - http://developer.linkedin.com/apis



Components of REST Architecture:

  • Resources - identified by logical URLs. Resources are the key element of a true RESTful design, as opposed to "methods" or "services" used in RPC and SOAP Web Services, respectively. You do not issue a "getProductName" and then a "getProductPrice" RPC calls in REST; rather, you view the product data as a resource -- and this resource should contain all the required information (or links to it). Whenever relevant, a resource should contain links to additional information -- just as in web pages.
  • There is no connection state; interaction is stateless (although the servers and resources can of course be stateful). Each new request should carry all the information required to complete it, and must not rely on previous interactions with the same client.
  • Resources should be cachable whenever possible (with an expiration date/time). The protocol must allow the server to explicitly specify which resources may be cached, and for how long. The HTTP cache-control headers are used for this purpose.

Design Guidelines:

  1. Queries should not return an overload of data. If needed, provide a paging mechanism. For example, a "product list" GET request should return the first n products (e.g., the first 10), with next/prev links.
  2. GET access requests should never cause a state change. Anything that changes the server state should be a POST request (or other HTTP verbs, such as DELETE).
  3. Rather than letting clients construct URLs for additional actions, include the actual URLs with REST responses.
Another advantage of REST lies with performance: with better cache support, lightweight requests and responses, and easier response parsing, REST allows for nimbler clients and servers, and reduces network traffic, too.

Documenting REST Services:
With version 2.0, WSDL supports all HTTP verbs and it is now considered to be an acceptable method of documenting REST services (WSDL 1.0 only supported HTTP GET and POST verbs).
The second alternative is WADL, the Web Application Description Language which is light weight compared to WSDL and less verbose.


Here is a WADL specification, describing Yahoo "News Search" service:

 1 <?xml version="1.0"?> 
 2 <application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 3  xsi:schemaLocation="http://wadl.dev.java.net/2009/02 wadl.xsd" 
 4  xmlns:tns="urn:yahoo:yn" 
 5  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
 6  xmlns:yn="urn:yahoo:yn" 
 7  xmlns:ya="urn:yahoo:api" 
 8  xmlns="http://wadl.dev.java.net/2009/02"> 
 9   <grammars> 
10     <include 
11       href="NewsSearchResponse.xsd"/> 
12     <include 
13       href="Error.xsd"/> 
14   </grammars> 
15 
16   <resources base="http://api.search.yahoo.com/NewsSearchService/V1/"> 
17     <resource path="newsSearch"> 
18       <method name="GET" id="search"> 
19         <request> 
20           <param name="appid" type="xsd:string" 
21             style="query" required="true"/> 
22           <param name="query" type="xsd:string" 
23             style="query" required="true"/> 
24           <param name="type" style="query" default="all"> 
25             <option value="all"/> 
26             <option value="any"/> 
27             <option value="phrase"/> 
28           </param> 
29           <param name="results" style="query" type="xsd:int" default="10"/> 
30           <param name="start" style="query" type="xsd:int" default="1"/> 
31           <param name="sort" style="query" default="rank"> 
32             <option value="rank"/> 
33             <option value="date"/> 
34           </param> 
35           <param name="language" style="query" type="xsd:string"/> 
36         </request> 
37         <response status="200"> 
38           <representation mediaType="application/xml" 
39             element="yn:ResultSet"/> 
40         </response> 
41         <response status="400"> 
42           <representation mediaType="application/xml" 
43             element="ya:Error"/>
44         </response> 
45       </method> 
46     </resource> 
47   </resources> 
48 
49 </application>
WADL uses type safety using XML schema types.
To author WADL, get the  http://www.w3.org/Submission/wadl/wadl.xsd and use a tool that can validate your WADL.xml against the WADL.xsd (one such tool is - XRay XML Editor or you can use http://www.utilities-online.info/xsdvalidation/). Apigee has created a WADL Builder - https://github.com/apigee/WADL-builder

Some REST advocates, however, find even the lightweight WADL to be an overkill. And indeed, most REST services are documented by no more than a textual description (a human-readable HTML file).

Using REST in Java


package rest.client;



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

/**
 * A Simple REST client using Java HttpURLConnection class.
 *
 * @author rwatsh
 */
public class RestClient {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        System.out.println(httpGet("http://localhost:8080/CustomerDB/webresources/entities.customer"));
    }

    public static String httpGet(String urlStr) throws IOException {
        URL url = new URL(urlStr);
        HttpURLConnection conn =
                (HttpURLConnection) url.openConnection();

        if (conn.getResponseCode() != 200) {
            throw new IOException(conn.getResponseMessage());
        }

        // Buffer the result into a string
        BufferedReader rd = new BufferedReader(
                new InputStreamReader(conn.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = rd.readLine()) != null) {
            sb.append(line);
        }
        rd.close();

        conn.disconnect();
        return sb.toString();
    }

    public static String httpPost(String urlStr, String[] paramName,
            String[] paramVal) throws Exception {
        URL url = new URL(urlStr);
        HttpURLConnection conn =
                (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setUseCaches(false);
        conn.setAllowUserInteraction(false);
        conn.setRequestProperty("Content-Type",
                "application/x-www-form-urlencoded");

        // Create the form content
        OutputStream out = conn.getOutputStream();
        Writer writer = new OutputStreamWriter(out, "UTF-8");
        for (int i = 0; i < paramName.length; i++) {
            writer.write(paramName[i]);
            writer.write("=");
            writer.write(URLEncoder.encode(paramVal[i], "UTF-8"));
            writer.write("&");
        }
        writer.close();
        out.close();

        if (conn.getResponseCode() != 200) {
            throw new IOException(conn.getResponseMessage());
        }

        // Buffer the result into a string
        BufferedReader rd = new BufferedReader(
                new InputStreamReader(conn.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = rd.readLine()) != null) {
            sb.append(line);
        }
        rd.close();

        conn.disconnect();
        return sb.toString();
    }
}

Yahoo has a nice documentation of how to use Java for REST - http://developer.yahoo.com/java/howto-reqRestJava.html.

References:

No comments:

Popular micro services patterns

Here are some popular Microservice design patterns that a programmer should know: Service Registry  pattern provides a  central location  fo...