Stop Making The Web Harder Than It Is; Real-world REST, HATEOAS, and Hypermedia APIs with Magpie


Published on

Developing for the Web shouldn't be hard. Yet, many smart developers make it more difficult than it needs to be by choosing tools and frameworks that do not fully take advantage of all that HTTP has to offer. This talk demonstrates how projects at all levels-- from the simplest brochureware site to the most advanced Hypermedia APIs--can be made simpler by getting back to the basics of HTTP. We introduce Tamarou's internal application development and publishing framework, Magpie (scheduled for public release to coincide with YAPC::NA) and step through a series of real-world examples to show how its resource-oriented approach to development keeps simple things simple and makes hard things easier.

Topics include:

* Why MVC is the wrong way to think about Web development.
* Why most frameworks that claim to be RESTful aren't (and how that makes life harder)
* An brief introduction to Resource-oriented development.
* A series of production-tested Magpie recipes covering the gamut of Web-dev from simple templated sites through advanced Hypermedia applications.

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Stop Making The Web Harder Than It Is; Real-world REST, HATEOAS, and Hypermedia APIs with Magpie

  1. 1. Stop Making The Web Harder Than It Is;Real-world REST, HATEOAS, and Hypermedia APIs with Magpie Kip Hampton Senior Architect, Tamarou @kiphampton
  2. 2. I’m looking at you, gphat...
  3. 3. ZOMG Teh Future!
  4. 4. Haha, Only Serious• Dedicated Hypermedia Type (HTML)• Communication sent over HTTP using the standard verbs. (GET, POST)• Data contains embedded, discoverable links to related resources and addditional metadata.• Raw payload meaningful to both humans and specialized clients.
  5. 5. Why Is The Web Still Hard?• We invented (then re-invented) new things instead of using all that HTTP offered.• We overburdened the things we did use.• We applied the wrong design patterns (MVC).
  6. 6. REST == Using All Of HTTP• HTTP Verbs (GET, POST, PUT, DELETE, etc)• Status Codes (theres more to life than 200 OK)• Headers (Link, ETag, X-* custom headers)• Media Types (Be inventive!)
  7. 7. Sorry, HATEOASers• Hypermedia as the Engine of Application State• Dont make the client have to guess (or already know) what to do next. o Think: HTML Links, Forms o Custom media types especially useful.
  8. 8. Hypertext Application Language• Simple, lightweight.• Comprehensible to both human and automated clients.• Associated Resources can be embedded or linked to.• Available in both JSON and XML formats.• More at:
  9. 9. HAL (JSON){ "_links": { "self": { "href": "/orders" }, "next": { "href": "/orders?page=2" }, "find": { "href": "/orders{?id}", "templated": true } }, "_embedded": { "orders": [{ "_links": { "self": { "href": "/orders/123" }, "basket": { "href": "/baskets/98712" }, "customer": { "href": "/customers/7809" } }, "total": 30.00, "currency": "USD", "status": "shipped", },{ "_links": { "self": { "href": "/orders/124" }, "basket": { "href": "/baskets/97213" }, "customer": { "href": "/customers/12369" } }, "total": 20.00, "currency": "USD", "status": "processing" }] }, currentlyProcessing: 14, shippedToday: 20 }}
  10. 10. "A resource is not the thingthat is transferred across thewire or picked up off the diskor seen from afar while walkingyour dog. Each of those is onlya representation."Roy Fielding, 2002
  11. 11. The Resource Is Not The Thing
  12. 12. Introducing Magpie• Built specifically with Resource-oriented development in mind.• Uses a event-based pipeline processing model. o Configuration determines which components are loaded into the pipeline. o Components determine which of their event methods will fire.• Implemented via Plack::Middleware::Magpie.
  13. 13. Hello, Magpieuse Plack::Builder;use Plack::Middleware::Magpie;my $docroot = ‘/some/path/to/htdocs’;my $app = builder { enable "Magpie", pipeline => [ Magpie::Transformer::XSLT => { stylesheet => “$docroot/stylesheets/hello.xsl” } ]; enable "Static", path => qr!.xml$!, root => $docroot;};$app; • Single pipeline component. • Resource data passed from upstream middleware.
  14. 14. Dispatching• The URL path is only part of the equation.• Dispatching happens on two levels: 1. Which components will be loaded into the pipeline? 2. Which event methods will be fired within those components?
  15. 15. Loading Components• Application pipelines are defined via configuration (Plack::Builder-like DSL, or XML file).• Several options: • Static pipelines. • Dynamic pipelines via the machine() keyword and one or more of the match* options.• Components are added top-down, in configuration order.
  16. 16. Dynamic Pipelines Dynamic component loading via the machine() keyword. • match -- Adds component(s) conditionally based on string equality or regular expression match against the request’s path.enable "Magpie", pipeline => [machine { match qr|^/api/cast-member| => [‘MyApp::Resource::CastMember’], match qr|^/api/prop| => [‘MyApp::Resource::Prop’],} MyApp::Serializer::JSON,];
  17. 17. Dynamic Pipelines (cont’d)• match_template -- Adds component(s) conditionally based on regular expression match and uses URI Template-like brackets ({}) to capture param/value pairs.• match_env -- Adds component(s) by evaluating an anonymous subroutine which is passed the Plack environment hash at request time.• match_accept -- Adds component(s) by evaluating a content negotiation matrix against the Accept* headers of the incoming request.
  18. 18. Event Dispatching• Each component class controls its own event dispatching.• Standard event models. o Magpie::Dispatcher::RequestMethod o Magpie::Dispatcher::RequestParam• Easy to roll your own. o Write your event methods, o Register the methods you want Magpie to know about, o Implement load_queue() to define which events fire under what circumstances.
  19. 19. Do I really need all that?
  20. 20. Simple Resourcepackage MyApp::Resource::Widget;use Moose;extends Magpie::Resource;use Magpie::Constants;sub GET { my ($self, $context) = @_; $self->parent_handler->resource($self); my $data = $self->however_you_get_widget_data(%some_args); unless ($data) { $self->set_error({ status_code => 404, reason => Resource not found. }); return DONE; } $self->data($data); return OK;}
  21. 21. If theres no Model and the Resource is not The Thing, where does stuff go?
  22. 22. Assets• Each Magpie application has a Bread::Board container to hold the things required to implement your Resource classes and other components.• Assets can be added both via the DSL and the XML config. (merged at start-up).• Available in each component class $dbh = $self->resolve_asset( service => db_handle);
  23. 23. But Wait!Theres more!
  24. 24. Extras• Existing Plack::Middleware::* classes can be used as pipeline components with no modification.• Component class event methods have full access to the pipeline and can end the processing chain, add or remove components, etc.• Component base classes offer a predictable set of convenience attibutes for operating on the incoming request, the outgoing response, the current resource class, etc.• All component classes are Trait-aware from the start.
  25. 25. Whats There?• A solid, stable, tested core.• Workable APIs for various common component types (Resources, Transformers, Plugins, Dispatchers).• Small but growing number of general components. (KiokuDB and File Resources, XSLT, Template Toolkit Transformers, etc.)• A committed core of developers.
  26. 26. Whats Missing?• Docs, docs, docs.• Many more generic component classes.• Bootstrap profiles for common types of applications.• Magpie GUI.• Mostly, what Magpie needs right now is…
  27. 27. YOU!
  28. 28. Questions?
  29. 29. Thank You
  30. 30. More Information• GitHub:• IRC: #magpie• Mailing List:• Hallway++ Barge right up and ask!