Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Building Hypermedia APIs in JavaScript

3,429 views

Published on

Nicolas Grenie's presentation from HTML5 Dev Conf. 2014:

There is currently a major shift sweeping over the software industry. With each passing day the world is becoming more and more API-driven. When building an API there are many design options and Hypermedia is the new emerging way of designing APIs. Hypermedia APIs are widely used by companies such as Paypal and Amazon. In this session I will discuss the principles of Hypermedia APIs and the different ways to implement one in Node.js. I will first introduce you to a basic implementation using Express and then move on to a more advanced solution using a dedicated framework: Fortune.js. I will also share my experience of building APIbunny (http://apibunny.com), an API-driven easter game.

Published in: Technology
  • Be the first to comment

Building Hypermedia APIs in JavaScript

  1. 1. Building Hypermedia APIs in Javascript from homemade solution to using Fortune.js
  2. 2. You? HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  3. 3. You? • Who uses APIs? HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  4. 4. You? • Who uses APIs? • Who knows what Hypermedia APIs are? HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  5. 5. You? • Who uses APIs? • Who knows what Hypermedia APIs are? • Who had ever build one? HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  6. 6. Me HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  7. 7. Me • 3scale evangelist HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  8. 8. Me • 3scale evangelist • API freak HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  9. 9. Me • 3scale evangelist • API freak • Hacker in Residence HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  10. 10. Me • 3scale evangelist • API freak • Hacker in Residence • Node.js, Meteor HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  11. 11. Hypermedia 101 HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  12. 12. you are already using Hypermedia APIs HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  13. 13. Core values HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  14. 14. Core values • Discoverable API HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  15. 15. Core values • Discoverable API • Machine readable API HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  16. 16. Core values • Discoverable API • Machine readable API • Link-based HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  17. 17. Example: Github GET 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}" } HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  18. 18. Example: building REST approach /rooms/r123 /doors/d123 HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  19. 19. Example: building Adding relations /rooms/r123 • /rooms/r123/doors/d123 /doors/d123 • /doors/d123/rooms/r123 HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  20. 20. Example: building Buildings 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 HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  21. 21. Me… HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  22. 22. Me… HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  23. 23. Let’s put Hypermedia in it Linking 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 HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  24. 24. HATEOAS Hypermedia as the Engine of Application State • Basic implementation with Express • add “link” properties to the JSON response HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  25. 25. HATEOAS GET 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" } ] } } HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  26. 26. There is a framework for that HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  27. 27. Fortune.js HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  28. 28. 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); HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  29. 29. Fortune.js HTTP Person Pet Notes GET /people /pets HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung 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)
  30. 30. 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" } } } HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  31. 31. 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" } } } HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  32. 32. 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" } } } HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  33. 33. 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) HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  34. 34. API-based game: APIbunny HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  35. 35. APIbunny { north: { ref: 'cell', inverse: 'south' }, east: { ref: 'cell', inverse: 'west' }, south: { ref: 'cell', inverse: 'north' }, west: { ref: 'cell', inverse: 'east' } } HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  36. 36. 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' } } HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  37. 37. 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 HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  38. 38. 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 expected on #4 { west:1 east:7 south:5 } HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  39. 39. 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 expected on #4 { west:1 east:7 south:5 } east of #1 is #4 -> west of #4 is #1 but east of #7 is #4 -> west of #4 is #7 HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  40. 40. APIbunny • POST requests format is not usual {"people":[{"age":1000,"name":"Wall-E"}]} HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  41. 41. APIbunny • thousands players, 44 winners, ~10 code shared • Open https://github.com/picsoung/apibunny/ • V2 is coming ;) HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  42. 42. 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 HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung
  43. 43. Questions? " picsoung !picsoung HTML5 Conference SF Oct. 2014 Nicolas Grenié - !picsoung

×