2. Material in this presentation is based on:
– “A Brief Introduction to REST”, Stefan Tilkov
– “REST Anti-Patterns”, Stefan Tilkov
– “Addressing Doubts about REST”, Stefan Tilkov
– “A Guide to Designing and Building RESTful Web Services
with WCF 3.5”, Aaron Skonnard
Disclaimer
4. • REpresentational State Transfer
– Roy Fielding’s PhD thesis (2000)
• Two main ideas:
1. Everything is a resource
2. Each resource has a Uniform interface
REST
6. 1. Give every “thing” an ID
2. Use standard methods
3. Provide multiple representations
4. Communicate statelessly
5. Link things together
Key principles
7. • Even non-usual things
– e.g., process, process step
• Individual itens …
– http://example.com/customers/1234
– http://example.com/orders/2007/10/776654
– http://example.com/products/4554
– http://example.com/processes/salary-increase-234
• … and collections
– http://example.com/orders/2007/11
– http://example.com/products?color=green
1) Give every “thing” an ID
URIs are opaque!
8. • Uniform interface
– Common set of methods
• Well defined semantics
– E.g., Standard HTTP verbs and
response codes
2) Use standard methods
9. Method Description Safe Idempotent
GET Requests a specific representation of a
resource
Yes Yes
PUT Create or update a resource with the
supplied representation
No Yes
DELETE Deletes the specified resource No Yes
POST Submits data to be processed by the
identified resource
No No
HEAD Similar to GET but only retrieves headers
and not the body
Yes Yes
OPTIONS Returns the methods supported by the
identified resource
Yes Yes
Uniform interface
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
10. Method Collection URI, such as
http://expl.com/customers/
Element URI, such as
http://expl.com/customers/142
GET
List the URIs and perhaps other
details of the collection's members.
Retrieve a representation of the
addressed member of the
collection, expressed in an
appropriate Internet media type.
PUT
Replace the entire collection with
another collection.
Update the addressed member of
the collection, or if it doesn't
exist, create it.
POST
Create a new entry in the collection.
The new entry's URL is assigned
automatically and is usually
returned by the operation.
Treat the addressed member as a
collection in its own right
and create a new entry in it.
DELETE Delete the entire collection.
Delete the addressed member of
the collection.
Uniform interface
Source: Richardson, Leonard; Ruby, Sam (2007), RESTful Web Services, O'Reilly
12. Status Range Description Examples
100 Informational 100 Continue
200 Successful 200 OK
201 Created
202 Accepted
300 Redirection 301 Moved Permanently
304 Not Modified
400 Client error 400 Bad Request
401 Unauthorized
402 Payment Required
404 Not Found
405 Method Not Allowed
409 Conflict
500 Server error 500 Internal Server Error
501 Not Implemented
Response codes
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
14. • Use HTTP content negotiation
– Accept: header
– Use standard MIME formats as much as possible
• Example #1:
GET /customers/1234 HTTP/1.1
Host: example.com
Accept: application/vnd.mycompany.customer+xml
• Example #2:
GET /customers/1234 HTTP/1.1
Host: example.com
Accept: text/x-vcard
3) Multiple representations
16. $> [Client:] Show me your products
[Server:] Here's a list of all the products
$> I'd like to buy 1 of http://ex.org/product/X, I am
"John"/"Password“
I've added 1 of http://ex.org/product/X to
http://ex.org/users/john/basket
$> I'd like to buy 1 of http://ex.org/product/Y, I am
"John"/"Password“
I've added 1 of http://ex.org/product/Y to
http://ex.org/users/john/basket
$> I don't want http://ex.org/product/X, remove it, I am
"John"/"Password“
I've removed http://ex.org/product/X from
http://ex.org/users/john/basket
$> Okay I'm done, username/password is "John"/"Password“
Here is the total cost of the items in
http://ex.org/users/john/basket
4) Communicate statelessly
http://www.peej.co.uk/articles/no-sessions.html
20. • The resource provides info about
possible “actions” to follow
• Well know semantics
• Atom:link rel
– See IANA registry
http://www.iana.org/assignments/link
-relations/link-relations.xml
Hypermedia controls
21. • Place an order
PUT /order HTTP/1.1
Host: http://central-cafe.com
Content: application/xml
<order> <drink>latte</drink> </order>
• Response
201 Created
Location: http://central-cafe.com/orders/1234
Content: application/xml
<order> <drink>latte</drink> <cost>3.0</cost>
<link rel=“http://cafe.org/cancel”
uri=“http://central-cafe.com/order/1234”/>
<link rel=“http://cafe.org/payment”
uri=“http://central-cafe.com/payment/order/1234”/>
</order>
HATEOAS example
Allowed actions
23. • OPTIONS will return currently
acceptable actions on a resource
• Request
OPTIONS /order/1234 HTTP 1.1
Host: cafe.org
• Response
200 OK
Allow: GET, PUT
Look before you leap
PUT is allowed; e.g., order
is not yet processed
24. • Leverage HTTP authentication
• For actions that need authentication
– The Server returns
• 401 Unauthorized
• WWW-Authenticate header
– The Client uses Authorization header
Authentication
25. • HTTP cache is powerfull and
complex
– … and time-proven
• Performance
• Scalability
Cache
29. • Obtain list of public bookmarks
(filtered by user and/or subject)
• Obtain list of a user’s private
bookmarks (filtered by subject)
• Create a user account
• Add a public/private bookmark
Bookmark management
30. Operation Description
createUserAccount Creates a new user account
getUserAccount Retrieves user account details for the authenticated user
updateUserAccount Updates user account details for the authenticated user
deleteUserAccount Deletes the authenticated user’s account
getUserProfile Retrieves a specific user’s public profile information
createBookmark Creates a new bookmark for the authenticated user
updateBookmark Updates an existing bookmark for the authenticated user
deleteBookmark Deletes one of the authenticated user’s bookmarks
getBookmark Retrieves a specific bookmark (anyone can retrieve a public
bookmark; only authenticated users can retrieve a private
bookmark)
getUserBookmarks Retrieves the user’s private bookmarks, allows filtering by tags
getUserPublicBookmarks Retrieves the user’s public bookmarks, allows filtering by tags
getPublicBookmarks Retrieves all public bookmarks, allows filtering by tags
Traditional RPC-style API
31. RPC API
• Verb/Action
• e.g., getBookmark
• e.g., createUser
REST API
• Resource/Noum
• e.g., Bookmark
• e.g., User
From verbs to nouns
32. • An individual user account
• A specific user’s public profile
• An individual bookmark
• A user’s collection of private bookmarks
• A user’s collection of public bookmarks
• The collection of all public bookmarks
Resources in the
sample service
33. • Create URI templates for accessing
the resources
– Start with service’s base URI
– E.g., http://bmark.org/
• May use path components to
dissambiguate
• May use query string for further
semantics
Designing the URI
34. • http://bmark.org/public
• Filter by subject
– http://bmark.org/public?tag={subject}
• Filter by user
– http://bmark.org/public/{username}
• Combining filters
– http://bmark.org/public/{username} ?tag={subject}
Public bookmarks
35. • Specific user account
– http://bookmark.org/users/{username}
• Specific user profile
– http://bookmark.org/users/{username}/profile
User accounts
37. Method URI Template Equivalent RPC operation
PUT users/{username} createUserAccount
GET users/{username} getUserAccount
PUT users/{username} updateUserAccount
DELETE users/{username} deleteUserAccount
GET users/{username}/profile getUserProfile
POST users/{username}/bookmarks createBookmark
PUT users/{username}/bookmarks/{id} updateBookmark
DELETE users/{username}/bookmarks/{id} deleteBookmark
GET users/{username}/bookmarks/{id} getBookmark
GET users/{username}/bookmarks?tag={tag} getUserBookmarks
GET {username}?tag={tag} getUserPublicBookmarks
GET ?tag={tag} getPublicBookmarks
REST API
38. • Resources
• URI
• Verb
• Resource representation
• Response codes
REST API
39. • Request
PUT /users/skonard HTTP/1.1
Host: bmark.org
<User>
<Email>aaron@pluralsight.com</Email>
<Name>Aaron Skonnard</Name>
</User>
• Response
201 Created
Location: http://bmark.org/users/skonard
Create user account
40. • Request
GET /users/skonard HTTP/1.1
Host: bmark.org
Accept: application/vnd.contoso.user+xml
• Response
200 Ok
<User>
<Email>aaron@pluralsight.com</Email>
<Name>Aaron Skonnard</Name>
<Bookmarks
ref=‘http://bmark.org/users/skonard/bookmarks‘/>
<Id>http://bmark.org/users/skonard</Id>
</User>
Get user account
Provide links to
other resources
41. • Request
POST /users/skonard/bookmarks HTTP/1.1
Host: bmark.org
<Bookmark>
<Public>true</Public>
<Tags>REST,WCF</Tags>
<Title>Aaron’s Blog</Title>
<Url>http://pluralsight.com/aaron</Url>
</Bookmark>
• Response
201 Created
Location: http://bmark.org/users/skonard/bookmarks/13
Add a bookmark
49. REST ≠ CRUD
2) Calculation results are resources
• One way
GET /sum?a=2&b=3
• A more RESTful way
POST /sums
<a>2</a><b>3</b>
201 Created
Location: http://expl.com/sums/1A0BD3FT98H6
<number>5</number>
Remember GET
demands idempotence
Result’s URI
50. • The Uniform Interface is the contract
• XSD, DTDs, etc. are still available
• Resources may provide a XHTML
representation with documentation
and data
• WADL
No formal contract
52. 1. POST the request
2. Receive a 202 Accepted or 201
Created with result URI
3. Pull the URI to GET result
How to handle assync
requests?
53. 1. POST the request providing a callback
URL
2. Receive a 202 Accepted
3. “Wait” for server to POST result’s URI
(and result representation) to the
callback URL
4. Optionaly GET result
How to handle assync
requests?
54. 1. Treat transaction as a resource
2. Change the transaction resource
itself (possible multiple POST steps)
3. PUT to transaction to commit
changes
How to handle
transactions?
55. • Most Firewalls only allow GET/POST
– Use X-HTTP-Method-Override header
POST /users/skonnard/bookmarks/123 HTTP/1.1
X-HTTP-Method-Override: DELETE
How to circunvent the
web today?
59. • Some web frameworks disable cache
by default
– Cache-control: no-cache
Ignoring caching
60. • There is more to the web than 200 Ok
• HTTP rich set of response codes
– Semantically richer conversation
– Example:
201 Created
Location: http://expl.com/customers/1234
Ignoring return codes
66. Added value to the web
SOAP/WS-*
• 1 URL for each
endpoint
• 1 method: POST
• Closed application-
specific vocabulary
– E.g., createCustomer
REST
• Millions of URLs
– One for each resource
• 6 methods per
resource
• Standard HTTP
vocabulary
– Open to every HTTP-
compliant client
69. • “Architectural Styles and the Design of Network-based Software
Architectures”, PhD Thesis (2000), Roy Thomas Fielding.
http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
• REST in Practice: Hypermedia and Systems Architecture (2010) Jim Webber,
Savas Parastatidis, Ian Robinson. O’Reilly Media.
• Richardson Maturity Model, Martin fowler.
http://martinfowler.com/articles/richardsonMaturityModel.html
• “A Brief Introduction to REST”, Stefan Tilkov, Dec 10, 2007.
http://www.infoq.com/articles/rest-introduction
• HTTP 1.1 methods definition. http://www.w3.org/Protocols/rfc2616/rfc2616-
sec9.html#sec9
• HTTP 1.1 Status code definitions.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
• “A Guide to Designing and Building RESTful Web Services with WCF 3.5”, Aaron
Skonnard, Pluralsight (October 2008). http://msdn.microsoft.com/en-
us/library/dd203052.aspx
• “Addressing Doubts about REST”, Stefan Tilkov, Mar 13, 2008.
http://www.infoq.com/articles/tilkov-rest-doubts
• “REST Anti-Patterns”, Stefan Tilkov, Jul 02, 2008.
http://www.infoq.com/articles/rest-anti-patterns
• “How to get a cup of coffe”, Jim Webber, Savas Parastatidis & Ian Robinson.
Oct 02, 2008. http://www.infoq.com/articles/webber-rest-workflow
Notas del editor
One “incarnation” of the REST style is HTTP (and a set of related set of standards, such as URIs), or slightly more abstractly: the Web’s architecture itself. To continue the example from above, HTTP “instantiates” the REST uniform interface with a particular one, consisting of the HTTP verbs.
From: http://www.infoq.com/articles/rest-introductionREST is a set of principles that define how Web standards, such as HTTP and URIs, are supposed to be used (which often differs quite a bit from what many people actually do). The promise is that if you adhere to REST principles while designing your application, you will end up with a system that exploits the Web’s architecture to your benefit
Use URIs to identify everything that merits being identifiable, specifically, all of the “high-level” resources that your application provides, whether they represent individual items, collections of items, virtual and physical objects, or computation results.
Use URIs to identify everything that merits being identifiable, specifically, all of the “high-level” resources that your application provides, whether they represent individual items, collections of items, virtual and physical objects, or computation results.
From:http://www.infoq.com/articles/rest-introductionThere was an implicit assumption in the discussion of the first two principles: that the consuming application can actually do something meaningful with the URIs. […] how does your [application] know what to do with the URI?It knows what to do with it because every resource supports the same interface, the same set of methods (or operations, if you prefer). Why is this important? Essentially, it makes your application part of the Web — its contribution to what has turned the Web into the most successful application of the Internet is proportional to the number of resources it adds to it. In a RESTful approach, an application might add a few million customer URIs to the Web; if it’s designed the same way applications have been designed in CORBA times, its contribution usually is a single “endpoint” — comparable to a very small door that provides entry to a universe of resource only for those who have the key.The uniform interface also enables every component that understands the HTTP application protocol to interact with your application. Examples of components that benefit from this are generic clients such as curl and wget, proxies, caches, HTTP servers, gateways, even Google/Yahoo!/MSN, and many more.To summarize: For clients to be able to interact with your resources, they should implement the default application protocol (HTTP) correctly, i.e. make use of the standard methods GET, PUT, POST, DELETE.
Safe – no side effectsIdempotent – repeatable with no duplicate changeFrom: http://www.infoq.com/articles/rest-introductionAlthough HTTP fully supports CRUD, HTML 4 only supports issuing GET and POST requests through its various elements. This limitation has held Web applications back from making full use of HTTP, and to work around it, most applications overload POST to take care of everything but resource retrieval. HTML 5, which is currently under development, plans to fix this by adding new support for PUT and DELETE.
From: http://www.infoq.com/articles/tilkov-rest-doubtsboth POST and PUT can be used to create new resources: they differ in that with PUT, it’s the client that determines the resource’s URI (which is then updated or created), whereas a POST is issued to a “collection” or “factory” resource and it’s the server’s task to assign a URI.
Allows for different types of clientsShould use HTTP content negotiationFormat encoding in the URI however allows it to be bookmarkedJSON:The XMLHttpRequest API has been built for requesting XML via HTTP this is useful because XML is the most popular data format all requested data has to be processed by using XML access methods in JavaScriptJavaScript does not have XML as its internal data model the XML received via XMLHttpRequest has to be parsed into a DOM tree DOM access in JavaScript is inconvenient for complex operationsJavaScript Object Notation (JSON) encodes data as JavaScript objects more efficient for the consumer if the consumer is written in JavaScript this turns the generally usable XML service into a JavaScript-oriented service for large-scale applications, it might make sense to provide XML and JSON this can be negotiated with HTTP content negotiation
From: http://www.infoq.com/articles/rest-introductionThis illustrates why ideally, the representations of a resource should be in standard formats — if a client “knows” both the HTTP application protocol and a set of data formats,it can interact with any RESTful HTTP application in the world in a very meaningful way.Summary: Provide multiple representations of resources for different needs.
From: http://www.infoq.com/articles/rest-introductionREST 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 for any of the clients it communicates with beyond a single request. The most obvious reason for this is scalability
Client may follow linkInternal and/or external scope of the applicationFrom: http://www.infoq.com/articles/rest-introductionThe beauty of the link approach using URIs is that the links can point to resources that are provided by a different application, a different server, or even a different company on another continent — because the naming scheme is a global standard, all of the resources that make up the Web can be linked to each otherUse links to refer to identifiable things (resources) wherever possible. Hyperlinking is what makes the Web the Web.
Fromwikipedia: http://en.wikipedia.org/wiki/HATEOASThis principle is the key differentiator between a REST and most other forms of client server system.Rather than the actions and interfaces a client may use being defined elsewhere, such as in a WSDL file or predefined in the client code, the principle is that the hypermedia in eachserver response will contain links that correspond to all the actions that the client can currently perform. Therefore, dependent on the current application state, every server response describes the new actions that are available. The server can change the range of allowable responses in a dynamic way, and a client should adapt its behavior to these changes.A client of a RESTful application need only know a single fixed URL to access it. All future actions should be discoverable dynamically from hypermedia links included in the representations of the resources that are returned from that URL. Standardized media types are also expected to be understood by any client that might use a RESTful API. Application state transitions are driven by a combination of the known processing rules for each media type, client selection from the server-provided choices in representations received, and the user's manipulation of those representations. Thus interactions are driven by hypermedia, rather than by any out-of-band information.[1]If necessary, the client’s knowledge of media types, resource communication mechanisms, and user interaction, may be improved on-the-fly by the transmission of code-on-demand from the server to the client as defined elsewhere in the REST architecture.[2]
From http://www.infoq.com/articles/webber-rest-workflow
UsersBookmarks (public and private)
We should define the set of resourcesThe URI for each resourcesThe methods (verbs) supported (implemented) by each resourceThe resource’s represnetation(s)The possible response messages for each verb
Usa-se o verbo PUTO cliente envia o URI do recurso e a sua represnetaçãoAlternativa:Usar POST /usersO servidor criava o URI do recurso
Provide hyperlinks between resources: hypermedia as the engine of application state
Should use HTTP content negotiationFormat encoding in the URI however allows it to be bookmarkedIt is also possible to use the “extension” as part of the URL, e.g, http://ex.org/users/skonard.xmlhttp://ex.org/users/skonard.json
From: The problem with using a custom XML vocabulary is you’ll have to provide metadata (like an XML Schema definition) and documentation for clients consuming your resources. If you can use a standard format, on the other hand, you will immediately have an audience that knows how to consume your service. There are two standard formats that are quite popular today: XHTML and Atom/AtomPub .
The set of acceptable actions may change dynamicaly based on the state of the resource.For instance, if the order is already being processed you may not be able to change it (i.e, to issue a PUT to that resource)
REST is good for CRUD but not “real” business logic
From: http://www.infoq.com/articles/tilkov-rest-doubtsNo 1:1 mapping between HTTP verbs and CRUD db operationsFirst of all, the HTTP verbs - GET, PUT, POST, and DELETE - do not have a 1:1 mapping to the CRUD database operations. For example, both POST and PUT can be used to create new resources: they differ in that with PUT, it’s the client that determines the resource’s URI (which is then updated or created), whereas a POST is issued to a “collection” or “factory” resource and it’s the server’s task to assign a URI.
From: http://www.infoq.com/articles/tilkov-rest-doubtsAny computation calc(a, b) that returns a result c can be transformed into a URI that identifies its result. At first, this seems like a gross misuse of RESTful HTTP — aren’t we supposed to use URIs to identify resources, not operations? Yes, but in fact this is what we do: http://example.com/sum?augend=2&addend=3 identifies a resource, namely the result of adding 2 and 3. And in this particular (obviously contrived) example, using a GET to retrieve the result might be a good idea — after all, this is cacheable, you can reference it, and computing it is probably safe and not very costly.Of course in many, if not most cases, using a GET to compute something might be the wrong approach. Remember that GET is supposed to be a “safe” operation, i.e. the client does not accept any obligations (such as paying you for your services) or assume any responsibility, when all it does is follow a link by issuing a GET. In many other cases, it’s therefore more reasonable to provide input data to the server so that it can create a new resource via POST. In its response, the server can indicate the URI of the result (and possibly issue a redirect to take you there). The result is then re-usable, can be bookmarked, can be cached when it’s retrieved … you can basically extend this model to any operation that yields a result — which is likely to be every one you can think of.
From: http://www.infoq.com/articles/webber-rest-workflowPolling is normally thought of as offering low scalability; the Web, however, supports an extremely scalable polling mechanism.We have two conflicting requirements here. We want [clients] to keep up-to-date by polling the feed often, but we don't want to increase the load on the service or unnecessarily increase network traffic. To avoid crushing our service under load, we'll use a reverse proxy just outside our service to cache and serve frequently accessed resource representations.For most resources – especially those that are accessed widely, like our Atom feed for drinks – it makes sense to cache them outside of their host services. This reduces server load and improves scalability.
From:many of today’s Web browsers and firewalls only allow GET and POST requests. Due to this limitation, many sites overload GET or POST to fake PUT and DELETE requests. This can be accomplished by specifying the real HTTP method in a custom HTTP header. A common HTTP header used for this purpose is the X-HTTP-Method-Override header, which you can use to overload POST with a DELETE operation as shown in this example:POST /bookmarkservice/skonnard/bookmarks/123 HTTP/1.1X-HTTP-Method-Override: DELETEUsing this technique is widely considered an acceptable practice for working around the limitations of today’s Web infrastructure because it allows you to keep your URI design free of RPCisms.
POST carries an entity body, not just a URI. A typical scenario uses a single URI to POST to, and varying messages to express differing intents.URIs do not represent resources but rather encode operations or represent single endpointHTTP verb semantics are not respectedURIs cannot (should not) be bookmarked and followedMay cause unexpected side effects
One of the greatest benefits of the web/RESTPerformanceScale (+/-)
Server side should return appropriate and meaningful return codes
From: http://www.infoq.com/articles/rest-anti-patternspeople [use] 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 REST’s core concepts: hypermedia asHypermedia, the concept of linking things together, is what makes the Web a web – a connected set of resources, where applications move from one state to the next by following links. the engine of application state.
From: http://www.infoq.com/articles/rest-anti-patternsHTTP’s notion of content negotiation allows a client to retrieve different representations of resources based on its needs. For example, a resource might have a representation in different formats such as XML, JSON, or YAML, for consumption by consumers implemented in Java, JavaScript, and Ruby respectively.
From: http://www.infoq.com/articles/rest-anti-patternsIdeally, a message – an HTTP request or HTTP response, including headers and the body – should contain enough information for any generic client, server or intermediary to be able to process it.For example, when your browser retrieves some protected resource’s 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 the startup of the PDF viewer registered on your system, and finally you can read the PDF on your screen. Any other user in the world could use his or her own infrastructure to perform the same request. If the server developer adds another content type, any of the server’s clients (or service’s 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, anything not being standardized by an official standards body breaks this constraint, and can be considered a case of this anti-pattern. In practice, you strive for following 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).
Closed vocabulary: only specifically designed clients can work with that serverOpen vocabulary: every app that understands HTTP can work with