2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

78
HTTP ALL THE THINGS Simplifying Rich Applications by Respecting the Rules of the Web

description

PHP Conference Argentina 2013

Transcript of 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Page 1: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

HTTP ALL THE THINGSSimplifying Rich Applications byRespecting the Rules of the Web

Page 2: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Me

Nate Abele

Former lead developer, CakePHP

Founder & current lead developer, Lithium

Member, AngularUI

@nateabele

Page 3: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

History

Page 4: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

1998: SOAP & XML-RPC

Page 5: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

SOAP<?xml version="1.0"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <soap:Header></soap:Header> <soap:Body> <m:SomeCommand xmlns:m="..."> <m:BodyOfMessage>...</m:BodyOfMessage> </m:SomeCommand> </soap:Body></soap:Envelope>

Page 6: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Or...

Page 7: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

XML-RPC<?xml version="1.0"?>

<methodCall>

<methodName>examples.getStateName</methodName>

<params>

<param>

<value><i4>40</i4></value>

</param>

</params>

</methodCall>

Page 8: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

:-(

POST *

Invocaction details in body

Format lock-in

No relationships

No discoverability

Page 9: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

2000: REST

Page 10: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

REST Constraints

Client-Server

Stateless

Cacheable

Uniform Interface

Opaque Layering

Code-on-Demand

Page 11: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

The 4 Levels

RPC over HTTP (i.e. SOAP)

Resources

Verbs

Hypermedia Controls

Page 12: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Now: Hypermedia /HATEOAS

Page 13: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

¿Hypermedia?Content negotiation

State traversal

Page 14: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Content negotiation

application/json ...?

Page 15: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Content negotiation

application/json

FALE

Page 16: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Content negotiation

Better:application/rss+xml

Page 17: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Content negotiation

application/vnd.twitter.stream+json

// I can decode this!

json_decode()

/**

* I can understand this

!

*/

class Tweet {

protected $username;

protected $text;

// ...

}

Page 18: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

State traversal

Page 19: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web
Page 20: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Client: “What's next?”

Page 21: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

We already do this!

Page 22: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Browsers<link rel="stylesheet" href="/css/app.css" />

<link rel="next" href="/next" />

<link

rel="alternate"

type="application/rss+xml"

href="/posts.rss"

/>

Page 23: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Users(with the help of browsers)

<a href="/next" />Next</a>

<form></form>

Page 24: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Atom?

<link

rel="foo"

type="text/foo"

href="http://foo"

/>

Page 25: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

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/subtasks"} }}]

Page 26: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Why?

Page 27: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

AngularJS

Page 28: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Valid alternatives

EmberJS

KnockoutJS

Backbone (kind of, not really)

Page 29: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

AngularJS

Higher level of abstraction

Simple, well-designed architecture

Ridiculously simple unit testing

Page 30: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Event binding

Page 31: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Event bindingjQuery

<input type="text" id="name" /><h1>Hello!</h1>

<script type="text/javascript">

</script>

$(document).ready(function() { $('#name').keydown(function(e) { $('h1').html("Hello " + e.target.value + "!") }); });

Page 32: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Event bindingAngularJS

<input type="text" ng-model="name" />

<h1>Hello {{ name }}!</h1>

Hello !

Page 33: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

IterationjQuery

<ul class="greetings"></ul>

<script type="text/javascript">

</script>

$(["Hello", "Hola", "Ciao"]).each(function(k, v) { $(".greeting").append("<li>" + v + " World</li>" });

Page 34: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

IterationAngularJS

<ul> <li ng-repeat="greet in ['Hello', 'Hola', 'Ciao']"> {{ greet }} World </li></ul>

Hello World

Hola World

Ciao World

Page 35: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

<ul> <li ng-repeat="greet in ['Hello', 'Hola', 'Ciao']"> {{ greet }} World </li></ul>

Hello World

Hola World

Ciao World

Page 36: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

OrganizationAngularJS

Item: Qty: 0 Price: 0 Total: $0.00

Total: $0.00

Page 37: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

OrganizationAngularJS

<div ng-controller="CheckoutController">

<div ng-repeat="item in items">

Item: <input type="text" ng-model="item.name">

Qty: <input type="number" ng-model="item.qty">

Price: <input type="number" ng-model="item.price">

Total: <div class="total">

{{ item.qty * item.price | currency: "$" }}

</div>

</div>

<hr>

<div>Total: {{ total() | currency: "$" }}</div>

</div>

Page 38: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

OrganizationAngularJS

function CheckoutController($scope) {

$scope.items = $scope.items || [{ price: 0, qty: 0 }];

$scope.total = function() {

if ($scope.items[$scope.items.length - 1].qty) {

$scope.items.push({ price: 0, qty: 0 });

}

return $scope.items.map(function(item) {

return item.qty * item.price;

}).reduce(function(a, b) {

return a + b;

});

};

}

Page 39: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

OrganizationjQuery

¿Ummm...?

Page 40: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

OrganizationjQuery

*shrug*

Page 41: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

TestabilityAngularJS

describe("Shopping cart", function() {

describe("Checkout widget", function() {

it("should create a default element", function() {

var scope = {},

controller = new CheckoutController(scope);

expect(scope.items.length).toBe(1);

expect(scope.items[0].qty).toBe(0);

expect(scope.items[0].price).toBe(0);

});

});

});

Page 42: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

TestabilityAngularJS

describe("Shopping cart", function() {

describe("Checkout widget", function() {

// ...

it("should calculate order total", function() {

var scope = { items: [

{ price: 2, qty: 4 }, { price: 10, qty: 1 }

]};

var controller = new CheckoutController(scope);

expect(scope.total()).toBe(18);

});

});

});

Page 43: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

¿jQuery...?

Page 44: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

AngularJS + HTTPResources

Page 45: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

$resource()

Page 46: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

var Task = $resource("http://my.api/tasks/:id", {

id: "@id"

});

var newTask = new Task({

title: "New Task",

description: "..."

});

/* POST /tasks { "title": "New Task", ... } */

newPost.$save();

Page 47: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

/* GET /tasks/5 */

var oneTask = Task.get({ id: 5 });

/* GET /tasks?completed=false&due=1381158984 */

var current = Task.query({

completed: false,

description: "..."

});

Page 48: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

¡Muy mal!¡No me gusta!

¡Eso es shinaniganos!

Page 49: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Tight coupling

Client-side URL templates

Excessive parameters

No links!

Page 50: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Intent

Page 51: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

/tasks?

completed=false

&due=1381158984

Page 52: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

No meaning

Page 53: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

/tasks/current

Page 54: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

/tasks/:id

Page 55: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

$resource("/posts/:id", {id:"@id"});

{

id: 5,

title: "Something New",

slug: "something-new"

}

Page 56: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

...?

/posts/something-new

Page 57: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

What to do?

Page 58: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

uor/angular-model(on GitHub) *

* Current code is old and broken, new release coming tomorrow

Page 59: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

modelProvider.model("Tasks", {

$instance: {

finish: function() {

this.completed = true;

return this.$save();

},

isCompleted: function() {

return !!this.completed;

}

}

});

Page 60: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Where's the URL?

Page 61: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

3 options

Page 62: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Automatic: /tasks

Page 63: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

<link

rel="resource"

name="Tasks"

href="<?=$this->url('Tasks'); ?>"

/>

Page 64: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

GET /

Accept:application/vnd.resource-def+json

Page 65: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

{

"Tasks": "http://my.app/tasks",

"Users": "http://my.app/users"

}

Page 66: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

OPTIONS /tasks

Accept:application/vnd.resource-

schema+json

Page 67: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

{

"title": "string",

"completed": "boolean",

...

}

Page 68: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

More HTTP goodies...that you don't need to

reinvent

Page 69: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

HTTP Range

GET /rickroll.mp4

Range: bytes=100-99999

Page 70: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

HEAD /posts HTTP/1.1

...

HTTP 200 OK

Accept-Ranges: posts

Page 71: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

GET /posts HTTP/1.1

Range: posts=1-20

Page 72: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

HTTP AuthAlways use protection!

Page 73: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

CachingImplement any invalidationstrategy you can imagine

Page 74: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

PHP?

Page 75: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

nateabele/li3_resources

(on GitHub)

Page 76: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Automatic CRUD manipulation with verbs

Parameter mapping

Links from model relationships

Schemas with OPTIONS

Proxies for mapping database values

Page 77: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Coming soon...Range pagination

Smart search with ?q=...

...Tests (runs away)

Page 78: 2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web

Thanks!