Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

REST for Web Developers

Lorna Mitchell
February 18, 2013

REST for Web Developers

Fairly introductory session on REST for a PHP user group, but contains no PHP. Lots of HTTP theory and curl examples, using GitHub's API

Lorna Mitchell

February 18, 2013
Tweet

More Decks by Lorna Mitchell

Other Decks in Technology

Transcript

  1. REST and HTTP On the web, we use HTTP's features

    to implement REST • Verbs • Status codes • Headers
  2. Verbs Verbs give us CRUD Verb Collection Resource GET fetch

    resources fetch one resource POST create resource PUT [create]/update resource DELETE delete resource
  3. Common Status Codes 200 OK 201 Created 204 No Content

    304 Not Modified 400 Bad Request 404 Not Found
  4. 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/)
  5. 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
  6. Content Negotiation 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
  7. 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
  8. 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
  9. 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" }
  10. Hypermedia Hypermedia are hyperlinks for APIs • Clients can find

    related data • Relying on following links means URLs can change
  11. 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"}
  12. 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
  13. 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" }
  14. 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}
  15. 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
  16. 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"}
  17. 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
  18. 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
  19. 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
  20. Authorization Headers • Options for auth: Basic/Digest, OAuth • Use

    headers, this information isn't part of a resource • Use tokens and expire tokens
  21. 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
  22. 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
  23. 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