Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
REST
eMag Issue 12 - April 2014
What is
REST?
In this presentation summary youll learn
precisely what REST is, and is not, about as well
as the background of REST that caused it to be
defined.
PAGE 9
A BRIEF INTRODUCTION
TO REST
HOW TO GET
A CUP OF COFFEE
REST
ANTI-PATTERNS
RESTFUL JAVA
EVOLVES
PAGE 3
PAGE 14
PAGE 28
PAGE 33
Contents
Page 3
What Is REST?
Page 9
In this presentation summary youll learn precisely what REST is, and is not, about as well
as the background of REST that caused it to be defined. Youll also see how Mike covers the
key principles behind REST, such as HATEOAS as well as tries to debunk some of the myths
behind what is and is not a RESTful service.
Page 14
Jim Webber, Savas Parastatidis and Ian Robinson show how to drive an applications flow
through the use of hypermedia in a RESTful application, using the well-known example from
Gregor Hohpes Starbucks does not use Two-Phase-Commit to illustrate how the Webs
concepts can be used for integration purposes.
REST Anti-Patterns
Page 28
Stefan Tilkov explains some of the most common anti-patterns found in applications that claim
to follow a RESTful design and suggests ways to avoid them: tunneling everything through
GET or POST, ignoring caching, response codes, misusing cookies, forgetting hypermedia and
MIME types, and breaking self-descriptiveness.
Page 33
In Bills session he covers how best to write RESTful services in Java using the JAX-RS standard.
He goes into detail about the various annotations and options that JAX-RS 2.0 provides as
well as what drove their development. By the end of this you will understand JAX-RS and at
least be able to do further deep dives for yourself with the copious materials found on InfoQ
or elsewhere.
Page 3
Page 4
OrderManagementService
+
+
+
+
+
+
+
class Resource {
Resource(URI u);
Response get();
Response post(Request r);
Response put(Request r);
Response delete();
}
getOrders()
submitOrder()
getOrderDetails()
getOrdersForCustomers()
updateOrder()
addOrderItem()
cancelOrder()
+
+
+
+
+
getCustomers()
addCustomer()
getCustomerDetails()
updateCustomer()
deleteCustomer()
You can see that there are two services defined here
(without implying any particular implementation
technology). The interface to these services is
specific to the task its an OrderManagement and a
CustomerManagement service we are talking about.
If a client wants to consume these services, it needs
to be coded against this particular interface. There
is no way to use a client that was built before these
interfaces were specified to meaningfully interact
with them. The interfaces define the services
application protocol.
In a RESTful HTTP approach, you would have to
get by with the generic interface that makes up the
Page 5
/orders
GET - list all orders
PUT - unused
POST - add a new order
DELETE - unused
/orders/{id}
GET - get order details
PUT - update order
POST - add item
DELETE - cancel item
<<interface>>
Resource
GET
PUT
POST
DELETE
/customers
GET - list all customers
PUT - unused
POST - add a new customer
DELETE - unused
/customers/{id}
GET - get customer details
PUT - update customer
POST - unused
DELETE - delete customer
/customers/{id}/orders
GET- get all orders for customer
PUT - unused
POST- add order
DELETE - cancel all customer
orders
Operations
Instances
Page 6
Communicate statelessly
The last principle I want to address is stateless
communication. First of all, its important to
stress that although REST includes the idea of
statelessness, this does not mean that an application
that exposes its functionally cannot have state in
fact, this would render the whole approach pretty
useless in most scenarios. REST mandates that
state be either turned into resource state or kept
on the client. In other words, a server should not
have to retain some sort of communication state
Contents
REST in theory
I have a confession to make. What I explained is not
really REST and I might get flamed for simplifying
things a little too much. But I wanted to start things
differently than usual, so I did not provide the formal
background and history of REST at the beginning. Let
me try to address this, if somewhat briefly.
Ive avoided taking great care to separate REST from
HTTP itself and the use of HTTP in a RESTful way. To
understand the relationship between these different
aspects, we have to look at the history of REST.
The term REST was defined by Roy T. Fielding in his
Ph.D. thesis (you might actually want to follow that
link its quite readable for a dissertation). Roy had
been one of the primary designers of many essential
Web protocols, including HTTP and URIs, and he
formalized a lot of the ideas behind them in the
document. (The dissertation is considered the REST
Bible, and rightfully so. The author invented the term
so, by definition, anything he wrote about it must be
considered authorative.) In the dissertation, Roy first
defines a methodology to talk about architectural
styles: high-level, abstract patterns that express the
core ideas behind an architectural approach. Each
architectural style comes with a set of constraints
that define it. Examples of architectural styles
include the null style (which has no constrains at all),
pipe and filter, client/server, distributed objects, and
you guessed it REST.
Page 7
Summary
I have attempted to quickly introduce the concepts
behind REST, the architecture of the Web. A RESTful
HTTP approach to exposing functionality is different
from RPC, distributed objects, and Web services;
it takes some mind shift to really understand this
difference. Awareness of REST principles is beneficial
whether you are building applications that expose
only a Web UI or want to turn your application API
into a good Web citizen.
Contents
Page 8
What Is REST?
by Mike Amundsen, Director of API Architecture, API Academy, CA / Layer 7 Technologie
Roy T. Fielding described REST more than a decade ago in a dissertation on the
styles and design of software for networks. The REST chapter was just one in a sixchapter dissertation; about 25 pages of a 172-page document. REST is an example
of how Fielding thought about establishing network-level architecture. Its not the
ultimate; its not the only. Its just the example of analysis and design of a style.
However, sometimes when we hear REST, we hear
something very different.
Contents
Page 9
REST Constraints
Fielding identifies six constraints. The first one is the
idea of the client-server relatoinship. The client
always initiates; the server always responds. That
means no peer-to-peer implementations. Fielding
thinks, in order to meet his goals about maximizing
and minimizing, that client-server is the constraint
that should be adopted by everyone.
The next constratinis statelessness. Fielding writes
in his dissertation that the server should not be
responsible for remembering every party to which
it is talking. Servers should be able to forget a client
instantly. The next time something comes in, the
server should be able to start afresh.
Page 10
Page 11
Fieldings REST
As dissertations go, Fieldings is eminently readable.
Chapter 5 is the one that talks about REST. Chapters
2 and 3 are much, much better, I think. Chapters 2
and 3 are sort of historical. In those two chapters,
Fielding talks about what he thinks should be
important in a network architecture, and he talks
Page 12
Contents
Page 13
Introduction
The integration domain is changing. The influence of
the Web and the trend towards more agile practices
are challenging our notions of what constitutes good
integration. Instead of being a specialist activity
conducted in the void between systems or even
worse, an afterthought integration is now an
everyday part of successful solutions.
Yet, the impact of the Web is still widely
misunderstood and underestimated in enterprise
computing. Even those who are Web-savvy often
struggle to understand that the Web isnt about
middleware solutions supporting XML over HTTP,
nor is it a crude RPC mechanism. This is a shame
because the Web has much more value than simple
point-to-point connectivity; it is in fact a robust
integration platform.
Contents
Why workflows?
Workflows are a staple of enterprise computing and
have been implemented in middleware practically
forever (at least in computing terms). A workflow
structures work into a number of discrete steps
and the events that prompt transitions between
steps. The overarching business process that a
workflow implements often spans several enterprise
information systems, making workflows fertile
ground for integration work.
Page 14
Contents
Page 15
<order xmlns=http://starbucks.example.
org/>
<drink>latte</drink>
</order>
Figure 4: POSTing a drink order
Contents
Page 16
Updating an order
One of the nice things about Starbucks is you can
customise your drink in a myriad of ways. In fact,
some of the more advanced customers would be
better off ordering by chemical formula, given the
number of upgrades they demand! But lets not be
that ambitious, at least not to start with. Instead,
well look at another story card:
Response
OPTIONS /order/1234
HTTP 1.1 Host:
starbucks.example.
org
Page 17
Response
PUT /order/1234
HTTP 1.1 Host:
starbucks.example.
com Expect:
100-Continue
100 Continue
200 OK
Location: http://starbucks.example.com/
order/1234
Content-Type: application/xml
Content-Length:
<order xmlns=http://starbucks.example.
org/>
<drink>latte</drink>
<additions>shot</additions>
<cost>4.00</cost>
<next xmlns=http://example.org/
state-machine
rel=http://starbucks.example.
org/payment
uri=https://starbucks.example.
com/payment/order/1234
type=application/xml/>
</order>
Contents
Page 18
Contents
Page 19
Response
OPTIONS/payment/order/1234
HTTP 1.1 Host: starbucks.
example.com
Allow: GET,
PUT
Contents
Page 20
Request
PUT /payment/order/1234 HTTP 1.1
Host: starbucks.example.com
Content-Type: application/xml
Content-Length: ...
<payment xmlns=http://starbucks.
example.org/>
<cardNo>123456789</cardNo>
<expires>07/07</expires>
<name>John Citizen</name>
<amount>4.00</amount>
</payment>
Response
201 Created
Location: https://starbucks.example.com/
payment/order/1234
Content-Type: application/xml
Content-Length: ...
<payment xmlns=http://starbucks.
example.org/>
<cardNo>123456789</cardNo>
<expires>07/07</expires>
<name>John Citizen</name>
<amount>4.00</amount>
</payment>
Figure 12: Paying the bill
Once weve paid for our drink, weve reached the end
of our workflow, and the end of the story as far as
the consumer goes. But its not the end of the whole
story. Lets now go inside the service boundary to
look at Starbucks internal implementation.
Contents
Page 21
200 OK
Expires: Thu, 12Jun2008 17:20:33 GMT
Content-Type: application/atom+xml
Content-Length:
<?xml version=1.0 ?>
<feed xmlns=http://www.w3.org/2005/
Atom>
<title>Coffees to make</title>
<link rel=alternate
uri=http://starbucks.example.
org/orders/>
<updated>2008-06-10T19:18:43z</
updated>
<author><name>Barista System</name></
author>
<id>urn:starbucks:barista:coffees-tomake</id>
<entry>
<link rel=alternate
type=application/xml
uri=http://starbucks.example.
org/order/1234/>
<id>http://starbucks.example.org/
order/1234</id>
</entry>
</feed>
Figure 13: Atom feed for drinks to be made
Contents
Page 22
</content>
</entry>
Contents
Page 23
<entry>
<content type=text+xml>
<order xmlns=http://starbucks.
example.org/>
<drink>latte</drink>
<additions>shot</additions>
<cost>4.00</cost>
<status>preparing</status>
</order>
</content>
</entry>
Request
Response
GET /payment/
order/1234
HTTP 1.1 Host:
starbucks.
example.org
Page 24
Response
GET /payment/
order/1234 HTTP 1.1
Host: starbucks.
example.org
Authorization:
Digest
username=barista
joe
realm=starbucks.
example.org
nonce=...
uri=payment/
order/1234
qop=auth
nc=00000001
cnonce=...
reponse=...
opaque=...
200 OK
Content-Type:
application/xml
Content-Length: ...
<payment
xmlns=http://
starbucks.example.
org/>
<cardNo>123456789</
cardNo>
<expires>07/07</
expires>
<name>John
Citizen</name>
<amount>4.00</
amount>
</payment>
Request
Response
200 OK
Page 25
<next xmlns=http://example.org/statemachine
rel=http://wifi.example.org/freeoffer
uri=http://wifi.example.com/freeoffer/order/1234
type=application/xml/>
Acknowledgements
The authors would like to thank Andrew Harrison of
Cardiff University for the illuminating discussions
around conversation descriptions on the Web.
1. An ETag (an abbreviation of entity tag) is a unique identifier for the state of a resource. An ETag for a resource is
typically an MD5 checksum or SHA1 hash of that resources data.
2. When safety is at stake, of course, we prevent things from going too far wrong in the first place! But receiving coffee
isnt a safety critical task, even though it might seem that way for some most mornings!
3. HTTP 1.1 offers some useful request directives, including max-age, max-stale, and max-fresh, which allow the client
to indicate the level of staleness it is prepared to accept from a cache.
Contents
Contents
Savas Parastatidis is a
software architect in the
Online Services Division
at Microsoft. He builds
technologies for reasoning
over the worlds information
and is interested in all
things related to semantic
computing, knowledge
representation and reasoning,
the Web, and large-scale
services, which led him to
co-author the book REST in
Practice.
Page 27
REST Anti-Patterns
by Stefan Tilkov
When people start trying out REST, they usually start looking for examples and
not only find a lot of examples that claim to be RESTful or are labeled as a REST
API, but also dig up discussions about why a specific service that claims to do
REST actually fails to do so.
Why does this happen? HTTP is nothing new, but
it has been applied in a wide variety of ways. Some
ways are in line with what the Webs designers had
in mind but many are not. Applying REST principles
to your HTTP applications, whether you build them
for human consumption, for use by another program,
or both, means that you do the exact opposite: you
try to use the Web correctly or, if you object to
the idea that one is right and one is wrong, in a
RESTful way. For many, this is a new approach.
The usual standard disclaimer applies: REST, the
Web, and HTTP are not the same thing. REST could
be implemented with many different technologies,
and HTTP is just one concrete architecture that
happens to follow the REST architectural style.
I should be careful to distinguish REST from
RESTful HTTP. Im not careful, so lets assume the
two are the same for the remainder of this article.
Contents
Page 28
Contents
Ignoring caching
Even if you use the verbs as they are intended to be
used, you can still easily ruin caching opportunities.
The easiest way to do so is by including a header
such as this one in your HTTP response:
Cache-control: no-cache
Doing so will simply prevent caches from caching
anything. Of course, this may be what you intend,
but more often than not its just a default setting
thats specified in your Web framework. However,
supporting efficient caching and re-validation is
one of the key benefits of using RESTful HTTP. Sam
Ruby suggests that a key question to ask when
assessing somethings RESTfulness is Do you
support ETags? (ETags are a mechanism introduced
in HTTP 1.1 to allow a client to validate whether
a cached representation is still valid, by means of
a cryptographic checksum). The easiest way to
generate correct headers is to delegate this task
to a piece of infrastructure that knows how to do
this correctly for example, by generating a file in
a directory served by a Web server such as Apache
HTTPD.
Of course, theres a client side to this, too. When
you implement a programmatic client for a RESTful
service, you should exploit the available caching
Page 29
Contents
Misusing cookies
Using cookies to propagate a key to some serverside session state is another REST anti-pattern.
Cookies are a sure sign that something is not
RESTful. Right? Not necessarily. One of the key
ideas of REST is statelessness, although not in
the sense that a server cannot store any data. Its
fine if there is resource state or client state. Its
session state that is disallowed due to scalability,
reliability, and coupling reasons. The most typical
use of cookies is to store a key that links to some
server-side data structure that is kept in memory.
This means that the cookie, which the browser
passes along with each request, is used to establish
conversational, or session, state.
If a cookie is used to store information, such as an
authentication token, that the server can validate
without reliance on session state, cookies are
perfectly RESTful, with one caveat: they shouldnt
be used to encode information that can be
transferred by other, more standardized means (e.g.
in the URI, some standard header or, in rare cases,
in the message body). For example, its preferable
to use HTTP authentication from a RESTful HTTP
point of view.
Forgetting hypermedia
The first REST idea thats hard to accept is the
standard set of methods. REST theory doesnt
specify which methods make up the standard set,
it just says there should be a limited set that is
applicable to all resources. HTTP fixes them at GET,
PUT, POST, and DELETE (primarily, at least), and
casting all of your application semantics into just
these four verbs takes some getting used to. But
having done that, people start using a subset of
what actually makes up REST: a sort of Web-based
CRUD (Create, Read, Update, Delete) architecture.
Applications that expose this anti-pattern are not
really unRESTful (if there even is such a thing),
they just fail to exploit another of RESTs core
concepts: hypermedia as the engine of application
state.
Hypermedia, the concept of linking things together,
is what makes the Web a web, a connected set of
Page 30
Breaking self-descriptiveness
Breaking the constraint of self-descriptiveness is an
anti-pattern so common that its visible in almost
every REST application, even in those created by
those who call themselves RESTafarians, myself
included. Ideally, a message an HTTP request or
HTTP response, including headers and the body
should contain enough information to allow any
generic client, server, or intermediary to process
it. For example, when your browser retrieves some
protected resources PDF representation, you can
see how all of the existing agreements in terms
of standards kick in: some HTTP authentication
exchange takes place; there might be some caching
and/or revalidation; the content-type header
sent by the server (application/pdf) triggers
your system to start its default PDF viewer; and
finally you can read the PDF on your screen. All
other users in the world could use their own
infrastructure to perform the same request. If the
server developer adds another content type, any
of the servers clients (or services consumers) just
need to make sure they have the appropriate viewer
installed.
Every time you invent your own headers, formats,
or protocols, you break the self-descriptiveness
constraint to a certain degree. If you want to take
an extreme position, you can consider anything not
standardized by an official standards body to be
breaking this constraint, and can be considered a
case of this anti-pattern. In practice, you strive to
follow standards as much as possible and accept
that some convention might only apply in a smaller
domain (e.g. your service and the clients specifically
developed against it).
Page 31
Summary
Ever since the Gang of Four published Design
Patterns: Elements of Reusable Object-Oriented
Software, which kickstarted the patterns movement,
many people have misunderstood it and tried to
apply as many patterns as possible, a notion that has
been ridiculed for equally as long. Patterns should
be applied if and only if they match the context.
Similarly, one could religiously try to avoid all of the
anti-patterns in any given domain. In many cases,
there are good reasons to violate any rule, or, in REST
terminology, to relax any particular constraint. Its
fine to do so, but its useful to be aware of the fact,
and make a more informed decision.
Hopefully, this article helps you to avoid some of the
most common pitfalls when starting your first REST
projects.
Contents
Page 32
Contents
Page 33
Contents
@Path(/queue)
public class QueueResource {
@GET
@Suspend
@Produces(application/json)
public void pull(@Context
ExecutionContext ctx)
{
queue.put(ctx);
}
}
The client API for JAX-RS is a fluent low-level API:
a pattern of writing your Java APIs so they look
like DSLs. With this API, you can reuse the content
handlers, the message-body readers, and writers that
you originally wrote on the server side. You can reuse
them back in the client side.
There are really two major pieces of the client API.
You have the client interface, which deals with
configuration, connection management, etc., and a
WebTarget interface that represents a particular URI.
Its really an abstraction for a URI or a URI template.
And from that WebTarget, you can build requests.
One good thing about this WebTarget is that
different services you interact with might have
different authentication models. One URL might use
digest authentication while another might use basic
authentication. You can differently configure each
WebTarget you create.
WebTarget uri =
client.target(http://shop.com/
orders/{id});
uri.register(new CookieCache());
uri.register(new ResponseCache());
uri.setProperty(USERNAME, bill);
uri.setProperty(PASSWORD, geheim);
uri.setProperty(AUTH_TYPE, BASIC);
The client API also has an asynchronous interface. Its
really two different forms. You have a feature from
Java UDL, the concurrent package thats in Java, and
you have the ability to register a callback interface. It
looks the same as a synchronous request except you
are inserting async in there. In this particular case,
instead of getting back an order object, were getting
back a Future that we can pull to see if the request
has been done or not.
Page 34
Future<Order> future =
client.target(http://shop.
com)
.request()
.async()
.get(Order.class);
Order order = future.get();
You get a Future object or you can register a
callback. You register a callback by implementing the
InvocationCallback interface. You specify what youre
interested in getting back.
class MyCall implements
InvocationCallback<Order>
{
public void completed(Order order) {
... }
public void failed(InvocationException
err) {
... }
}
Future<Order> order =
client.target(http://
shop.com).request().async().get(new
MyCall());
Another thing you might want to do with the prematch filter is content negotiation. Instead of sending
an Accept header, you can add a file suffix to your URL
like .text.jason.xml. In that case, a pre-match filter
would strip the suffix, build an Accept header, and
put that into the Java request so that when your Java
resource method gets called, the matching will be
based on the available information.
For example, here we have a Java header that will
contain the HTTP method we want to invoke. The
filter is going to see if the request contains that
header. If it does, it would take the value of that
header and change the Java method thats going to be
invoked and applied to the resource method.
@Provider
class HttpMethod implements
ContainerRequestFilter
{
public void
filter(ContainerRequestContext ctx) {
if (ctx.getHeaders().
containsKey(HTTP-METHOD) {
ctx.setMethod(
ctx.getHeaders().getFirst(HTTP_
METHOD));
}
} }
Contents
Page 35
@Provider
@PostMatch
class Auth implements
ContainerRequestFilter
{
public void
filter(ContainerRequestContext ctx) {
Contents
Page 36