hypermedia apis and hateoas / wix engineering

77
Tel Aviv, 2017 Volodymyr Tsukur @ Engineering Meetup Hypermedia APIs and <HATEOAS>

Upload: vladimir-tsukur

Post on 16-Apr-2017

75 views

Category:

Technology


0 download

TRANSCRIPT

Tel Aviv, 2017Volodymyr Tsukur @ Engineering Meetup

Hypermedia APIs and <HATEOAS>

REST

Volodymyr Tsukurpartner @

software engineer @

flushdia vtsukur program committee @

Web / HTTP API

Richardson Maturity Model

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

DEMO TIME !

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

DEMO TIME !

/uri Style Adoption?

43%

Richardson Maturity Model

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

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

Security!

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

DEMO TIME !

Hypermedia Client

if (review._links.has("submission")) { // draw submit button / UI}

Non-Hypermedia Client

Hypermedia Client

"Simple" Hypermedia

✓where to go? ✓when? - how?

"I want hypermedia!" (2014)

0 %

7 %

14 %

21 %

28 %

Hypermedia SOAP CRUD

40%"I want hypermedia!" (2015)

«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

Hypertext Application Language

Mason{ "name": "Aviran", "title": "…", … "@controls": { "user": { "href": "/users/3" }, "review-submission": { "href": "/reviews/7/submission", "method": "PUT" } }}

Hypermedia Factors

level of hypermedia support

CL = Link Semantics

"_links": { "review": { "href": "/reviews/7" }}

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

CL = Link Semantics

<link rel="stylesheet" src="styles.css" />

LE = Link Outbound

"_links": { "user": { "href": "/users/7" }}

LE = Link Outbound

<a href="/review/1536c64.html"> Shai says "!", rating: 1</a>

LE = Link Embedded"_embedded": { "ratings": [ { "id": "7", … }, { "id": "8", … }, ]}

LE = Link Embedded

<img src="/images/cities/tel-aviv.jpg">

LT = Templated Queries"_links": { "review-by-id": { "href": "/reviews{/id}", "templated": true }}

LT = Templated Queries"_links": { "reviews": { "href": "/reviews{?page,size,sort}", "templated": true }}

RFC 6570

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 Factors

?What about and

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

CL = Link Semantics

"_links": { "review": { "href": "/reviews/7" }}

CL = Link Semantics

"_links": { "http://trump-feedback/rels/review": { "href": "/reviews/7" }}

CL = Link Semantics

"_links": { "urn:trump-feedback/rels/review": { "href": "/reviews/1" }}

CL = Link Semantics

"_links": { "trump-feedback:review": { "href": "/reviews/1" }}

CompactURIEtrump-feedback=http://trump-feedback/rels/{rel}

trump-feedback:review

http://trump-feedback.com/rels/review

DEMO TIME !

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" } }}

Profiles

✓where to go? ✓when? ✓how?

DEMO TIME !

Richardson Maturity Model

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/