Upgrade to Pro — share decks privately, control downloads, hide ads and more …

10 things you are doing wrong with REST

1761ecd7fe763583553dde43e62c47bd?s=47 Joshua Thijssen
September 14, 2013
150

10 things you are doing wrong with REST

1761ecd7fe763583553dde43e62c47bd?s=128

Joshua Thijssen

September 14, 2013
Tweet

Transcript

  1. 10 things you are doing wrong with REST 1 PFCongres

    - Utrecht 13-14 september * * almost
  2. Joshua Thijssen Freelance consultant and trainer @ NoxLogic & TechAdemy

    Founder of the Dutch Web Alliance. Development in PHP, Python, Perl, C, Java. Lead developer of Saffire. Blog: http://adayinthelifeof.nl Email: jthijssen@noxlogic.nl Twitter: @jaytaph
  3. http://www.phparch.com/books/mastering-the-spl-library/ PDF, ePub, Mobi, or hardcopy

  4. 4

  5. 5

  6. 6

  7. 7

  8. 8

  9. 9

  10. 10

  11. 11

  12. 12

  13. 13

  14. 14

  15. 15

  16. 16

  17. 17

  18. 18

  19. 19

  20. 20

  21. WORLD WIDE WEB powered by HTTP 0.9 21

  22. HTTP 1.0 (rfc 1945) T. Berners-Lee Roy T. Fielding H.

    Frystyk 22
  23. 23 “This is how we do webby things from now

    on”
  24. Roy T. Fielding 24 (the T stands for kickass)

  25. 25 I want to get a Ph.D in webby stuff!

    Write a dissertation! Here it is! Pass Roy T. Fielding wrote a dissertation:
  26. 26 chapter 5 (rest) Architectural Styles and the Design of

    Network-based Software Architectures
  27. 27 ➡ client-server ➡ stateless ➡ cacheable ➡ layered system

    ➡ code-on-demand (optional constraint) ➡ uniform interface
  28. 28 What’s the hype about REST?

  29. ➡ REST will not make things automatically easier for you.

    ➡ REST is not black magic that solves all your problems. ➡ REST does not mean your API will scale to facebook/twitter sizes. ➡ REST is not even a protocol. 29
  30. ➡ REST is a combination of several architectural styles. ➡

    (LCSS$ + uniform interface) 30
  31. 31 ➡ identification of resources ➡ manipulation of resources through

    representations ➡ self-descriptive messages ➡ hypermedia as the engine of application state URIs HTTP requests & responses HTTP headers & mime types Links inside media types
  32. ➡ (network) visibility ➡ simplicity ➡ better user experience ➡

    scalability ➡ evolvability 32
  33. ➡ REST is (transport) protocol agnostic 33

  34. ➡ GET /article/1234 ➡ PUT /article/1234 ➡ POST /articles ➡

    DELETE /article/1234 34
  35. ➡ RETR /article/1234 ➡ STOR /article/1234 ➡ STOR /articles ➡

    DELE /article/1234 35
  36. ➡ REST provide you the means to create a scalable

    / evolvable API. ➡ That doesn’t automatically make it happen. ➡ If you API is crap, REST won’t help. 36
  37. 37 HTTP APIs. ARE. COOL.

  38. 38 PUT vs POST

  39. 39 ➡ Isn’t a (true) REST problem ➡ HTTP problem

  40. 40 PUT or POST? PUT when the resource URI is

    known POST when it’s not (server decides location) PUT /user/jthijssen/talk/123 POST /user/jthijssen/talks
  41. 41 PUT /user/jthijssen/talk/123 POST /user/jthijssen/talks PUT = idempotent, POST is

    not! PUT /user/jthijssen/talk/123 PUT /user/jthijssen/talk/123 POST /user/jthijssen/talks POST /user/jthijssen/talks POST is the worst option for caching / scalability, but use it if you don’t know what to do.
  42. No hypermedia / HATEOAS 42

  43. hypermedia format? 43

  44. 44 text Once upon a midnight dreary, while I pondered

    weak and weary, Over many a quaint and curious volume of forgotten lore, While I nodded, nearly napping, suddenly there came a tapping, As of some one gently rapping, rapping at my chamber door. `'Tis some visitor,' I muttered, `tapping at my chamber door - Only this, and nothing more.' just data
  45. 45 hypertext Once upon a <a href=”www.midnight.com”>midnight</a> dreary, while I

    pondered weak and weary, Over many a quaint and curious volume of forgotten lore, While I nodded, nearly napping, suddenly there came a <a href=”iwouldtapthat.com”>tapping</a>, As of some one gently <a href=”jayz.com/albums”>rapping</a>, rapping at my chamber door. `'Tis some visitor,' I muttered, `tapping at my chamber door - Only this, and nothing more.' links point to other textual data
  46. 46 hypermedia <poem> <paragraph> Once upon a <a href=”www.midnight.com”>midnight</a> dreary,

    while I pondered weak and weary, Over many a quaint and curious volume of forgotten lore, While I nodded, nearly napping, suddenly there came a <a href=”whotappedthat.com”>tapping</a>, As of some one gently <a href=”jayz.com/albums”>rapping</a>, rapping at my chamber door. `'Tis some visitor,' I muttered, `tapping at my chamber door - Only this, and nothing more.' </paragraph> <link rel=”self” type=”application/pdf” href=”http://edgarallen.poe/raven”> <link rel=”cover-art” type=”image/jpg” title=”cover” href=”raven-bookcover.jpg”> <link rel=”cover-art” type=”image/png” title=”cover” href=”raven-bookcover.png”> <link rel=”audiobook” type=”sound/mp3” title=”audiobook” href=”audiobook-theraven.mp3”> <link rel=”first” href=”http://edgaralen.poe/firstpoem”> <link rel=”next” href=”http://edgaralen.poe/nextpoem”> </poem> links to different types of (hyper)media (hypertext + multimedia)
  47. 47 ➡ HTML, JSON, XML, TEXT. ➡ Not hypermedia.

  48. 48 ➡ XHTML ➡ Collection+JSON ➡ HAL ➡ Siren ➡

    Custom type (application/vnd.*+format)
  49. 49 ➡ My hovercraft is full of eels. ➡

  50. 50 ➡ Hypertext as the engine of application state ➡

    Hypermedia format with not only data, but also specifies operations on that data ➡ (Finite) state machine
  51. 51 pfz airlines

  52. 52 ➡ search tickets ➡ confirm ticket, select seats etc

    ➡ pay your ticket ➡ get e-ticket
  53. 53 POST /search?order=price&limit=5 HTTP/1.1 Host: api.pfz-airlines.com Accept: application/vnd.pfz.flights+xml ; version:

    1.0 <search> <destination>LAS</destination> <date type=”depart”>14-oct-2012</date> <date type=”return”>21-oct-2012</date> <type>firstclass</type> </search>
  54. 54 HTTP/1.1 200 OK Content-type: application/vnd.pfz.flights+xml ; version: 1.0 <flights

    xmlns=...> <flight id=”PF123”> <link rel=”details” action=”/flight/15263” type=”text/xml”> <link rel=”confirm” action=”/confirm/flight/15263” type=”text/xml”> </flight> <flight id=”PF262”> <link rel=”details” action=”/flight/523525” type=”text/xml”> <link rel=”confirm” action=”/confirm/flight/523525” type=”text/xml”> </flight> </flights>
  55. 55 POST /confirm/flight/15263HTTP/1.1 Host: api.pfz-airlines.com Accept: application/vnd.pfz.flights+xml ; version: 1.0

    <flight> <seat>2A</seat> <meal>vegetarian</meal> </flight> HTTP/1.1 401 Authentication required
  56. 56 POST /confirm/flight/15263HTTP/1.1 Host: api.pfz-airlines.com Accept: application/vnd.pfz.booking+xml ; version: 1.0

    Authorization: OAuth ...... <flight> <seat>2A</seat> <meal>vegetarian</meal> </flight> HTTP/1.1 201 Created Location: /booking/1616163 <booking> <booking_id>1616163</booking_id> <link rel=”details” href=”/booking/1616163” type=”application/xml”> <link rel=”payment” href=”/payment/booking/1616163” type=”application/xml”> <link rel=”cancel” href=”/booking/1616163” type=”application/xml”> </booking>
  57. 57 OPTIONS /booking/1616163 HTTP/1.1 Host: api.pfz-airlines.com Authorization: OAuth ...... HTTP/1.1

    200 OK Allow: GET, DELETE, PUT
  58. 58 DELETE /booking/1616163 HTTP/1.1 Host: api.pfz-airlines.com Authorization: OAuth ...... HTTP/1.1

    204 No content
  59. 59 GET /booking/1616163 HTTP/1.1 Host: api.pfz-airlines.com Accept: application/vnd.pfz.booking+xml ; version:

    1.0 Authorization: OAuth... HTTP/1.1 200 OK <booking> <flight> <flightno>PF123</flightno> <time>14:24</time> <link rel=”details” method=”get” href=”/flight/15263”> </flight> <info> <seat>2A</seat> <meal>vegetarian</meal> <inflightentertainment> <movie>Movie that you already saw</movie> <movie>Another movie you don’t care about</movie> <movie>And a chickflic movie, so you don’t want to watch</movie> <serie>Episode of Friends</serie> <serie>Episode of Friends</serie> <serie>Episode of Friends</serie> <serie>Episode of Friends</serie> </inflightentertainment> <link rel=”cancel” href=”/booking/1616163” type=”application/xml”> </info> <payment> <status>Not paid</status> <link rel=”pay” method=”put” href=”/payment/booking/1616163”> <link rel=”details” method=”get” href=”/payment/booking/1616163”> </payment> </booking>
  60. 60 PUT /payment/booking/1616163 HTTP/1.1 Host: api.pfz-airlines.com Accept: application/vnd.pfz.payment+xml ; version:

    1.0 Authorization: OAuth ...... <payment> <cardno>4111-1111-1111-1111</cardno> <expires>04/16</expires> <name>Joshua Thijssen</name> <amount currency=”eur”>514.00</amount> </payment> HTTP/1.1 201 Created Location: /payment/booking/1616163
  61. 61 OPTIONS /booking/1616163 HTTP/1.1 Host: api.pfz-airlines.com Authorization: OAuth ...... HTTP/1.1

    200 OK Allow: GET
  62. 62 GET /booking/1616163 HTTP/1.1 Host: api.pfz-airlines.com Accept: application/vnd.pfz.booking+xml ; version:

    1.0 Authorization: OAuth... HTTP/1.1 200 OK <booking> <flight> <flightno>PF123</flightno> <time>14:24</time> <link rel=”details” method=”get” href=”/flight/15263”> </flight> <info> <seat>2A</seat> <meal>vegetarian</meal> <inflightentertainment> <movie>Movie that you already saw</movie> <movie>Another movie you don’t care about</movie> <movie>And a chickflic movie, so you don’t want to watch</movie> <serie>Episode of Friends</serie> <serie>Episode of Friends</serie> <serie>Episode of Friends</serie> <serie>Episode of Friends</serie> </inflightentertainment> <link rel=”cancel” href=”/booking/1616163” type=”application/xml”> </info> <payment> <status>Paid in full</status> <link rel=”pay” method=”put” href=”/payment/booking/1616163”> <link rel=”details” method=”get” href=”/payment/booking/1616163”> </payment> <link rel=”eticket” method=”get” href=”/eticket/12415156261616”> </booking>
  63. URL construction 63

  64. 64 ➡ Never *EVER* construct URLs directly from code.

  65. 65

  66. 66 url = MAIN_URL + “/” + user_id + “/talks”;

    rc = HTTP.post(url, data);
  67. and now the server changes the location of your talks...

    67
  68. 68

  69. 69 url = data.link_rel(“talks”, user_id); rc = HTTP.post(url, data); Uri

    can change: server, uri, protocol, port etc..
  70. implementation leaks 70

  71. 71 ➡ It’s bad in code, it’s just as bad

    in API’s ➡ Leaking implementation means harder time to change your implementation ➡ Your implementation WILL change over time!
  72. 72 ➡ http://example.org/api.php/article/1234

  73. 73 GET /api/article/1234 HTTP/1.1 Host: example.org Accept: application/json 200 OK

    { "article" : { "id" : 1234, "name" : "red stapler", "price" : 24.99, "category" : "office supplies", "dt_created" : "2013-01-05 12:41:52", "dt_updated" : "2013-01-05 12:41:52" } }
  74. ➡ You are not transmitting resources ➡ You are transmitting

    REPRESENTATIONS of resources 74
  75. GET /boats/pol-5831 75

  76. 76 image/jpg

  77. 77 application/vnd.boat+xml <?xml version="1.0"?> <boat> <color>white</color> <engine> <type>outboard</type> <power>115</power> </engine>

    <capacity>4</capacity> </boat>
  78. 78 text/plain White boat with a johnson 115HP outboard engine.

    There is room for 4 persons. It has been recently washed.
  79. 79 ➡ Don’t leak implementation. ➡ Use (custom) hypermedia formats

    so your implementation can change. ➡ Happy.
  80. JSON only 80

  81. 81 ➡ JSON is not a hypermedia format. ➡ JSON-HAL,

    JSON-LD, Collection+JSON are (but not standardized yet). ➡ A JSON-only API cannot be restful (as it does not use a hypermedia format) ➡ XML-only API is neither RESTful
  82. 82 { "article" : { "id" : 1234, "name" :

    "red stapler", "price" : 24.99, "category" : "office supplies", "dt_created" : "2013-01-05 12:41:52", "dt_updated" : "2013-01-05 12:41:52" } }
  83. 83 { "article" : { "id" : 1234, "name" :

    "red stapler", "price" : 24.99, "price_usd" : 29.99, "price_cad" : 31.99, "category" : "office supplies", "dt_created" : "2013-01-05 12:41:52", "dt_updated" : "2013-01-05 12:41:52" } }
  84. 84 <article id=1234> <name>red stapler</name> <prices> <price currency="eur">24.99</price> <price currency="usd">29.99</price>

    <price currency="cad">31.99</price> </prices> ... }
  85. Every time you call your API “RESTful”, Roy Fielding will

    eat a cat*... 85 * probably not, but you get my point..