Upgrade to Pro — share decks privately, control downloads, hide ads and more …

REST for Web Developers

REST for Web Developers

DrupalCon Portland session on REST, what it should look like, how to use it, and how to make the best of it in your own applications

D33d8bdd9096c80b8d1acca8d28410b5?s=128

Lorna Mitchell

May 22, 2013
Tweet

More Decks by Lorna Mitchell

Other Decks in Technology

Transcript

  1. None
  2. REST for Web Developers Lorna Mitchell, DrupalCon Portland

  3. REST is About Data REpresentational State Transfer • Resources •

    Collections
  4. URLs are Pretty AND Hackable • http://api.example.com/articles • http://api.example.com/articles/2756 •

    http://api.example.com/articles/2756/comments • http://api.example.com/comments/101134
  5. Using REST With HTTP On the web, we use HTTP's

    features to implement REST • Verbs • Status codes • Headers
  6. Verbs Define Operations

  7. Verbs Give Us CRUD CRUD: Create, Read, Update, Delete Verb

    Collection Resource GET fetch resources fetch one resource POST create resource PUT [create]/update resource DELETE delete resource
  8. Status Codes Are Headlines

  9. Common Status Codes 200 OK 201 Created 204 No Content

    304 Not Modified 400 Bad Request 404 Not Found
  10. HTTP Headers for Metadata

  11. Request Headers > GET / HTTP/1.1 > User-Agent: curl/7.27.0 >

    Host: www.lornajane.net > Accept: */* (examples made by cURL http://curl.haxx.se/)
  12. Response Headers < HTTP/1.1 200 OK < Server: Apache/2.2.22 (Ubuntu)

    < X-Powered-By: PHP/5.4.6-1ubuntu1.1 < X-Pingback: http://www.lornajane.net/xmlrpc.php < Vary: Accept-Encoding < Content-Type: text/html; charset=UTF-8 < Transfer-Encoding: chunked < Date: Wed, 06 Feb 2013 14:02:25 GMT < X-Varnish: 179948671 179948601 < Age: 18 < Via: 1.1 varnish < Connection: keep-alive
  13. Negotiating Content Format Agree on a format using the Accept

    and Content-Type headers Header from Chrome: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 • Server works out what format to send back • Changing Accept header changes response format
  14. Parsing Accept Headers Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Format Weighting text/html 100% application/xhtml+xml

    100% application/xml 90% */* 80%
  15. Negotiating Content Format We also have: • Accept-Language • Accept-Encoding

    • Accept-Charset
  16. REST in Practice

  17. GET Request Headers GET https://api.github.com/repos/lornajane/demo/issues > GET /repos/lornajane/demo/issues HTTP/1.1 >

    User-Agent: curl/7.27.0 > Host: api.github.com > Accept: */* > Authorization: token 2d2d0a9b70d86b3b3ed9bac915b47a4d29fcf556f
  18. GET Response Headers GET https://api.github.com/repos/lornajane/demo/issues < HTTP/1.1 200 OK <

    Server: GitHub.com < Date: Sun, 17 Feb 2013 20:32:24 GMT < Content-Type: application/json; charset=utf-8 < Status: 200 OK < Vary: Accept, Authorization, Cookie < Cache-Control: private, max-age=60, s-maxage=60 < Last-Modified: Sun, 17 Feb 2013 20:19:19 GMT < ETag: "d30cd8e8cd3f86e71c40334ed104f345" < X-OAuth-Scopes: gist, repo < X-Accepted-OAuth-Scopes: repo, public_repo < X-GitHub-Media-Type: github.beta < Content-Length: 1953
  19. GET Response Body GET https://api.github.com/repos/lornajane/demo/issues { "url": "https://api.github.com/repos/lornajane/demo/issues/1", "comments_url": "https://api.github.com/repos/lornajane/demo/issues/1/c

    "html_url": "https://github.com/lornajane/demo/issues/1", "number": 1, "title": "It's Broken", "user": { ... }, "state": "open", "comments": 0, "created_at": "2013-02-17T20:19:19Z", "updated_at": "2013-02-17T20:19:19Z", "body": "This Thing Does Not Work" }
  20. Hypermedia are Hyperlinks for APIs • Clients can find related

    data • Relying on following links means URLs can change
  21. POST Request POST https://.../repos/lornajane/demo/issues/1/comments > POST /repos/lornajane/demo/issues/1/comments HTTP/1.1 > User-Agent:

    curl/7.27.0 > Host: api.github.com > Accept: */* > Content-Type: application/json > Authorization: token 2d2d0a9b70d86b3b3ed9bac915b47a4d29fcf556f > Content-Length: 37 > {"body": "some comment on the issue"}
  22. POST Response Header POST https://.../repos/lornajane/demo/issues/1/comments < HTTP/1.1 201 Created <

    Server: GitHub.com < Date: Sun, 17 Feb 2013 21:27:15 GMT < Content-Type: application/json; charset=utf-8 < Status: 201 Created < Location: https://.../repos/lornajane/demo/issues/comments/13697012 < Content-Length: 1400 < ETag: "f8661566f14902412153409d034d464b" < Cache-Control: max-age=0, private, must-revalidate
  23. POST Response Body POST https://.../repos/lornajane/demo/issues/1/comments { "url": "https://.../repos/lornajane/demo/issues/comments/13697012", "issue_url": "https://.../repos/lornajane/demo/issues/11093693",

    "id": 13697012, "user": { ... }, "created_at": "2013-02-17T21:27:15Z", "updated_at": "2013-02-17T21:27:15Z", "body": "some comment on the issue" }
  24. PUT Request PUT https://.../repos/lornajane/demo/issues/comments/13697012 > PUT /repos/lornajane/demo/issues/comments/13697012 HTTP/1.1 > User-Agent:

    curl/7.27.0 > Host: api.github.com > Accept: */* > Content-Type: application/json > Authorization: token 2d2d0a9b70d86b3b3ed9bac915b47a4d29fcf556f < Content-Length: 1403 {amended json data block}
  25. PUT Response PUT https://.../repos/lornajane/demo/issues/comments/13697012 < HTTP/1.1 200 OK < Server:

    GitHub.com < Date: Sun, 17 Feb 2013 22:09:14 GMT < Content-Type: application/json; charset=utf-8 < Connection: keep-alive < Status: 200 OK < X-OAuth-Scopes: gist, repo < X-Accepted-OAuth-Scopes: repo, public_repo < Content-Length: 1403 < ETag: "eccb456c8339572840f4c51dd8180fc7" < Cache-Control: max-age=0, private, must-revalidate
  26. ... except GitHub use PATCH

  27. PATCH Request PATCH https://.../repos/lornajane/demo/issues/comments/13697012 > PATCH /repos/lornajane/demo/issues/comments/13697012 HTTP/1.1 > User-Agent:

    curl/7.27.0 > Host: api.github.com > Accept: */* > Content-Type: application/json > Authorization: token 2d2d0a9b70d86b3b3ed9bac915b47a4d29fcf556f < Content-Length: 39 {"body":"some other, improved comment"}
  28. PATCH Response PATCH https://.../repos/lornajane/demo/issues/comments/13697012 < HTTP/1.1 200 OK < Server:

    GitHub.com < Date: Sun, 17 Feb 2013 22:09:14 GMT < Content-Type: application/json; charset=utf-8 < Connection: keep-alive < Status: 200 OK < X-OAuth-Scopes: gist, repo < X-Accepted-OAuth-Scopes: repo, public_repo < Content-Length: 1403 < ETag: "eccb456c8339572840f4c51dd8180fc7" < Cache-Control: max-age=0, private, must-revalidate
  29. DELETE Request DELETE https://.../repos/lornajane/demo/issues/comments/13697012 > DELETE /repos/lornajane/demo/issues/comments/13697012 HTTP/1.1 > User-Agent:

    curl/7.27.0 > Host: api.github.com > Accept: */* > Authorization: token 2d2d0a9b70d86b3b3ed9bac915b47a4d29fcf556f
  30. DELETE Response DELETE https://.../repos/lornajane/demo/issues/comments/13697012 < HTTP/1.1 204 No Content <

    Server: GitHub.com < Date: Sun, 17 Feb 2013 22:22:37 GMT < Connection: keep-alive < Status: 204 No Content < X-RateLimit-Limit: 5000 < X-RateLimit-Remaining: 4967 < X-OAuth-Scopes: gist, repo < X-Accepted-OAuth-Scopes: repo, public_repo < X-GitHub-Media-Type: github.beta < X-Content-Type-Options: nosniff
  31. HTTP Superpowers

  32. Authorization Headers • Options for auth: Basic/Digest, OAuth • Use

    headers, this information isn't part of a resource • Use tokens and expire tokens
  33. 30-Second OAuth Overview OAuth handles the relationship between: • a

    user • their data stored on a provder • a consumer wanting to access their data Use tokens for access, these can be revoked/expired
  34. Caching Headers Used exactly as we do on the web!

    • Expires to say how long the client should keep the content • ETag or Last-Modified to check if something has changed • These can be used to check that a PUT updates the expected resource version
  35. RESTful Services

  36. When to use REST • For data-driven APIs • Where

    REST is (or can be) understood
  37. Designing RESTful Services • Resources, verbs and headers • Consider

    the failure case • How much data to return? How little? • Split into subresources • Allow more/less verbose representations
  38. Any Questions?

  39. Thanks • feedback: http://portland2013.drupal.org/node/1358/ • me: @lornajane http://www.lornajane.net/

  40. None