design hypermedia apis

Post on 10-May-2015

5.454 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

DESIGN HYPERMEDIA APISGustaf Nilsson Kotte / @gustaf_nk

OUR TASKDesign an API for a kanban board. The API will have multiple clients.

KANBAN BOARD

API GET/POST items/

{ id: 123, name: "...", description: "...", status: "backlog|working|verify|done" }

SERVER SIDE: ENFORCE RULESDon't trust clients

CLIENT SIDE: USER FRIENDLY

Hide non-valid transitionsShow primary transitions "Read the specification"

SPECIFICATION Implement the state machine on the right.

The primary action for each state is the "downward" arrow, except for the state "done" where the primary action is to move the item back to the "working" state.

CLIENT SIDE VARIATIONS function nextStates(item) { if (item.state == 'backlog') return ['working']; else if (item.state == 'working') return ['backlog', 'verify']; ... } function getPrimary(state) { if (item.state == 'backlog') return 'working'; ... }

CLIENT SIDE VARIATIONS function nextStates(item) { dict = { 'backlog' => ['working'], 'working' => ['backlog, verify'], ... return dict[item.state]; } function getPrimary(state) { if (item.state == 'backlog') return 'working'; ... }

CLIENT SIDE VARIATIONS function nextStates(item) { dict = { 'backlog' => ['working'], 'working' => ['backlog, verify'], ... return dict[item.state]; } function isPrimary(state, nextState) { return nextState == nextStates(state).last(); }

Many possibilities!

CLIENT SIDE VARIATIONS function nextStates(item) { var stateMachine = new StateMachine(conf.json);

return stateMachine.getTransitions(item.state); } function isPrimary(state, nextState) { return nextState == nextStates(state).last(); }

WITHOUT HYPERMEDIA

PREFER FAT APIS OVER FAT CLIENTS

http://martinfowler.com/articles/richardsonMaturityModel.html

HYPERMEDIA APIS

WHAT IS THE HYPERMEDIA CONSTRAINT?

— Jon Moore

You do stuff by reading pages and then either

follow links or submit forms.

DESIGN PROCESS1. Evaluate processes2. Create state machine3. Evaluate media types4. Create or choose media types5. Implementation6. Refinements

http://www.designinghypermediaapis.com

1. EVALUATE PROCESSES

1. EVALUATE PROCESSES

Collections: "board", backlog, working, verify, done Single: details, edit

Write: being able to change the state of an item according to the rules

2. CREATE STATE MACHINE

FIRST ATTEMPT...

Simplified view

Inline actions

Better root node

3. EVALUATE MEDIA TYPES

H-FACTORS

http://amundsen.com/hypermedia/hfactor/

H-FACTORS FOR OUR APILO: Support for out-bound navigational links (HTTP GET)LN: Support for non-idempotent updates (HTTP POST)CL: Support for adding semantic meaning to link elementsusing link relations

4. CREATE OR CHOOSE MEDIA TYPES

HTMLHALCollection+JSONSirenJSON-LDAtomSVGOData

Name Summary Read/write Comment

HAL Resources and relations R Write support with addon

Collection+JSON Collections over JSON RW

Siren ~ JSON port of HTML RW

JSON-LD ~ RDF over JSON R

USE HTML FOR HYPERMEDIA APIS

Lots of hypermedia controlsOld, standardized, everybody knows HTMLGood tooling support

https://vimeo.com/20781278http://codeartisan.blogspot.se/2012/07/using-html-as-media-type-for-your-api.html

http://amundsen.com/hypermedia/html/

MORE...

Great for learning about hypermedia!

EXAMPLE: MICROFORMATS2, ENTITIES<li class="h-item"> <div class="p-name"><%= item.name %></div> <div class="p-status"><%= item.status %></div> <div class="p-description"><%= item.description %></div> <div class="p-forms"> ... </div> <div class="p-links"> ... </div></li>

EXAMPLE: MICROFORMATS2, FORMS<div class="p-forms"> <form data-rel="move backlog" action="/items/backlog" method="POST"> <input name="id" type="hidden" value="4"> <input title="submit" type="submit" value="Move to backlog"> </form> <form data-rel="move verify next" action="/items/verify" method="POST"> <input name="id" type="hidden" value="4"> <input title="submit" type="submit" value="Move to verify"> </form></div>

5. IMPLEMENTATION

6. REFINEMENTS

(Better root node)

Cache profiles analysis: Separate Board and Navigation

DONE! JUST ONE MORE THING... :)

WRITING A HYPERMEDIA AWARE CLIENT

Not harder than writing a "regular" client, just different...

...which means it's harder, since new to many developers :(

GENERIC VS SPECIFIC CLIENT?

STANDARDIZED DOMAIN VS

WALLED GARDEN"Atom client" vs "Twitter client"However, standard media types still have value!

USE THE AFFORDANCESLink relations (navigational state)Form relations (server state)

DEMO: CHANGING THE APPLICATION

DEMO: RUBY CONSOLE CLIENT

WHERE'S THE APPLICATION?

SUMMARY

BOOKS, Steve Klabnik Designing Hypermedia APIs

, Mike Amundsen Building Hypermedia APIswith HTML5 and Node

THANK YOU!Gustaf Nilsson Kotte / @gustaf_nk

Code: https://github.com/gustafnk/kanban-awd-api

Demo: and http://kanban-awd.herokuapp.com/ http://kanban-api.herokuapp.com

Slides: http://www.slideshare.net/GustafKotte/design-hypermedia-apis

top related