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

10 things you are doing wrong with REST

Joshua Thijssen
September 14, 2013
180

10 things you are doing wrong with REST

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: [email protected] Twitter: @jaytaph
  3. 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. 25 I want to get a Ph.D in webby stuff!

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

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

    ➡ code-on-demand (optional constraint) ➡ uniform interface
  23. ➡ 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
  24. 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
  25. ➡ 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
  26. 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
  27. 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.
  28. 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
  29. 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
  30. 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)
  31. 48 ➡ XHTML ➡ Collection+JSON ➡ HAL ➡ Siren ➡

    Custom type (application/vnd.*+format)
  32. 50 ➡ Hypertext as the engine of application state ➡

    Hypermedia format with not only data, but also specifies operations on that data ➡ (Finite) state machine
  33. 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>
  34. 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>
  35. 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
  36. 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>
  37. 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>
  38. 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
  39. 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>
  40. 65

  41. 68

  42. 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!
  43. 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" } }
  44. 78 text/plain White boat with a johnson 115HP outboard engine.

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

    so your implementation can change. ➡ Happy.
  46. 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
  47. 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" } }
  48. 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" } }
  49. Every time you call your API “RESTful”, Roy Fielding will

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