Cloud Programming REST API

Cloud Programming REST API is at the core of an application that interacts with any of the cloud service types (IaaSPaaS, or Saas). These APIs are an important component of the cloud architecture. They abstract out the infrastructure and protocol details and allow you to communicate with your selected service.

To use these APIs effectively, you must understand the principles on which they are built. To this end, when you think cloud, you must think Web and the underlying protocol used to exchange information. We are all familiar with accessing a page on the Web using a browser. Well, when you access a Web page a request is issued from your computer (client browser) to the Web site (hosting server) using the HTTP protocol.

REST

The majority of the cloud programming REST APIs are built on the HTTP protocol where the Web is the platform. For more information, see HTTP 1.1 rfc 2616.

More specifically, the majority of the cloud services (and related APIs) are designed using an architectural style known as Representational State Transfer (REST). This style is widely used and is a simpler alternative to SOAP and related Web Services Description Language (WSDL).

Capitalizing on the Web success and based on its semantics, REST formalizes a set of principles by which you can design cloud services to access system’s resources, including how resource states are addressed and transferred over HTTP by a wide range of clients. As first described by Roy Fielding in his seminal thesis Architectural Styles and the Design of Network-based Software Architectures, REST is a set of software architectural principles that use the Web as a platform for distributed computing. Since then, REST has emerged as the predominant Web service design model.

Representational State Transfer

The Web is composed of resources. A resource is any item worth to be exposed. For example, the Sunshine Bakery Inc. may define a chocolate truffle croissant resource. Clients may access that resource with this URL:

http://www.sunshinebakery.com/croissants/croissant/chocolate-truffle

representation of the resource is returned for example, croissant-chocolate-truffle.html. The representation places the client application in a state. If the client traverses a hyperlink in the page, the new representation places the client application into another state. As a result, the client application changes (transfers) state with each resource representation

REST Design Principles

In its essence, a REST service follows these design principles:

  1. Proper use of HTTP methods.
  2. Stateless design.
  3. Directory like URIs.
  4. XML or JavaScript Object Notation (JSON) format.

Proper Use of HTTP Methods

A key design principle of a RESTful service is the proper use of HTTP methods that follows the protocol as defined in the RFC 2616.

For example, HTTP GET is a data-producing method that is intended to be used by a client to perform one of the following operations:

  1. Retrieve a resource.
  2. Obtain data from a Web service.
  3. Execute a query with the expectation that the Web service will look for and respond with a set of matching resources.

REST guidelines instruct the developers to use HTTP methods explicitly and in a way that is consistent with the protocol definition. This means a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods as follows:

  1. Retrieve a resource with GET.
  2. Create a resource on the service with POST.
  3. Update a resource with PUT.
  4. Remove a resource with DELETE.

Create a Resource (POST)

The correct way to create a resource is by using the HTTP POST method. All the parameter names and values are contained in XML tags. The payload, an XML representation of the entity to create, is sent in the body of an HTTP POST whose request URI is the intended parent of the entity as shown in the next example.

Host: myserver
Content-Type: application/xml
<?xml version="1.0">
<croissant>
  <name>chocolate-truffle</name>
</croissant>

The previous example shows a correct RESTful request which uses HTTP POST and includes the payload in the body of the request.

On the service, the request may be processed by adding the resource contained in the body as a subordinate of the resource identified in the request URI; in this case the new resource should be added as a child of /croissants. This containment relationship between the new entity and its parent, as specified in the POST request, is analogous to the way a file is subordinate to its parent directory. The client sets up the relationship between the entity and its parent and defines the new entity’s URI in the POST request.

Retrieve a Resource (GET)

A client application may get a representation of the resource (chocolate-truffle) using the URI, noting that at least logically the resource is located under /croissant, as shown in the next GET request.

GET /croissant/chocolate-truffle HTTP/1.1
Host: myserver
Accept: application/xml

This is an explicit use of GET which is for data retrieval only. GET is an operation that must be free of side effects, this property is also known as idempotence.

 Warning

Some APIs use GET to trigger transactions on the server for example, to add records to a database. In these cases the GET request URI is not used properly as shown next:

GET /addcroissant?name=chocolate-truffle HTTP/1.1

This is an incorrect design because GET request has side effects. If successfully processed, the result of the request is to add a new croissant type to the data store.  The following are the problems with this design:

  1. Semantic problem. Cloud services are designed to respond to HTTP GET requests by retrieving resources that match the path (or the query criteria) in the request URI and return a representation in a response, not to add a record to the database. This is an incorrect use of GET that is not compliant with of HTTP/1.1 protocol, using GET.

  2. Unintentional side effects. By triggering a change in the server-side state, could unintentionally allow Web caching tools (crawlers) and search engines to make server-side changes simply by crawling a link.

Update a Resource (PUT)

You use HTTP PUT request to update the resource, as shown in the following example:

Content-Type: application/xml
<?xml version="1.0">
<croissant>
  <name>chocolate-bonbon&lt</name>
</croissant>

The use of PUT to update the original resource provides a clean interface consistent with the definition of HTTP methods. The PUT request is proper for the following reasons:

  1. It identifies the resource to update in the URI.
  2. The client transfers a new representation of the resource in the body of the request.

Good Design Practices

  1. A well designed cloud service uses HTTP methods explicitly followed by nouns in URIs. The verbs POST, GET, PUT, and DELETE are all that is needed and are already defined by the protocol.  This allows clients to be explicit about the operations they invoke. The API should not define more verbs or remote procedures, such as /addcroissant or /updatecroissant.

  2. The body of an HTTP request transfers resource state, it does not carry the name of a remote method or remote procedure to be invoked.

Stateless Design

Cloud REST services need to scale to meet high performance demands. Clusters of servers with load-balancing and failover capabilities, proxies, and gateways allow requests to be forwarded from one server to the other to decrease the overall response time of a service call. Using intermediary servers to improve scale requires clients to send complete, independent requests which include all data needed by a request so that the components in the intermediary servers may forward, route, and load-balance without any state being held locally in between requests.

 A complete, independent request doesn’t require the service to retrieve any kind of application context or state. A client application includes within the HTTP headers and body of a request all the parameters, context, and data needed by the server-side component to generate a response.

A stateless service not only performs better, it shifts most of the responsibility of maintaining state to the client application. In a REST service, the server is responsible for generating responses and for providing an interface that enables the client to maintain the application state. For example, in the request for a multipage response, the client should include the actual page number to retrieve instead of simply asking for the next page as shown in the next figure.

A stateless service generates a response that links to the next page number in the set and lets the client do what it needs to keep this value around. This service design can be divided into two groups of responsibilities that clarifies how a stateless service can be created:

Service Responsibilities

  • Generate responses that include links to other resources. This allows client applications to navigate between related resources. This type of response embeds links.  If the request is for a parent or container resource, a typical REST response might also include links to the parent’s children or subordinate resources so that these remain connected.

  • Generate responses that indicate whether they are cacheable. This improves performance by reducing the number of requests and by eliminating some requests entirely. The service does this by including a Cache-Control and Last-Modified (a date value) HTTP response header.

Client Responsibilities

  • Use the Cache-Control response header. This determines whether to cache the resource (make a local copy). The client also reads the Last-Modified response header and sends back the date value in an If-Modified-Since header to ask the service if the resource has changed. In this conditional GET,  the service’s response is a standard 304 code (Not Modified) which omits the actual resource requested if it has not changed since last time it was modified. The client can safely use the cached resource, bypassing subsequent GET requests.

  • Send complete requests that can be serviced independently of other requests. The client uses HTTP headers as specified by the service and send complete representations of resources in the request body. The client sends requests that make very few assumptions about prior requests, the existence of a session on the server, the server’s ability to add context to a request, or about application state that is kept in between requests.

This collaboration between client application and service is essential to for a  stateless service. It improves performance by saving bandwidth and minimizing server-side application state.

Directory like URIs

The URIs determine how intuitive the REST service is and whether the service is going to be used in ways that the designers can anticipate.  URIs should be intuitive to the point where they are easy to guess. Ideally a URI should be self-documenting and must requires little explanation to understand how to access resources. In other words, a URI should be straightforward, predictable, and easy to understand.

One way to achieve this level of usability is to define directory like URIs that is the URI is hierarchical, rooted in a single path. Its branches are subpaths that expose the service’s main areas.  A URI is a tree with subordinate and superordinate branches connected at nodes. For example, in

http://www.sunshinebakery.com/croissants/croissant/{croissant}

The root, /croissants, has a /croissant node beneath it. Underneath that there are a series of croissants names, such as chocolate-truffle, raspberry-jam, and so on, each of which points to a croissant type. Within this structure, it’s easy to get a croissant by typing the specific croissant name after /croissant/.

Additional URIs Guidelines

  • Hide the server-side scripting technology file extensions (.jsp, .php, .asp), if any, so you can port to something else without changing the URIs.
  • Keep everything lowercase.
  • Substitute spaces with hyphens or underscores (one or the other).
  • Avoid query strings as much as possible.
  • Provide a default page or resource as a response instead of using 404 Not Found code if the request URI is for a partial path.
  • URIs should also be static so that when the resource changes or the implementation of the service changes, the link stays the same. This allows bookmarking.
  • It’s also important that the relationship between resources that’s encoded in the URIs remains independent of the way the relationships are represented where they are stored.

XML or JSON Format

The representation of a resource reflects the current state of the resource and its attributes, at the time a client requests it. The representation is a snapshot in time.

Client and service exchange  a resource representation in the request/response payload or in the HTTP body using XML or JSON format. It is very important to keep things simple and human-readable. The following are some guidelines to keep in mind:

  • The objects in the data model are usually related and the relationships between data model objects (resources) should be reflected in the way they are represented for transfer to a client application.
  • The client applications should have the ability to request a specific content suited for them. So the service should use the built-in HTTP Accept header, where the value of the header is a MIME type.  This allows the service to be used by a variety of clients written in different languages running on different platforms and devices.

Using MIME types and the HTTP Accept header is a mechanism known as content negotiation. This lets clients choose which data format is right for them and minimizes data coupling between the service and applications.

RELATED ARTICLES

Representational State Transfer (REST)

The Web architecture has influenced the REST genesis and the way other kinds of distributed systems are created. In its essence the Web is based on these fundamental principles (architectural style):

REST Context

REST Context

Resource Representation

A resource is the basic building block of a distributed system (and the Web) and represents anything that a service can expose such as a document, a video or a business process. What is exposed is not the actual resource but its representation. This representation is encoded in one or more transferrable formats such as HTML, XML, JSON, plain text, JPEG and so on. A simple example is a Web page.

A service accesses a resource representation never the underlying resource. This separation allows loose coupling between a client application and the service and also allows scalability because a representation can be cached and replicated.

Each representation is a view of the same actual resource, with transfer formats negotiated at runtime through a content negotiation mechanism.

Resource State

A service progresses by transitioning from one state to another like in a state machine. The key difference is that in the service the possible states and the transitions amongst them are not known in advance. As the service gets to a new state, the next possible transitions are discovered.

For example, in an hypermedia system the states are defined by uniquely identifiable resources. The identifiers of the possible states to transition are contained in the current (state) representation as hyperlinks. Hence the name Representational State Transfer (REST).

Resource Address

A service can act on a resource (i.e., representation) through a very well defined set of verbs as provided by the HTTP protocol. For more information, see HTTP 1.1 rfc 2616. This set provides a uniform interface or a small number of verbs with well defined and widely accepted semantics to meet the requirements of a distributed system.

To act upon a resource the service must be able to identify it unequivocally. Tis is done through the Uniform Resource Identifier (URI).  A URI uniquely identifies a resource and makes it addressable or capable of being manipulated using a protocol such as HTTP.

A one to many relationship exists between a resource and URIs. A URI identifies only one resource, but a resource can have more than one URI.

A URI takes the following form:

http://scheme-specific_structure

For example

http://myserver/croissants/croissant/chocolate-truffle

establishes that the URI must be interpreted by the service according to the HTTP scheme. Notice that the previous URI does not specifies the resource format.

Best Practices

It is good practice not to specify the format in the URI by adding a suffix to the resource such as .html or .xml or .jsp. It is the responsibility of the service to provide the correct format as specified by the client in the Accept attribute of the HTTP request header (content negotiation). This allows loose coupling between the client and the service.

Service Maturity Level

Leonard Richardson created a maturity model to classify services as highlighted next.

  • Level 0. Services use a single URI (end point) to “tunnel” remote procedure invocation. Typically they use only one HTTP verb (POST or GET) to communicate with the end point. SOAP Web Services with XML Payload (POX) are an example at this level.
  • Level 1. Services use multiple URIs (end points) and a single HTTP verb (GET or POST).  A client uses multiple resources to perform different tasks.
  • Level 2. Services use multiple URIs (end points) and multiple HTTP verbs. The idea is to closely follow the semantics of the HTTP verbs according to specification. That is GET reads, POST creates, PUT updates and DELETE removes a resource similarly to the CRUD operations.
  • Level 3. Services provide links to other resources to the client. RESTful services in particular HATEOAS (Hypermedia As The Engine Of Application State) services operate at Level 3 maturity.

 

Putting to REST the Cloud Service APIs

I had to deal with the Representational state transfer (REST) API conundrum in the past. A lot of information obfuscated what in its essence is a very straightforward concept.

The REST API is not strictly speaking an “API”, if you refer to the HTTP protocol verbs. REST, in the words of its originator Roy Fielding, is an “architectural style”. Specifically, it is a set of guidelines that hinge on the HTTP protocol specifications. See http://www.w3.org/Protocols/.

Why should you care about this mambo jumbo? Well, believe it or not,this style is the corner stone of all the Cloud  (Web) services. At its core a Cloud service is stateless.  All the information about state is on the client side. For example, if you take a web page, once it has been delivered to the client, there is no memory on the server side keeping track of “what to do next”. What to do next, that is all the state information, is in the page itself in terms of hyperlinks. In essence, besides  its HTML content,  the hyperlinks in the page are the representational state transfer.

REST guidelines instruct the developers to use HTTP verbs explicitly and in a way that it is consistent with the protocol definition. This means a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP verbs as follows:

  • Create a resource with POST
  • Retrieve a resource with GET
  • Update a resource with PUT
  • Delete a resource with DELETE

You can find more verbs here.

Why is REST Popular?

Because HTPP is ubiquitous, as a higher protocol in the application layer of the OSI model, the HTTP (REST) verbs have become the minimalist, effective and standard way to exchange information (text, images, videos and so on) on the Internet.

The following figure shows where the HTTP protocol is located in the OSI model:

OSI Model

Where is the API?

Well, any company that is in the web services business (shall we say Cloud), provides a set of libraries to support the most common programming languages (Java, Python, C#, etc…). A programmer can use a familiar programming language to perform requests associated with HTTP verbs. She must know a company specific library to make API calls. The library translates the calls into the appropriate HTTP verb requests. It also fills the HTTP protocol details such as header information.

The following is a logical diagram, albeit a simplified one, of the main components involved in a RESTful exchange:

REST API

The following code examples show how to list the objects in a bucket (stored in a public cloud storage “the service”):

  • The following code examples show how to list the objects in a bucket (stored in a public Cloud storage “the service”):

    Python

    def listObjects(bucketName, service):
      print 'List objects contained by the bucket "%s".' % bucketName
      fields_to_return = 'nextPageToken,items(bucket,name,metadata(my-key))'
      request = service.objects().list(bucket=bucketName, fields=fields_to_return)
      response = request.execute()
      print json_dumps(response, indent=2)
    

    Java

    Storage.Buckets.List listBuckets =
      service.buckets().list(settings.getProject());
    buckets = listBuckets.execute();
    for (Bucket bucket : buckets.getItems()) {
      displayMessageHeader("Getting bucket " + bucket.getName() + " metadata");
      displayBucketInformation(bucket);
    }
    

Under the hood, a GET request is issued. But you do not see it in the code snippet above.
What you see is an API call as highlighted.

Leave a Reply

Your email address will not be published. Required fields are marked *