Transcript
Page 1: Building Hypermedia APIs in JavaScript

Building Hypermedia APIs in Javascriptfrom homemade solution to using Fortune.js

Page 2: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

You?

Page 3: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

You?

• Who uses APIs?

Page 4: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

You?

• Who uses APIs?

• Who knows what Hypermedia APIs are?

Page 5: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

You?

• Who uses APIs?

• Who knows what Hypermedia APIs are?

• Who had ever build one?

Page 6: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Me

Page 7: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Me

• 3scale evangelist

Page 8: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Me

• 3scale evangelist

• API freak

Page 9: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Me

• 3scale evangelist

• API freak

• Hacker in Residence

Page 10: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Me

• 3scale evangelist

• API freak

• Hacker in Residence

• Node.js, Meteor

Page 11: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Hypermedia 101

Page 12: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

you are already using Hypermedia APIs

Page 13: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Core values

Page 14: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Core values

• Discoverable API

Page 15: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Core values

• Discoverable API

• Machine readable API

Page 16: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Core values

• Discoverable API

• Machine readable API

• Link-based

Page 17: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Example: GithubGET api.github.com { current_user_url: "https://api.github.com/user", authorizations_url: "https://api.github.com/authorizations", code_search_url: "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}", emails_url: "https://api.github.com/user/emails", emojis_url: "https://api.github.com/emojis", events_url: "https://api.github.com/events", feeds_url: “https://api.github.com/feeds",ed{/owner}{/repo}", … team_url: "https://api.github.com/teams", user_url: "https://api.github.com/users/{user}", user_organizations_url: "https://api.github.com/user/orgs", user_repositories_url: "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}", user_search_url: "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}" }

Page 18: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Example: building

REST approach

/rooms/r123

/doors/d123

Page 19: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Example: buildingAdding relations

/rooms/r123

• /rooms/r123/doors/d123

/doors/d123

• /doors/d123/rooms/r123

Page 20: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Example: buildingBuildings have hallways

/doors/1/rooms/1

/doors/1/hallways/1

/rooms/1/doors/1

/rooms/1/hallways/1

/hallways/1/doors/1

/hallways/1/rooms/1

Page 21: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Me…

Page 22: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Me…

Page 23: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Let’s put Hypermedia in itLinking ressources

• /rooms/1

- rel: door, href: /what/ever/door

- rel: door, href: /another/door

• /door

- rel: entry-to, href: /rooms/1

- rel: entry-to, href: /hallways/1

• /hallways/1

- rel: floor, href: /floors/1

Page 24: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

HATEOAS

• Basic implementation with Express

• add “link” properties to the JSON response

Hypermedia as the Engine of Application State

Page 25: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

HATEOASGET mybuilding.com/rooms/1 { "data": { "name": "Kitchen", "id": "1", "links" : [ { "rel": "door", "href": "https://mybuilding.com/rooms/12345678" }, { "rel": "door", "href": "https://theirbuilding.com/rooms/12345678" } ] } }

Page 26: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

There is a framework for that

Page 27: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Fortune.js

Page 28: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Fortune.js• simple to setup

var fortune = require('fortune') , app = fortune({ db: 'petstore' }) .resource('person', { name: String, age: Number, pets: ['pet'] // "has many" relationship to pets }) .resource('pet', { name: String, age: Number, owner: 'person' // "belongs to" relationship to a person }) .listen(1337);

Page 29: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Fortune.jsHTTP Person Pet Notes

GET /people /pets Get a collection of resources, accepts query ?

POST /people /pets Create a resource

GET /people/:id /pets/:id Get a specific resource, or multiple: 1,2,3

PUT /people/:id /pets/:id Create or update a resource

PATCH /people/:id /pets/:id Patch a resource (see RFC 6902)

DELETE /people/:id /pets/:id Delete a resource

GET /people/:id/pets /pets/:id/owner Get a related resource (one level deep)

Page 30: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Fortune.js• JSON API spec

{ "people": [ { "id": "tO69XnLz7amaYVRq", "name": "Wall-E", "age": 1000, "links": { "pets": [ "dPuXqUJxRIn9cOdH" ] } } ], "links": { "people.pets": { "href": "/pets/{people.pets}", "type": "pets" } } }

Page 31: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Fortune.js• JSON API spec

/people/tO69XnLz7amaYVRq { "people": [ { "id": "tO69XnLz7amaYVRq", "name": "Wall-E", "age": 1000, "links": { "pets": [ "dPuXqUJxRIn9cOdH" ] } } ], "links": { "people.pets": { "href": "/pets/{people.pets}", "type": "pets" } } }

Page 32: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Fortune.js• JSON API spec

/people/tO69XnLz7amaYVRq { "people": [ { "id": "tO69XnLz7amaYVRq", "name": "Wall-E", "age": 1000, "links": { "pets": [ "dPuXqUJxRIn9cOdH" ] } } ], "links": { "people.pets": { "href": "/pets/{people.pets}", "type": "pets" } } }

/pets/dPuXqUJxRIn9cOdH { "pets": [ { "id": "dPuXqUJxRIn9cOdH", "name": "Cucaracha", "age": 1000, "links": { "owner": "tO69XnLz7amaYVRq" } } ], "links": { "pets.owner": { "href": "/people/{pets.owner}", "type": "people" } } }

Page 33: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Fortune.js

adapters for NeDB, MongoDB, MySQL, Postgres, SQLite handles all the routing handles database interactions hooks for specific logic before/after interacting with

resources authentication not implemented (build your own)

Page 34: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

API-based game: APIbunny

Page 35: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

APIbunny{ north: { ref: 'cell', inverse: 'south' }, east: { ref: 'cell', inverse: 'west' }, south: { ref: 'cell', inverse: 'north' }, west: { ref: 'cell', inverse: 'east' } }

Page 36: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

APIbunny• Inverse relation does not work in case of maze{ north: { ref: 'cell', inverse: 'south' }, east: { ref: 'cell', inverse: 'west' }, south: { ref: 'cell', inverse: 'north' }, west: { ref: 'cell', inverse: 'east' } }

Page 37: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

APIbunny• Inverse relation does not work in case of maze{ north: { ref: 'cell', inverse: 'south' }, east: { ref: 'cell', inverse: 'west' }, south: { ref: 'cell', inverse: 'north' }, west: { ref: 'cell', inverse: 'east' } }

1 4 7

2 5 8

3 6 9

Page 38: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

APIbunny• Inverse relation does not work in case of maze{ north: { ref: 'cell', inverse: 'south' }, east: { ref: 'cell', inverse: 'west' }, south: { ref: 'cell', inverse: 'north' }, west: { ref: 'cell', inverse: 'east' } }

1 4 7

2 5 8

3 6 9

{ west:1 east:7 south:5 }

expected on #4

Page 39: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

APIbunny• Inverse relation does not work in case of maze{ north: { ref: 'cell', inverse: 'south' }, east: { ref: 'cell', inverse: 'west' }, south: { ref: 'cell', inverse: 'north' }, west: { ref: 'cell', inverse: 'east' } }

1 4 7

2 5 8

3 6 9

{ west:1 east:7 south:5 }

expected on #4

east of #1 is #4 -> west of #4 is #1

but east of #7 is #4 -> west of #4 is #7

Page 40: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

APIbunny• POST requests format is not usual

{"people":[{"age":1000,"name":"Wall-E"}]}

Page 41: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

APIbunny

• thousands players, 44 winners, ~10 code shared

• Open https://github.com/picsoung/apibunny/

• V2 is coming ;)

Page 42: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Ressources• http://apicodex.3scale.net/

• http://amundsen.com/hypermedia/

• http://www.designinghypermediaapis.com/

• https://www.youtube.com/watch?v=_UG7u7ARTfM (APIStrat SF)

• APIdays and APIstrat conferences

• API-craft meetup + google group

Page 43: Building Hypermedia APIs in JavaScript

HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

Questions?

!picsoung" picsoung