30
Stop Making The Web Harder Than It Is; Kip Hampton Senior Architect, Tamarou @kiphampton https://github.com/ubu https://metacpan.org/author/KHAMPTON Real-world REST, HATEOAS, and Hypermedia APIs with Magpie

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

Embed Size (px)

DESCRIPTION

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.

Citation preview

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

Stop Making The Web Harder Than It Is;

Kip HamptonSenior Architect, Tamarou

@kiphamptonhttps://github.com/ubu

https://metacpan.org/author/KHAMPTON

Real-world REST, HATEOAS, and Hypermedia APIs with Magpie

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

I’m looking at you, gphat...

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

ZOMG Teh Future!

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

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.

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

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

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

REST == Using All Of HTTP

• HTTP Verbs (GET, POST, PUT, DELETE, etc)

• Status Codes (there's more to life than 200 OK)

• Headers (Link, ETag, X-* custom headers)

• Media Types (Be inventive!)

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

Sorry, HATEOASers• Hypermedia as the Engine of

Application State

• Don't make the client have to guess (or already know) what to do next.

o Think: HTML Links, Formso Custom media types especially

useful.

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

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: http://stateless.co/hal_specification.html

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

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

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

"A resource is not the thing that is transferred across the wire or picked up off the disk or seen from afar while walking your dog. Each of those is only a representation."

Roy Fielding, 2002

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

The Resource Is Not The Thing

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

Introducing Magpie• Built specifically with Resource-oriented

development in mind.

• Uses a event-based pipeline processing model.

oConfiguration determines which components are loaded into the pipeline.

oComponents determine which of their event methods will fire.

• Implemented via Plack::Middleware::Magpie.

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

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.

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

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?

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

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.

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

Dynamic PipelinesDynamic 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, ];

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

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.

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

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.

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

Do I really need all that?

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

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

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

If there's no Model and the Resource is not

The Thing, where does stuff go?

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

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');

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

But Wait!

There's more!

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

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.

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

What's 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.

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

What's 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…

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

YOU!

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

Questions?

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

Thank You