CloudDays™ Quick Start – Introduction to Design Methodology, Patterns for REST

In his talk on Some REST Design Patterns (and Anti-Patterns), Cesare Pautasso explains, “REST architectural style is simple to define, but understanding how to apply it to design concrete REST services in support of SOA can be more complex.”

Several SOA Design Patterns:

  • Uniform Contract
  • Endpoint Redirection
  • Content Negotiation
  • Idempotent Capability

In this post,  you will learn the design methodology, walk through a step by step scenario where the client and server trade information to perform a set of actions, and you will learn more about the SOA design patterns.

REST Summary

In Choosing Between RESTful Web Service, SOAP, you learned that Representational State Transfer (REST) is an architecture style or design pattern for creating web services which allow anything connected to a network to something else on the network using Hypertext Transfer Protocol (HTTP).

Web Services expose data and functionality through resources identified by a Uniform Resource Identifier (URI).

REST has a uniform interface where clients perform stateless interaction with resources using a fixed set of verbs, typically GET (read), PUT (update), DELETE, POST.

You can have multiple representations of the same data.

Hyperlinks model resource relationships and valid state transitions for dynamic protocol description and discovery.

Design Methodology

imageYou should take steps to define your REST :

  1. Identify resources to be exposed as services (e.g., yearly risk report, book catalog, purchase order, open bugs, polls and votes)
  2. Model relationships (e.g., containment, reference, state transitions) between resources with hyperlinks that can be followed to get more details (or perform state transitions)
  3. Define “nice” URIs to address the resources
  4. Understand what it means to do a GET, POST, PUT, DELETE for each resource (and whether it is allowed or not)
  5. Design and document resource representations
  6. Implement and deploy on Web server
  7. Test with a Web browser

(Illustrations from SOA2010 SOA with REST)

Although there are four methods, you can add more resources, such as an author. And you can have multiple representations.

Scenario

Let’s create a simple example in a polling scenario.

in our scenario, you have polls and votes. It’s a containment relationship where you have number of polls in which you have a number of votes.

image

The URIs embed the identifiers of child instance resources.

POST on the container is used to create child resources.

PUT/DELETE us used for updating and removing child resources.

image

Step 1. Create a poll

In the first step, you create poll. In this case, we will use XML in the body. But you can also use JSON.

https://gist.github.com/devdays/9eb8e3333db655fde8ff

In this case, the poll was created using POST with the possible options that the user could select. The server returns a 201 response with the location of the poll and its identifier.

Step 2. Reading the poll

The client can then send a request to the server to read the poll.


GET /poll/770115

view raw

1-cloud-getPoll

hosted with ❤ by GitHub


200 OK
<options>A,B,C</options>
<votes href="vote" />

p>The poll with its identifier are retrieved with 200 OK in the response. The response body includes the options and the reference for the votes.

Step 3. Vote in a particular poll

In this step, you would post the data and return that the data vote was created. The response includes the location of the vote.


201 Created
Location: /poll/770115/vote/1


POST /poll/770115/vote
<name>Bruce Kyle</name>
<choice>C</choice>

Step 4. Retrieve votes

You can then retrieve the votes.


GET /poll/770115


200 OK
<options>A,B,C<options>
<votes>
<vote id="1">
<name>Bruce Kyle</name>
<choice>C</choice>
</vote>
</votes>

Step 5. Update a particular vote

You can now let your user change their mind. In this case, use a PUT to update the particular vote. Note that the URI goes to vote/1.

https://gist.github.com/devdays/c73925dbe98695ae7d6

Step 6. Retrieve

You can then retrieve the poll results again.


GET /poll/770115

view raw

1-retrievePoll

hosted with ❤ by GitHub


200 OK
<options>A,B,C<options>
<votes>
<vote id="1">
<name>Bruce Kyle</name>
<choice>A</choice
</vote>
</votes>

Step 7. Delete the Poll

You can then use the DELETE verb to delete the poll.


DELETE /poll/770115

view raw

1-deletePoll

hosted with ❤ by GitHub


200 OK

Step 8. Retrieve a poll that has been deleted

The server returns an 404 Not Found error because the poll has been deleted.


GET /poll/770115

view raw

1-retrievePoll

hosted with ❤ by GitHub


404 Not Found

view raw

2-responsePoll

hosted with ❤ by GitHub

Uniform Contract

How can consumers take advantage of multiple evolving endpoints? You need to keep your consumer up to date with respect to evolving contracts.

In the previous example, you saw how a Uniform Contract provides for Create, Read, Update, and Delete.

CRUD

HTTP

 
CREATE POST Create a sub resource
READ GET Retrieve the current state of the resource
UPDATE PUT Initialize or update the state of the resource for a given URI
DELETE DELETE Clear a resource, after the URI is no longer valid

POST vs GET

GET is a read-only operation. It can be repeated without affecting the state of the resource and can be cached.

NOTE: This does not mean that the same representation will be returned every time.

POST is a read-write operation and may change the state of the resource and provoke side effects on the server.

POST vs POST

How should you create a resource?

Solution 1. Let the client choose a unique ID


PUT /resource/E809EF63-86D7-4B8B-973E-69C1B509F692

view raw

1-cloud-put

hosted with ❤ by GitHub


201 Created

The downside of this is that how are you sure the client creates a unique identifier?

Solution 2. Let the server compute the unique id


POST /resource


301 Moved Permanently
Location: /resource/E809EF63-86D7-4B8B-973E-69C1B509F692

view raw

2-PostResponse

hosted with ❤ by GitHub

The downside of this is that duplicate instances can be created if requests are repeated due to communication issues.

Endpoint Redirection

How do you provide the consumer with information so they can adapt to changes in your service. For example, you may want to change the structure of your data. It may not be possible to replace all of your old endpoints simultaneously.

In that case, you can automatically refer your consumers that access the stale endpoint to the current identifier.


GET /old


301 Moved Permanently
Location: /new


GET /new


200 OK

HTTP supported endpoint redirection using a combination of the 3xx status codes and standard headers. For example, instead of using 301, you could provide 307 Temporary Redirect:

307 Temporary Redirect
Location: /newUri

Entity Endpoint

How can service consumers support new consumers without changing their contract? How can you change the content and data representation formats?

You want your Web Service to provide for loose coupling, increased interoperability, and increased organizational agility.

You can allow the client to negotiate the message format in a single message. The client can list the set of understood formats (MIME types). Then the server chooses the most appropriate and send the reply (or a 406 error if none can be found.)


GET /resource
Accept: text/html, application/xml, application/json


200 OK
Content-Type: application/json

You can perform content negotiation across different dimensions.

Request Header

Example Values

Response Header

Accept: application/xml,
application/json
Content-Type:
Accept-Language: en, fr, de, es Content-Language:
Accept-Charset: iso-8859-5,
unicode-1-1
Charset parameter of the Content-Type header
Accept-Encoding: compress, gzip Content-Encoding

 

Additional REST Patterns

For more patterns, see SOAPatterns.org.

References

Slideshare: SOA with REST

SOA with REST: Principles, Patterns & Constraints for Building Enterprise Solutions with REST (The Prentice Hall Service Technology Series from Thomas Erl)