2. Warning before we start
‣ REST != MVC
‣ Do not think in controllers, id’s,
actions, models, views, plugins,
helpers etc...
‣ In fact, do not think about
implementation AT ALL!!
3. What is REST?
Roy Fielding said:
REST is a coordinated set of architectural constraints that attempts to minimize
latency and network communication while at the same time maximizing the
independence and scalability of component implementations. This is achieved by
placing constraints on connector semantics where other styles have focused on
component semantics. REST enables the caching and reuse of interactions,
dynamic substitutability of components, and processing of actions by
intermediaries, thereby meeting the needs of an Internet-scale distributed
hypermedia system.
4. What is REST?
‣ Cacheable
‣ Stateless
‣ Scalable
‣ Fault-tolerant
‣ Loosely coupled
‣ ADVANTAGES OF REST
5. What is REST?
‣ URL identifies a resource
‣ URLs have an hierarchy
‣ Methods perform operations on resources
‣ Operation must be implicit
‣ Hypermedia format to represent data
‣ Link relations to navigate
‣ THE PRINCIPLES OF REST
6. What is REST?
‣ Identification of resources
‣ Manipulation of resources
‣ Self-descriptive messages
‣ HATEOAS
‣ THE FOUR MAIN PRINCIPLES
7. What is REST?
‣ Identification of resources
‣ Manipulation of resources
‣ Self-descriptive messages
‣ HATEOAS
‣ THE FOUR MAIN PRINCIPLES
8. Identification of resources
‣ /index.php?action=getarticle&id=5
‣ /default/article/5/4/6/size
Cacheable? Scalable? Readable?
‣ You are doing it wrong... :(
9. Identification of resources
‣ /articles
We want all articles
‣ /articles/5/photos/4/comments/1
We want the first comment of the fourth photo for the fifth article
‣ /articles/5/photos/4/comments
We want all comments of the fourth photo for the fifth article
Cacheable! Scalable! Readable!
‣ Readable and maintainable!
10. Identification of resources
✗ /photos/order/size/limit/5
✗ /photos/limit/5/order/size
✓ /photos?order=size&limit=5
✓ /photos?limit=5&order=size
‣ FILTERING THROUGH A QUERY STRING, NOT THE URI
11. What is REST?
‣ Identification of resources
‣ Manipulation of resources
‣ Self-descriptive messages
‣ HATEOAS
‣ THE FOUR MAIN PRINCIPLES
13. Manipulation of resources
‣ Create = PUT
‣ Retrieve = GET
‣ Update = POST
‣ Delete = DELETE
‣ CRUD to HTTP verb mapping
14. Manipulation of resources
‣ Any client should be able to make
the request as many times as
necessary.
‣ GET, OPTIONS, HEAD
‣ SAFE METHODS
15. Manipulation of resources
‣ Garantuees that the client can
repeat the request when it’s not
certain.
‣ $x++ vs $x=4
‣ ALL METHODS EXCEPT “POST”
‣ IDEMPOTENT METHODS
16. What is REST?
‣ Identification of resources
‣ Manipulation of resources
‣ Self-descriptive messages
‣ HATEOAS
‣ THE FOUR MAIN PRINCIPLES
17. Self-descriptive messages
‣ Stateless!
‣ All information for processing is available:
‣ How? (method + content-type)
‣ What? (URI)
‣ When? (preconditions)
‣ Who? (authentication)
23. What is REST?
‣ Identification of resources
‣ Manipulation of resources
‣ Self-descriptive messages
‣ HATEOAS
‣ THE FOUR MAIN PRINCIPLES
24. HATEOAS
HATEOAS
=
Hypermedia As The Engine Of Application State
25. HATEOAS
This is the hardest and
of course, most important part of REST
26. HATEOAS
‣ Use links to allow clients to discover
locations and operations.
‣ Link relations are used to express
options.
‣ Clients do not need to know URLs.
‣ This controls the state.
27. State inside your REST API
Fetch
Select Confirm Pay
E-Ticket
‣ “Flight booking API”
28. State inside your REST API
POST /search?order=price&limit=5 HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version: 1.0
<search>
<destination>LPA</destination>
<date>24-may-2011</date>
<type>firstclass</type>
</search>
‣ Search for specified flights
29. State inside your REST API
HTTP/1.1 200 OK
Content-type: application/vnd.enrise.nl+xml ; version: 1.0
<flights xmlns=...>
<flight>
<flightno>KL1234</flightno>
<time>4:24</time>
<link method=”get” rel=”details” action=”/flight/15263” type=”text/xml”>
<link method=”post” rel=”confirm” action=”/confirm/flight/15263” type=”text/xml”>
</flight>
<flight>
<flightno>HV123</flightno>
<time>3:54</time>
<link method=”get” rel=”details” action=”/flight/523525” type=”text/xml”>
<link method=”post” rel=”confirm” action=”/confirm/flight/523525” type=”text/xml”>
</flight>
</flights>
‣ Returns a collection of flights
30. State inside your REST API
POST /confirm/flight/15263 HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version: 1.0
<flight>
<seat>2A</seat>
<meal>vegetarian</meal>
</flight>
HTTP/1.1 401 Authentication required
‣ Confirm a specific flight
31. State inside your REST API
POST /confirm/flight/15263 HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version: 1.0
Authorization: OAuth ......
<flight>
<seat>2A</seat>
<meal>vegetarian</meal>
</flight>
HTTP/1.1 200 OK
Location: /booking/1616163
<booking>
<link rel=”details” href=”/booking/1616163” method=”get” type=”application/xml”>
<link rel=”payment” href=”/payment/booking/1616163” type=”application/xml”>
<link rel=”cancel” href=”/booking/1616163” method=”delete” type=”application/xml”>
</booking>
‣ Confirm a specific flight, with more info
32. State inside your REST API
OPTIONS /booking/1616163 HTTP/1.1
Host: www.enrise.com
Authorization: OAuth ......
HTTP/1.1 200 OK
Allow: GET, DELETE, PUT
‣ What can we do with our booking?
33. State inside your REST API
DELETE /booking/1616163 HTTP/1.1
Host: www.enrise.com
Authorization: OAuth ......
HTTP/1.1 204 No content
‣ Cancel our booking!
34. State inside your REST API
GET /booking/1616163 HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version: 1.0
Authorization: OAuth...
HTTP/1.1 200 OK
<booking>
<flight>
<flightno>KL1234</flightno>
<time>4:24</time>
<link rel=”details” method=”get” href=”/flight/15263”>
</flight>
<payment>
<status>Not paid</status>
<link rel=”details” method=”get” href=”/payment/booking/1616163”>
<link rel=”pay” method=”post” href=”/payment/booking/1616163”>
</payment>
</booking>
‣ Still need to pay for the flight
35. State inside your REST API
PUT /payment/booking/1616163 HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version: 1.0
Authorization: OAuth ......
<payment>
<cardno>4111-1111-1111-1111</cardno>
<expires>04/13</expires>
<name>Joshua Thijssen</name>
<amount currency=”eur”>414.00</amount>
</payment>
HTTP/1.1 201 Created
Location: /payment/booking/1616163
‣ Pay through another resource
36. State inside your REST API
OPTIONS /booking/1616163 HTTP/1.1
Host: www.enrise.com
Authorization: OAuth ......
HTTP/1.1 200 OK
Allow: GET
‣ Can’t delete our booking since it’s paid
37. State inside your REST API
GET /booking/1616163 HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version: 1.0
Authorization: OAuth...
HTTP/1.1 200 OK
<booking>
<flight>
<flightno>KL1234</flightno>
<time>4:24</time>
<link rel=”details” method=”get” href=”/flight/15263”>
</flight>
<payment>
<status>Paid in full</status>
<link rel=”details” method=”get” href=”/payment/booking/1616163”>
</payment>
<link rel=”eticket” method=”get” href=”/eticket/12415156261616”>
</booking>
‣ We can fetch our eticket now
38. (Common) pitfalls of REST design
‣ Versioning
‣ Methods in uri
‣ One uri per resource
‣ Controller resources
& non-CRUD
39. (Common) pitfalls of REST design
‣ Versioning
‣ Methods in uri
‣ One uri per resource
‣ Controller resources & Non-CRUD
40. (Common) pitfalls of REST design
‣ /api/v1.1/article/1234/photos
‣ /api/v1.2/article/1234/photos
‣ Different resources?
‣ Versioning
41. (Common) pitfalls of REST design
GET /api/article/1234/photos HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version = 1.0
GET /api/article/1234/photos HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+json ; version = 1.1
GET /api/article/1234/photos HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+json ; version = 5.0.4a
‣ Versioning
42. (Common) pitfalls of REST design
‣ Versioning
‣ Methods in uri
‣ One uri per resource
‣ Controller resources & Non-CRUD
43. (Common) pitfalls of REST design
‣ /api/get/articles/1234/photos
‣ /api/articles/new
‣ /api/articles/list
‣ Methods in URL
44. (Common) pitfalls of REST design
‣ Versioning
‣ Methods in uri
‣ One uri per resource
‣ Controller resources & Non-CRUD
45. (Common) pitfalls of REST design
‣ /api/article/1234
‣ /api/article/red+teddybear
‣ Different resources
‣ One URI per resource
46. (Common) pitfalls of REST design
GET /api/article/red+teddybear HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version = 1.0
HTTP/1.1 303 See Other
Location: /api/article/1234
‣ One URI per resource
47. (Common) pitfalls of REST design
‣ Versioning
‣ Methods in uri
‣ One uri per resource
‣ Controller resources & Non-CRUD
48. (Common) pitfalls of REST design
‣ Outside the CRUD?
‣ Multiple operations simultaneously?
‣ Controller resources & non-crud
50. (Common) pitfalls of REST design
POST /user/jthijssen/address_merge HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version = 1.0
Content-type: text/csv;charset=UTF-8
John Doe, 1 Main Street, Seattle, WA
Jane Doe, 100 North Street, Los Angeles, CA
HTTP/1.1 303 See Other
Location: /user/jthijssen/addressbook
‣ Controller resources & non-crud
54. HTTP Status codes
‣ 200 OK
Resource returned
‣ 201 Created
Resource created
‣ 204 No content
Resource deleted
‣ IMPORTANT 2xx CODES
55. HTTP Status codes
‣ 304 Not modified
Resource wasn’t changed
‣ IMPORTANT 3xx CODES
56. HTTP Status codes
‣ 400 Bad request
Incorrect payload
‣ 401 Unauthorized
Not authorized to operate
‣ 403 Forbidden
Not authorized to operate
‣ 404 Not found
Resource was not found
‣ IMPORTANT 4xx CODES
57. HTTP Status codes
‣ 405 Method not allowed
Method incorrect
‣ 406 Not acceptable
Cannot return in correct format
‣ 412 Precondition failed
“ETag mismatch”
‣ IMPORTANT 4xx CODES
58. HTTP Status codes
‣ 500 Internal server error
“Something” happened
‣ 501 Not implemented
Method is not implemented
‣ IMPORTANT 5xx CODES
59. HTTP Status codes
‣ 501 Not implemented vs
405 Method not allowed
‣ 409 Conflict vs
412 Precondition failed
‣ de·bat·a·ble/diˈbātəbəl/Adjective
61. ETags & Optimistic locking
GET /blogpost/12345 HTTP/1.1
Host: www.enrise.com
If-None-Match: abcd-1234
HTTP/1.1 304 Not modified
Blogpost is cached and can be used!
62. ETags & Optimistic locking
POST /blogpost/12345 HTTP/1.1
Host: www.enrise.com
If-Match: abcd-1234
<xml>
<author>Sjors de Valk</author>
</xml>
HTTP/1.1 412 Precondition failed
Blogpost is already modified by “someone”
64. REST examples
PUT /articles HTTP/1.1
Host: www.enrise.com
Content-type: application/vnd.enrise.nl+xml ; version = 1.0
<article xmlns=”http://www.enrise.com/article”>
<name>Teddybear</name>
<color>red</color>
<stock>15</stock>
<price currency=”eur”>15,95</price>
<price currency=”usd”>19,95</price>
</article>
HTTP/1.1 201 Created
Location: /articles/1234
‣ Creating a resource
65. REST examples
GET /articles HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version = 1.0
HTTP/1.1 200 OK
Content-length: 12345
Content-type: application/vnd.enrise.nl+xml
Date: sun, 01 Nov 2010 12:34:56 GMT
<articles xmlns=”http://www.enrise.com/article”>
<article>
<name>Teddybear</name>
<link method=”get” rel=”article” href=”/articles/1234”>
</article>
<article>
<name>Skippyball</name>
<link method=”get” rel=”article” href=”/articles/1121”>
</article>
</articles>
‣ Getting a resource collection
66. REST examples
GET /articles/1234 HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version = 1.0
HTTP/1.1 200 OK
Content-length: 12345
Content-type: application/vnd.enrise.nl+xml
Date: sun, 01 Nov 2010 12:34:56 GMT
<article xmlns=”http://www.enrise.com/article”>
<name>Teddybear</name>
...
</article>
HTTP/1.1 404 Not found
Content-length: 0
Date: sun, 01 Nov 2010 12:34:56 GMT
‣ Getting a resource
67. REST examples
DELETE /articles/1234 HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version = 1.0
HTTP/1.1 204 No content
Content-length: 0
Date: sun, 01 Nov 2010 12:34:56 GMT
‣ Delete a resource
68. REST examples
POST /articles/1234 HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version = 1.0 Idempotent
If-Match: 23709-12135125
<article xmlns=”http://www.enrise.com/article>
<name>Teddybear</name>
<color>red</color>
<stock>30</stock>
<price currency=”eur”>15,95</price>
<price currency=”usd”>19,95</price>
</article>
HTTP/1.1 200 OK
Content-length: 0
Date: sun, 01 Nov 2010 12:34:56 GMT
HTTP/1.1 412 Precondition failed
Content-length: 0
Date: sun, 01 Nov 2010 12:34:56 GMT
‣ Updating a resource
69. (Common) pitfalls of REST design
POST /user/jthijssen/address_merge HTTP/1.1
Host: www.enrise.com
Accept: application/vnd.enrise.nl+xml ; version = 1.0
Content-type: text/csv;charset=UTF-8
John Doe, 1 Main Street, Seattle, WA
Jane Doe, 100 North Street, Los Angeles, CA
HTTP/1.1 303 See Other
Location: /user/jthijssen/addressbook
‣ Controller resources