2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando las reglas de la Web
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

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

on

  • 3,807 views

PHP Conference Argentina 2013

PHP Conference Argentina 2013

Statistics

Views

Total Views
3,807
Views on SlideShare
3,807
Embed Views
0

Actions

Likes
0
Downloads
2
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

  • 1. HTTP ALL THE THINGS Simplifying Rich Applications by Respecting the Rules of the Web
  • 2. Me Nate Abele Former lead developer, CakePHP Founder & current lead developer, Lithium Member, AngularUI @nateabele
  • 3. History
  • 4. 1998: SOAP & XMLRPC
  • 5. 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>
  • 6. Or...
  • 7. XML-RPC <?xml version="1.0"?> <methodCall> <methodName>examples.getStateName</methodName> <params> <param> <value><i4>40</i4></value> </param> </params> </methodCall>
  • 8. :-( POST * Invocaction details in body Format lock-in No relationships No discoverability
  • 9. 2000: REST
  • 10. REST Constraints Client-Server Stateless Cacheable Uniform Interface Opaque Layering Code-on-Demand
  • 11. The 4 Levels RPC over HTTP (i.e. SOAP) Resources Verbs Hypermedia Controls
  • 12. Now: Hypermedia / HATEOAS
  • 13. ¿Hypermedia? Content negotiation State traversal
  • 14. Content negotiation application/json ...?
  • 15. Content negotiation application/json FALE
  • 16. Content negotiation Better: application/rss+xml
  • 17. Content negotiation application/vnd.twitter.stream+json // I can decode this! json_decode() /** * I can understand this ! */ class Tweet { protected $username; protected $text; // ... }
  • 18. State traversal
  • 19. Client: “What's next?”
  • 20. We already do this!
  • 21. Browsers <link rel="stylesheet" href="/css/app.css" /> <link rel="next" href="/next" /> <link rel="alternate" type="application/rss+xml" href="/posts.rss" />
  • 22. Users (with the help of browsers) <a href="/next" />Next</a> <form></form>
  • 23. Atom? <link rel="foo" type="text/foo" href="http://foo" />
  • 24. 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"} } }]
  • 25. Why?
  • 26. AngularJS
  • 27. Valid alternatives EmberJS KnockoutJS Backbone (kind of, not really)
  • 28. AngularJS Higher level of abstraction Simple, well-designed architecture Ridiculously simple unit testing
  • 29. Event binding
  • 30. Event binding jQuery <input type="text" id="name" /> <h1>Hello!</h1> <script type="text/javascript"> $(document).ready(function() { $('#name').keydown(function(e) { $('h1').html("Hello " + e.target.value + "!") }); }); </script>
  • 31. Event binding AngularJS <input type="text" ng-model="name" /> <h1>Hello {{ name }}!</h1> Hello !
  • 32. Iteration jQuery <ul class="greetings"></ul> <script type="text/javascript"> $(["Hello", "Hola", "Ciao"]).each(function(k, v) { $(".greeting").append("<li>" + v + " World</li>" }); </script>
  • 33. Iteration AngularJS <ul> <li ng-repeat="greet in ['Hello', 'Hola', 'Ciao']"> {{ greet }} World </li> </ul> Hello World Hola World Ciao World
  • 34. <ul> <li ng-repeat="greet in ['Hello', 'Hola', 'Ciao']"> {{ greet }} World </li> </ul> Hello World Hola World Ciao World
  • 35. Organization AngularJS Item: Qty: 0 Price: 0 Total: $0.00 Total: $0.00
  • 36. Organization AngularJS <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>
  • 37. Organization AngularJS 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; }); }; }
  • 38. Organization jQuery ¿Ummm...?
  • 39. Organization jQuery *shrug*
  • 40. Testability AngularJS 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); }); }); });
  • 41. Testability AngularJS 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); }); }); });
  • 42. ¿jQuery...?
  • 43. AngularJS + HTTP Resources
  • 44. $resource()
  • 45. 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();
  • 46. /* GET /tasks/5 */ var oneTask = Task.get({ id: 5 }); /* GET /tasks?completed=false&due=1381158984 */ var current = Task.query({ completed: false, description: "..." });
  • 47. ¡Muy mal! ¡No me gusta! ¡Eso es shinaniganos!
  • 48. Tight coupling Client-side URL templates Excessive parameters No links!
  • 49. Intent
  • 50. /tasks? completed=false &due=1381158984
  • 51. No meaning
  • 52. /tasks/current
  • 53. /tasks/:id
  • 54. $resource("/posts/:id", {id: "@id"}); { id: 5, title: "Something New", slug: "something-new" }
  • 55. /posts/something-new ...?
  • 56. What to do?
  • 57. uor/angular-model (on GitHub) * * Current code is old and broken, new release coming tomorrow
  • 58. modelProvider.model("Tasks", { $instance: { finish: function() { this.completed = true; return this.$save(); }, isCompleted: function() { return !!this.completed; } } });
  • 59. Where's the URL?
  • 60. 3 options
  • 61. Automatic: /tasks
  • 62. <link rel="resource" name="Tasks" href="<?=$this->url('Tasks'); ?>" />
  • 63. GET / Accept: application/vnd.resource-def+json
  • 64. { "Tasks": "http://my.app/tasks", "Users": "http://my.app/users" }
  • 65. OPTIONS /tasks Accept: application/vnd.resourceschema+json
  • 66. { "title": "string", "completed": "boolean", ... }
  • 67. More HTTP goodies ...that you don't need to reinvent
  • 68. HTTP Range GET /rickroll.mp4 Range: bytes=10099999
  • 69. HEAD /posts HTTP/1.1 ... HTTP 200 OK Accept-Ranges: posts
  • 70. GET /posts HTTP/1.1 Range: posts=1-20
  • 71. HTTP Auth Always use protection!
  • 72. Caching Implement any invalidation strategy you can imagine
  • 73. PHP?
  • 74. nateabele/li3_resour ces (on GitHub)
  • 75. Automatic CRUD manipulation with verbs Parameter mapping Links from model relationships Schemas with OPTIONS Proxies for mapping database values
  • 76. Coming soon... Range pagination Smart search with ?q=... ...Tests (runs away)
  • 77. Thanks!