Hypermedia API
-
Upload
svitla-systems-inc -
Category
News & Politics
-
view
3.204 -
download
3
description
Transcript of Hypermedia API
What is Hypermedia API?
client code <=> API code
API:
1. namespace
2. its functions
3. their params
Web API:
1. domain (https://graph.facebook.com/)
2. addresses (/users, /groups, etc)
3. params for them (?access_token=...&...)
The main API problem:
Client-server coupling
Change in domain, URL, params →clients brake
WWW exists 20 years.
Clients don't brake
You can upgrade at any time.
Hypermedia API =Web API +
Web experience
Hypermedia API =1 URL
https://api.github.com/https://api.twilio.com/2010-04-01
Where are the URLs and params?
MIME type description
application/vnd.github-issue.text+json
application/json
application/vnd.tekpub.productions+json
application/vnd.spire-io.session+json
RFC2119:
MUST, SHALL, REQUIRED
SHOULD, RECOMMENDED
MAY, OPTIONAL
MUST NOT, SHALL NOT
SHOULD NOT, NOT RECOMMENDED
E.g.:
Response representations MUST begin with <root> element as the first element
Servers SHOULD return a response code of 204 if the HTTP DELETE request was
successful.
Document MAY contain a single filters object.
Five properties: href(REQUIRED), rel (REQUIRED), name (OPTIONAL), prompt
(OPTIONAL), and a data array (OPTIONAL)
"filters":[
{"rel":"category", "href":"...", "prompt":"",
"data":[
{"name":"category",
"value":"Microsoft"}]},
{"rel":"category", "href":"...", "prompt":"",
"data":[{"name":"category",
"value":"Ruby"}]}]
"filters":[
{"rel":"category", "href":"...", "prompt":"",
"data":[
{"name":"category",
"value":"Microsoft"}]},
{"rel":"category", "href":"...", "prompt":"",
"data":[{"name":"category",
"value":"Ruby"}]}]
Rels are described in MIME
Best MIME type is XHTML: it supports forms!
3 whales:HTTP + MIME + HATEOAS
HATEOAS: hypermedia as the engine of application state
<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>
ticket: {
assigned_to: someone,
links: [
{rel: “unassign”, url: “...”},
{rel: “close”, url: “...”}
]
}
ticket: {
assigned_to: null,
links: [
{rel: “assign”, url: “...”},
{rel: “remove”, url: “...”}
]
}
*MIME types are registered in IANA w/ public access
HTTP:
HTTP verbs:
GET
HEAD
POST
PUT
PATCH
DELETE
OPTIONS
HTTP verbs:
GET
HEAD
POST
PUT
PATCH
DELETE
OPTIONS
Status codes:
100.upto(505).almost_each do |status_code|…end
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
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
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
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
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
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
Request headers:
OPTIONS /payment/order/1234 HTTP 1.1 Host: starbucks.example.com
Response
200 OK Allow: GET, PUT
Request headers:
PUT /order/1234 HTTP 1.1 Host: starbucks.example.com Expect: 100-Continue
Response:
100 Continue
Request:
PUT /order/1234 HTTP 1.1 Host: starbucks.example.com {body}
Response:
200 OK
{body}
Request:
PUT /order/1234 HTTP 1.1 Host: starbucks.example.com
{body}
Response:
409 Conflict
Request:
PUT /order/1234 HTTP 1.1 Host: starbucks.example.com Expect: 100-Continue
Response:
417 Expectation Failed
HTTP Headers:Accept/typeEtagCacheAuthorizationVersionIf-Unmodified-SinceIf-Match
HTTP Headers:Accept/typeEtagCacheAuthorizationVersionIf-Unmodified-SinceIf-Match
Media types (revisited):Accept: application/xmlAccept: application/json
GET https://api.github.com/gists/1
Accept: application/json
200 OK
Content-Type: application/json; charset=utf-8
(response body)
GET https://api.github.com/gists/1
Accept: application/xml
200 OK
Content-Type: application/xml; charset=utf-8
(response body)
GET https://api.github.com/gists/1
Accept: application/xml
406 Not Acceptable
Content-Type: application/json
{
"message": "Must ACCEPT application/json: [\"application/xml\"]"
}
HTTP Headers:Accept/typeEtagCacheAuthorizationVersionIf-Unmodified-SinceIf-Match
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
HTTP Headers:Accept/typeEtagCacheAuthorizationVersionIf-Unmodified-SinceIf-Match
Authentication:Basic HTTP Authentication
(with SSL or Digesting)
HTTP Headers:Accept/typeEtagCacheAuthorizationVersionIf-Unmodified-SinceIf-Match
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
HTTP Headers:Accept/typeEtagCacheAuthorizationVersionIf-Unmodified-SinceIf-Match
Richardson Maturity Model
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
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
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
4. Hypermedia Controls. HATEOAS. You’re 100% REST compliant.
GET https://api.example.com/HTTP 1.1
Accept: application/vnd.example-v1+jsonIf-Match: “...”
Authentication: ...
200 OK{root: {entries: ...},
links: [{rel: “edit”, url: “...”}, {…}]}
No client-server coupling
1 stable URL
No dependencies on URLs and params
Client is valid forever (ideally)
Just as web browsers work
Wish you all to be at level 4
(if you want)
Sources:
“Architectural Styles andthe Design of Network-based Software
Architectures”http://www.ics.uci.edu/~fielding/pubs/di
ssertation/top.htm
http://blog.steveklabnik.com/posts/2012-02-27-hypermedia-api-reading-list
“Building Hypermedia APIs with HTML5 and Node”
Mike Amundsen
http://timelessrepo.com/haters-gonna-hateoas
REST is over!http://blog.steveklabnik.com/posts/2012-02-
23-rest-is-over
Questions!