hypermedia apis and hateoas / wix engineering
TRANSCRIPT
6
{ "user": "Noah", "title": "Meets expectations", "comment": "hey dude,you make America Great Again!", "rank": 10}
Trump Feedback API
7
{ "user": "Shai", "title": "!", "comment": "oh you s** ** a bi***,how could people elect someone like you, ******* ******* ???", "rank": 1}
Trump Feedback API
9
Method URL Task
POST /reviews Create
GET /reviews View all
GET /reviews/{id} Get
PATCH / PUT /reviews/{id} Update
DELETE /reviews/{id} Delete
CRUD Style API
if (status == Status.NEW) { submittedAt = LocalDateTime.now() status = Status.SUBMITTED} …
CRUD is NOT enough
create submit accept
update
delete
NEW
DELETED
SUBMITTED ACCEPTED
12
Method URL Task
PUT /reviews/{id}/submission Submit
PUT /reviews/{id}/acceptance Accept
GET /reviews/search/accepted Get accepted reviews
API Changes
17
Task Method URL
Update PATCH /reviews/{id}
Delete DELETE /reviews/{id}
Submit PUT /reviews/{id}/submission
Accept PUT /reviews/{id}/acceptance
URL Binding & Construction
URL Change Drivers• monolith → micro-services • deployment requirements / proxies • resource renaming • optimization by client proximity • caching • …
20
Task Method URLUpdate
(only if NEW) PATCH /reviews/{id}
Delete (only if NEW) DELETE /reviews/{id}
Submit (only if NEW) PUT /reviews/{id}/submission
Accept (only if
SUBMITTED)PUT /reviews/{id}/acceptance
"Figuring" Out the Flow
22
Task Method URLUpdate
(only if NEW and user has permissions)
PATCH /reviews/{id}
Delete (only if NEW and user
has permissions)DELETE /reviews/{id}
Submit (only if NEW and user
has permissions)PUT /reviews/{id}/submission
Accept (only if SUBMITTED and user has permissions)
PUT /reviews/{id}/acceptance
Security!
"Hypermedia" =
{ "user": "Aviran", "title": "...", …}
data{ … "_links": { "submission": { "href": "/reviews/7/submission" }, "update": { "href": "/reviews/7" }, "deletion": { "href": "/reviews/7" } }}
link
+
26
Link Relation Task Method
update Update PATCH
deletion Delete DELETE
submission Submit PUT
acceptance Accept PUT
Hypermedia API
«A REST API should spend almost all of its descriptive effort in defining the media type(s)
used for representing resources and driving application state, or in defining extended relation
names and/or hypertext-enabled mark-up for existing standard media types.»
Roy T. Fielding, 2008
Mason{ "name": "Aviran", "title": "…", … "@controls": { "user": { "href": "/users/3" }, "review-submission": { "href": "/reviews/7/submission", "method": "PUT" } }}
IANA Link RelationsName Description RFC
self Conveys an identifier for the link's context. RFC4287
first An IRI that refers to the furthest preceding resource in a series of resources. RFC5988
last An IRI that refers to the furthest following resource in a series of resources. RFC5988
up Refers to a parent document in a hierarchy of documents. RFC5988
item The target IRI points to a resource that is a member of the collection represented by the context IRI. RFC6573
collection The target IRI points to a resource which represents the collection resource for the context IRI. RFC6573
edit Refers to a resource that can be used to edit the link's context. RFC5023
prev/previous Indicates that the link's context is a part of a series, and that the previous in the series is the link target. HTML5
next Indicates that the link's context is a part of a series, and that the next in the series is the link target. HTML5
IANA Link RelationsName Description RFC
create-form The target IRI points to a resource where a submission form can be obtained. RFC6861
edit-form The target IRI points to a resource where a submission form for editing associated resource can be obtained. RFC6861
payment Indicates a resource where payment is accepted RFC5988
latest-version Points to a resource containing the latest (e.g., current) version of the context. RFC5829
profile Identifying that a resource representation conforms to a certain profile, without affecting the non-profile semantics of the resource representation. RFC6906
search Refers to a resource that can be used to search through the link's context and related resources. OpenSearch
index Refers to an index. HTML4
about Refers to a resource that is the subject of the link's context. RFC6903
help Refers to context-sensitive help. HTML5
LT = Templated Queries"_links": { "reviews": { "href": "/reviews{?page,size,sort}", "templated": true }}
LT = Templated Queries
<form method="get" action="/hotels/search"> <input name="query" type="text"> <input type="submit"></form>
LN = Non-Idemp. Updates"actions": [ { "name": "create-review", "method": "POST", "href": "/reviews", "type": "application/json", "fields": [ { "name": "user", "type": "text" }, { "name": "title", "type": "text" }, { "name": "comment", "type": "text" }, { "name": "rank", "type": "number" }, … ] }]
<form method="post" action="/reviews"> <input name="user" type="text"> <input name="title" type="text"> <input name="comment" type="text"> … <input type="submit"></form>
LN = Non-Idemp. Updates
LN = Idempotent Updates"actions": [ { "name": "delete-review", "method": "DELETE", "href": "/reviews/7" }]
CM = Method Modification"actions": [ { "name": "delete-rating", "method": "DELETE", "href": "/ratings/1" }]
CR = Read Modification"_links": { "ballot": [ { "name": "ballot-json", "href": "/reviews/7", "type": "application/json" } { "name": "ballot-xml", "href": "/reviews/7", "type": "application/xml" } ]}
Hypermedia FactorsHTML XML JSON
LE ⩗ ⊗ ⊗
LO ⩗ ⊗ ⊗
LT ⩗ ⊗ ⊗
LN ⩗ ⊗ ⊗
LI ⊗ ⊗ ⊗
CR ⊗ ⊗ ⊗
CU ⩗ ⊗ ⊗
CM ⩗ ⊗ ⊗
CL ⩗ ⊗ ⊗
JSON-based Media TypesJSON-LD JSON API HAL Cj Siren Mason Uber
LE ⩗ ⩗ ⩗ ⩗ ⩗ ⩗ ⩗
LO ⩗ ⩗ ⩗ ⩗ ⩗ ⩗ ⩗
LT ⊗ ⩗ ⩗ ⩗ ⊗ ⩗ ⩗
LN ⊗ ⊗ ⊗ ⩗ ⩗ ⩗ ⩗
LI ⊗ ⊗ ⊗ ⩗ ⩗ ⩗ ⩗
CR ⊗ ⊗ ⩗ ⊗ ⩗ ⩗ ⩗
CU ⊗ ⊗ ⊗ ⊗ ⩗ ⩗ ⩗
CM ⊗ ⊗ ⊗ ⊗ ⩗ ⩗ ⩗
CL ⩗ ⩗ ⩗ ⩗ ⩗ ⩗ ⩗
Before Choosing Media Type
• list information client would want from the API
• draw state diagram - think "tasks" - "(non-)idempotent", "(un-)safe"
{ "@id": "http://trump.feedback/reviews/7", "@context": "http://trump.feedback/schema/review.jsonld", "user": "Shai", "title": "!", "comment": "oh you s** ** a bi*** ...", "rank": 1, …}
JSON-LD
{ "@context": { "user": "http://schema.org/name", "title": "https://schema.org/title", "comment": "https://schema.org/comment", "rank": "https://schema.org/ratingValue" … }}
http://trump-feedback/schema/rating.jsonld
{ "@id": "http://trump-feedback/reviews/7", … "supportedOperations": [ { "@type": "ReviewSubmission", "method": "PUT", "expects": "#Review" } ]}
JSON-LD + Hydra
{ "class": [ "review" ], "properties": { "user": "Aviran", "title": "...", … }, "links": …, "actions": [ { "name": "review-submission", "href": "/reviews/7", "method": "PUT", … } ]}
SIREN
CompactURIEtrump-feedback=http://trump-feedback/rels/{rel}
trump-feedback:review
http://trump-feedback.com/rels/review
Documentation• no URLs except of the entry point • resources • links (namespaces) • HTTP status codes, verbs • authentication, rate limiting • errors
Mason{ "name": "Aviran", "title": "...", … "@namespaces": { "trump-feedback": { "name": "http://trump-feedback/rels/" } }, "@controls": { "trump-feedback:user": { "href": "/users/3" }, "trump-feedback:review-submission": { "href": "/reviews/7/submission", "method": "PUT" } }}
References1. http://www.google.com.ua/trends/explore#q=web%20api%2C%20rest%20api&cmpt=q&tz= 2. http://finance.i.ua/market/ 3. http://projects.spring.io/spring-boot/ 4. http://projects.spring.io/spring-data/ 5. http://docs.spring.io/spring-data/jpa/docs/1.7.2.RELEASE/reference/html/ 6. http://projects.spring.io/spring-data-rest/ 7. http://docs.spring.io/spring-data/rest/docs/2.3.0.RELEASE/reference/html/ 8. https://spring.io/blog/2014/07/14/spring-data-rest-now-comes-with-alps-metadata 9. http://projects.spring.io/spring-hateoas/ 10. http://docs.spring.io/spring-hateoas/docs/0.17.0.RELEASE/reference/html/ 11. https://github.com/spring-projects/spring-restdocs 12. https://blog.akana.com/hypermedia-apis 13. http://www.apiacademy.co/lessons/api-design/web-api-architectural-styles 14. http://www.programmableweb.com/news/modern-api-architectural-styles-offer-developers-choices/2014/06/13 15. https://en.wikipedia.org/wiki/Hypermedia 16. http://stateless.co/hal_specification.html 17. https://github.com/kevinswiber/siren 18. https://www.mnot.net/blog/2013/06/23/linking_apis 19. http://oredev.org/2010/sessions/hypermedia-apis 20. http://vimeo.com/75106815 21. https://www.innoq.com/blog/st/2012/06/hypermedia-benefits-for-m2m-communication/ 22. http://ws-rest.org/2014/sites/default/files/wsrest2014_submission_12.pdf 23. http://www.infoq.com/news/2014/03/ca-api-survey 24. https://twitter.com/hypermediaapis 25. https://www.youtube.com/watch?v=hdSrT4yjS1g 26. https://www.youtube.com/watch?v=mZ8_QgJ5mbs 27. http://nordsc.com/ext/classification_of_http_based_apis.html 28. http://soabits.blogspot.no/2013/12/selling-benefits-of-hypermedia.html 29. https://github.com/mamund/Building-Hypermedia-APIs 30. http://tech.blog.box.com/2013/04/get-developer-hugs-with-rich-error-handling-in-your-api/