Slide 1

Slide 1 text

PHP New Zealand Conference Designing Hypermedia APIs Nate Abele! August 2014! Wellington, New Zealand

Slide 2

Slide 2 text

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 / [email protected]

Slide 3

Slide 3 text

Consulting · Training · Development http://radify.io

Slide 4

Slide 4 text

Hypermedia: ¿WAT? ❖ REST?! ❖ Content negotiation?! ❖ State machine?! ❖ Something else?

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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” } } }]

Slide 7

Slide 7 text

But… Really

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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…

Slide 10

Slide 10 text

Problems “Over time, software atrophies.! Boundaries must be erected to manage it.” See also: http://12factor.net

Slide 11

Slide 11 text

Versioning

Slide 12

Slide 12 text

Versioning ❖ A way of managing change over time! ❖ Different options, different tradeoffs! ❖ Considerations! ❖ Maintenance for you! ❖ Maintenance for consumers! ❖ Complexity over time! ❖ Operational overhead

Slide 13

Slide 13 text

Versioning: Version Numbers ❖ Explicit communication, manual intervention! ❖ Blocking; waterfall release cycle! ❖ Good for “local” dependencies

Slide 14

Slide 14 text

Versioning: __________?

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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.)

Slide 21

Slide 21 text

Implementation

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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!

Slide 24

Slide 24 text

Design Considerations Your ORM is Not Your Model https://vend.github.io/preso/monolith.html! ! @nzdominic

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

Design Considerations: Links ❖ Good: title! ❖ Better: title + description! ❖ Possibly: type

Slide 27

Slide 27 text

Implementation Goals ❖ Flexible! ❖ Composable! ❖ Testable

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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' => [. . .] ]] ] } }

Slide 30

Slide 30 text

class Links { ! public function types() { return ['json', 'xml']; } ! public function methods() { return ['GET']; } ! public function apply($request, $object, array $results) { // ... } }

Slide 31

Slide 31 text

Fractal http://fractal.thephpleague.com/

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

Formats ❖ HAL! ❖ UBER! ❖ Collection+JSON! ❖ Siren! ❖ Custom?

Slide 34

Slide 34 text

People to follow ❖ Mike Amundsen @mamund! ❖ Steve Klabnik @steveklabnik! ❖ Luke Stokes @lukestokes! ❖ Kevin Swiber @kevinswiber

Slide 35

Slide 35 text

Thanks! ❖ @nateabele! ❖ [email protected]