What is Hypermedia API?

2c1ea30835c4bec1c6b66dff6bba807a?s=47 Marat
September 30, 2012

What is Hypermedia API?

Talk given on RubyShift 2012 in Kyiv September 29-30.

RoR did a great thing to make REST popular. Now it turns out that
original REST approach is not what we think REST is. But what it is
then? Hypermedia API is a new term which stands for original REST
approach. What is the difference between "REST" and Hypermedia API
(true REST)? What is Hypermedia? Why is it needed? These questions
are covered in my talk.

2c1ea30835c4bec1c6b66dff6bba807a?s=128

Marat

September 30, 2012
Tweet

Transcript

  1. What is Hypermedia API?

  2. client code <=> API code

  3. API: 1. namespace 2. its functions 3. their params

  4. Web API: 1. domain (https://graph.facebook.com/) 2. addresses (/users, /groups, etc)

    3. params for them (?access_token=...&...)
  5. The main API problem: Client-server coupling

  6. Change in domain, URL, params → clients brake

  7. None
  8. None
  9. WWW exists 20 years. Clients don't brake

  10. You can upgrade at any time.

  11. None
  12. Hypermedia API = Web API + Web experience

  13. Hypermedia API = 1 URL https://api.github.com/ https://api.twilio.com/2010-04-01

  14. Where are the URLs and params?

  15. MIME type description

  16. application/vnd.github-issue.text+json application/json application/vnd.tekpub.productions+json application/vnd.spire-io.session+json

  17. RFC2119: MUST, SHALL, REQUIRED SHOULD, RECOMMENDED MAY, OPTIONAL MUST NOT,

    SHALL NOT SHOULD NOT, NOT RECOMMENDED
  18. E.g.: Response representations MUST begin with <root> element as the

    first element
  19. Servers SHOULD return a response code of 204 if the

    HTTP DELETE request was successful.
  20. Document MAY contain a single filters object. Five properties: href(REQUIRED),

    rel (REQUIRED), name (OPTIONAL), prompt (OPTIONAL), and a data array (OPTIONAL)
  21. "filters":[ {"rel":"category", "href":"...", "prompt":"", "data":[ {"name":"category", "value":"Microsoft"}]}, {"rel":"category", "href":"...", "prompt":"",

    "data":[{"name":"category", "value":"Ruby"}]}]
  22. "filters":[ {"rel":"category", "href":"...", "prompt":"", "data":[ {"name":"category", "value":"Microsoft"}]}, {"rel":"category", "href":"...", "prompt":"",

    "data":[{"name":"category", "value":"Ruby"}]}]
  23. Rels are described in MIME

  24. Best MIME type is XHTML: it supports forms!

  25. None
  26. 3 whales: HTTP + MIME + HATEOAS

  27. HATEOAS: hypermedia as the engine of application state

  28. None
  29. <root> <id>q0</id> <link rel = "q1" uri = "..." />

    <link rel = "q2" uri = "..." /> </entry> <root> <id>q1</id> <link rel = "q0" uri = "..." /> <link rel = "q3" uri = "..." /> </entry>
  30. ticket: { assigned_to: someone, links: [ {rel: “unassign”, url: “...”},

    {rel: “close”, url: “...”} ] }
  31. ticket: { assigned_to: null, links: [ {rel: “assign”, url: “...”},

    {rel: “remove”, url: “...”} ] }
  32. *MIME types are registered in IANA w/ public access

  33. HTTP:

  34. HTTP verbs: GET HEAD POST PUT PATCH DELETE OPTIONS

  35. HTTP verbs: GET HEAD POST PUT PATCH DELETE OPTIONS

  36. Status codes: 100.upto(505).almost_each do |status_code| … end

  37. 100 Continue 201 Created 202 Accepted 206 Partial Content 303

    See Other 400 Bad Request 401 Unauthorized 404 Not Found 409 Conflict 412 Precondition Failed 417 Expectation Failed
  38. 100 Continue 201 Created 202 Accepted 206 Partial Content 303

    See Other 400 Bad Request 401 Unauthorized 404 Not Found 409 Conflict 412 Precondition Failed 417 Expectation Failed
  39. 100 Continue 201 Created 202 Accepted 206 Partial Content 303

    See Other 400 Bad Request 401 Unauthorized 404 Not Found 409 Conflict 412 Precondition Failed 417 Expectation Failed
  40. 100 Continue 201 Created 202 Accepted 206 Partial Content 303

    See Other 400 Bad Request 401 Unauthorized 404 Not Found 409 Conflict 412 Precondition Failed 417 Expectation Failed
  41. 100 Continue 201 Created 202 Accepted 206 Partial Content 303

    See Other 400 Bad Request 401 Unauthorized 404 Not Found 409 Conflict 412 Precondition Failed 417 Expectation Failed
  42. 100 Continue 201 Created 202 Accepted 206 Partial Content 303

    See Other 400 Bad Request 401 Unauthorized 404 Not Found 409 Conflict 412 Precondition Failed 417 Expectation Failed
  43. Request headers: OPTIONS /payment/order/1234 HTTP 1.1 Host: starbucks.example.com Response 200

    OK Allow: GET, PUT
  44. Request headers: PUT /order/1234 HTTP 1.1 Host: starbucks.example.com Expect: 100-Continue

    Response: 100 Continue
  45. Request: PUT /order/1234 HTTP 1.1 Host: starbucks.example.com {body} Response: 200

    OK {body}
  46. Request: PUT /order/1234 HTTP 1.1 Host: starbucks.example.com {body} Response: 409

    Conflict
  47. Request: PUT /order/1234 HTTP 1.1 Host: starbucks.example.com Expect: 100-Continue Response:

    417 Expectation Failed
  48. HTTP Headers: Accept/type Etag Cache Authorization Version If-Unmodified-Since If-Match

  49. HTTP Headers: Accept/type Etag Cache Authorization Version If-Unmodified-Since If-Match

  50. Media types (revisited): Accept: application/xml Accept: application/json

  51. GET https://api.github.com/gists/1 Accept: application/json 200 OK Content-Type: application/json; charset=utf-8 (response

    body)
  52. GET https://api.github.com/gists/1 Accept: application/xml 200 OK Content-Type: application/xml; charset=utf-8 (response

    body)
  53. GET https://api.github.com/gists/1 Accept: application/xml 406 Not Acceptable Content-Type: application/json {

    "message": "Must ACCEPT application/json: [\"application/xml\"]" }
  54. HTTP Headers: Accept/type Etag Cache Authorization Version If-Unmodified-Since If-Match

  55. GET https://api.github.com/gists/1 Accept: application/json 200 OK ETag: "2259b5bea67655550030acf98bad4184" {body} GET

    https://api.github.com/gists/1 Accept: application/json If-None-Match: "2259b5bea67655550030acf98bad4184" 304 Not Modified
  56. HTTP Headers: Accept/type Etag Cache Authorization Version If-Unmodified-Since If-Match

  57. Authentication: Basic HTTP Authentication (with SSL or Digesting)

  58. HTTP Headers: Accept/type Etag Cache Authorization Version If-Unmodified-Since If-Match

  59. Accept: application/vnd.example+json Accept: application/vnd.example+json;version=1.0 Accept: application/vnd.example-v2+json Start point URI remains:

    http://api.example.com
  60. HTTP Headers: Accept/type Etag Cache Authorization Version If-Unmodified-Since If-Match

  61. Richardson Maturity Model

  62. 1. “The Swamp of POX.” You’re using HTTP to make

    RPC calls. HTTP is only really used as a tunnel. http://api.example.com?post_id=1&user_id=2
  63. 2. Resources. Rather than making every call to a service

    endpoint, you have multiple endpoints. http://api.example.com/posts/edit/1 http://api.example.com/users/show/1
  64. 3. HTTP Verbs. GET http://api.example.com/posts/1 PUT http://api.example.com/posts/1 PATCH http://api.example.com/posts/1 POST

    http://api.example.com/posts DELETE http://api.example.com/posts/1
  65. 4. Hypermedia Controls. HATEOAS. You’re 100% REST compliant. GET https://api.example.com/

    HTTP 1.1 Accept: application/vnd.example-v1+json If-Match: “...” Authentication: ... 200 OK {root: {entries: ...}, links: [{rel: “edit”, url: “...”}, {…}]}
  66. No client-server coupling 1 stable URL No dependencies on URLs

    and params
  67. Client is valid forever (ideally)

  68. Just as web browsers work

  69. Wish you all to be at level 4 (if you

    want)
  70. Thank you! @maratkamen marat@svitla.com

  71. Sources:

  72. “Architectural Styles and the Design of Network-based Software Architectures” http://www.ics.uci.edu/~fielding/pubs/di

    ssertation/top.htm
  73. http://blog.steveklabnik.com/posts/2012-02- 27-hypermedia-api-reading-list

  74. “Building Hypermedia APIs with HTML5 and Node” Mike Amundsen

  75. http://timelessrepo.com/haters-gonna-hateoas

  76. REST is over! http://blog.steveklabnik.com/posts/2012-02- 23-rest-is-over

  77. Questions!