Designing Hypermedia APIs

7fca546408cc6d46ab158f06baed2535?s=47 Nate Abele
August 28, 2014

Designing Hypermedia APIs

7fca546408cc6d46ab158f06baed2535?s=128

Nate Abele

August 28, 2014
Tweet

Transcript

  1. PHP New Zealand Conference Designing Hypermedia APIs Nate Abele! August

    2014! Wellington, New Zealand
  2. The Vanity Slide ❖ Former lead developer, CakePHP! ❖ Founder,

    Li3 (a.k.a. Lithium)! ❖ Member, AngularUI team! ❖ Lead Developer, AngularUI Router! ❖ Architect-in-Chief, Radify! ❖ Highly opinionated, sometimes right! ❖ @nateabele / nate@radify.io
  3. Consulting · Training · Development http://radify.io

  4. Hypermedia: ¿WAT? ❖ REST?! ❖ Content negotiation?! ❖ State machine?!

    ❖ Something else?
  5. Foundation: REST Level 0 Level 1 Level 2 Level 3

    RPC HTTP /soap /service …/posts …/comments …/users POST /users GET /users/nate { name: nate } * See: Richardson Maturity Model GET /users/nate/posts GET /users/nate Accept: application/vnd.somethinguseful+json
  6. Hypermedia 101 GET http://my.app/tasks HTTP/1.1 Accept: application/hal+json ! [{ title:

    "Finish the demo", completed: false, _links: { self: { href: “http://my.app/tasks/1138” }, owner: { href: “http://my.app/users/nate” }, subtasks: { href: “http://my.app/tasks/1138/tasks” } } }]
  7. But… Really

  8. “Hypermedia is a way of thinking about distributed systems.”

  9. Problems ❖ …built an app with Facebook Connect?! ❖ …built

    an app with Facebook anything?! ❖ …published an API, then changed the database schema?! ❖ …read an API doc, just to see how resources are related? Ever…
  10. Problems “Over time, software atrophies.! Boundaries must be erected to

    manage it.” See also: http://12factor.net
  11. Versioning

  12. Versioning ❖ A way of managing change over time! ❖

    Different options, different tradeoffs! ❖ Considerations! ❖ Maintenance for you! ❖ Maintenance for consumers! ❖ Complexity over time! ❖ Operational overhead
  13. Versioning: Version Numbers ❖ Explicit communication, manual intervention! ❖ Blocking;

    waterfall release cycle! ❖ Good for “local” dependencies
  14. Versioning: __________?

  15. Versioning: Content Negotiation GET http://my.app/users/nate HTTP/1.1 Accept: application/vnd.radify.user+json ! {

    name: “Nate Abele", title: “Architect”, address: “1 Rad Way, Philadelphia, PA” }
  16. Versioning: Content Negotiation GET http://my.app/users/nate HTTP/1.1 Accept: application/vnd.radify.user-addr+json ! {

    name: “Nate Abele", title: “Architect”, address: { street: “1 Rad Way”, city: “Philadelphia”, state: { name: “Pennsylvania”, abbr: “PA” }, country: { name: “United States”, abbr: “US” } } }
  17. Versioning: New Resources GET http://my.app/users/nate HTTP/1.1 Accept: application/vnd.radify.user+json ! {

    name: “Nate Abele", title: “Architect”, address: “1 Rad Way, Philadelphia, PA”, _links: { address: { href: “http://my.app/users/nate/address” } } }
  18. Versioning: Feature Flags GET http://my.app/users/nate?better_addresses=1 GET http://my.app/users/nate Go-Faster: 1 PATCH

    http://my.app/users/nate { new_email_templates: true } POST http://my.app/transaction-involving-mail $_SERVER[“EXPERIMENTAL”] = ALL_THE_THINGS GET http://beta.my.app/users/nate See also: chrome://flags
  19. Versioning: Feature Flags ❖ Implicit: never breaks clients! ❖ Clean

    boundary between server and clients! ❖ Agile: incremental evolution, no ‘all-or-nothing’ decisions! ❖ Good for network dependencies! ❖ Granular; cascading
  20. Versioning: Feature Flags ❖ Server-side! ❖ Per environment (local, remote)!

    ❖ Per deploy (beta/release, staging/production)! ❖ Per instance (for internal testing, segmenting etc.)! ❖ Client-side! ❖ Per account (preferences)! ❖ Per session (if using tokens/cookies)! ❖ Per request (headers, query params, etc.)
  21. Implementation

  22. Existing Formats ❖ HAL! ❖ Collection+JSON! ❖ Siren

  23. Design Considerations ❖ Provide links to related resources! ❖ The

    network is slow: collate relevant data to send over the wire! ❖ Give the people what they want! ❖ Also: no database IDs!
  24. Design Considerations Your ORM is Not Your Model https://vend.github.io/preso/monolith.html! !

    @nzdominic
  25. Architecture: The Lost Years https://www.youtube.com/watch?v=HhNIttd87xs

  26. Design Considerations: Links ❖ Good: title! ❖ Better: title +

    description! ❖ Possibly: type
  27. Implementation Goals ❖ Flexible! ❖ Composable! ❖ Testable

  28. li3_resources https://github.com/nateabele/li3_resources

  29. class Projects extends li3_resources\action\Resource { ! protected function _mappers() {

    return [ 'Fields' => [ 'name', 'slug', 'created' => function($project) { return $project->_id->getTimestamp(); } ], 'Links', 'Schema', 'FlagAsNew' => ['+1 weeks’], 'Embed' => [ 'Permissions' => [ 'conditions' => ['approved' => true] 'fields' => [. . .] ]] ] } }
  30. class Links { ! public function types() { return ['json',

    'xml']; } ! public function methods() { return ['GET']; } ! public function apply($request, $object, array $results) { // ... } }
  31. Fractal http://fractal.thephpleague.com/

  32. BEAR.Sunday https://bearsunday.github.io/

  33. Formats ❖ HAL! ❖ UBER! ❖ Collection+JSON! ❖ Siren! ❖

    Custom?
  34. People to follow ❖ Mike Amundsen @mamund! ❖ Steve Klabnik

    @steveklabnik! ❖ Luke Stokes @lukestokes! ❖ Kevin Swiber @kevinswiber
  35. Thanks! ❖ @nateabele! ❖ nate@radify.io