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

REST in practice - Dutch PHP Conference - June 2012

REST in practice - Dutch PHP Conference - June 2012

Joshua Thijssen

June 09, 2012
Tweet

More Decks by Joshua Thijssen

Other Decks in Technology

Transcript

  1. DPC Uncon
    REST
    in practice?
    How to deal with

    View Slide

  2. Joshua Thijssen / Netherlands
    Freelance consultant, developer and
    trainer @ NoxLogic / Techademy
    Development in PHP, Python, Perl,
    C, Java....
    Blog: http://adayinthelifeof.nl
    Email: [email protected]
    Twitter: @jaytaph
    2

    View Slide

  3. REST
    3
    Representational State Transfer
    It’s not hard: like poker, or chess

    View Slide

  4. 4
    ➡ Quick REST recap
    ➡ Common “myths”
    ➡ Common “mistakes”
    ➡ How to do stuff
    @Todo:

    View Slide

  5. 5
    Quick REST recap

    View Slide

  6. 6
    Are you doing REST?

    View Slide

  7. Restful constraints
    7
    ➡ Client / Server
    ➡ Stateless
    ➡ Cacheable
    ➡ Layered system
    ➡ Code on demand (optional)
    ➡ Uniform interface

    View Slide

  8. Uniform interface
    8
    ➡ Identification through representations of
    resources
    ➡ Manipulation through representations
    ➡ Self-descriptive messages
    ➡ Hypermedia as the engine of application state
    (HATEOAS)

    View Slide

  9. Are you mature enough?
    9
    (according to Richardson)

    View Slide

  10. 10
    http://martinfowler.com/articles/richardsonMaturityModel.html

    View Slide

  11. 11
    http://martinfowler.com/articles/richardsonMaturityModel.html
    Level 0: Plain Old XML
    ➡ HTTP is tunnel protocol
    ➡ POST to single URL (or worse: GET)
    ➡ SOAP / XML-RPC

    View Slide

  12. 12
    http://martinfowler.com/articles/richardsonMaturityModel.html
    Level 1: Resources
    ➡ Entities are resources
    ➡ /user/jthijssen instead of /users
    ➡ /user/jthijssen/talks

    View Slide

  13. 13
    http://martinfowler.com/articles/richardsonMaturityModel.html
    Level 2: HTTP Verbs
    ➡ POST or PUT for creations
    ➡ GET for retrievals
    ➡ POST or PUT for updates
    ➡ DELETE for deletions
    ➡ PATCH for partial updates

    View Slide

  14. 14
    http://martinfowler.com/articles/richardsonMaturityModel.html
    Level 3: Hypermedia controls
    ➡ HATEOAS
    ➡ Hypermedia as the engine of application state
    ➡ Using links to detect your next states
    ➡ One bookmark link to rule them all

    View Slide

  15. 15
    Wait, wut?
    Let’s go to DisneyLand!

    View Slide

  16. 16
    Are you (still) doing REST?

    View Slide

  17. 17
    Common “myths”

    View Slide

  18. REST == HTTP
    18

    View Slide

  19. REST == CRUD
    19

    View Slide

  20. URL’s are important
    20

    View Slide

  21. REST scales
    21

    View Slide

  22. COOKIES are EVIL
    22

    View Slide

  23. 23
    I’ve never have eaten a cookie in my life...

    View Slide

  24. 24
    Gimme moar cookies! Om nom nom!

    View Slide

  25. 25
    Application state
    vs
    Resource state

    View Slide

  26. ➡ User has got multiple addresses
    ➡ Entity X/Y/Z is set to 42
    26
    Resource state
    Resource state never changes through GET
    (or other safe) methods!

    View Slide

  27. ➡ Which “stage” is the user in the checkout
    process?
    ➡ Which page is the user currently browsing
    ➡ Is the user currently logged in?
    27
    Application state

    View Slide

  28. 28
    “Per client” state should be saved by the client,
    not on the server.
    It’s called Representational STATE TRANSFER

    View Slide

  29. 29
    Common “mistakes”

    View Slide

  30. 30
    PUT or POST?
    PUT when the resource URI is known
    POST when it’s not (server decides)
    PUT /user/jthijssen/talk/123
    POST /user/jthijssen/talks

    View Slide

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

    View Slide

  32. 32
    url = data.link_rel(“talks”, user_id);
    rc = HTTP.post(url, data);
    url = MAIN_URL + “/” + user_id + “/talks”;
    rc = HTTP.post(url, data);
    Uri can change: server, uri, protocol, port etc..
    If you need to “construct” an URI, you are doing it wrong

    View Slide

  33. 33
    Composite resources

    View Slide

  34. Watch out with visibility
    34



    Joshua Thijssen
    0612345678


    ...

    View Slide

  35. Watch out with visibility
    35



    Joshua Thijssen
    0612345678

    Mainstreet 1234
    1234AB
    Amsterdam
    Netherlands



    ...

    View Slide

  36. Watch out with visibility
    36
    person
    address
    person address address
    Duplicated cache!

    View Slide

  37. ➡ Degrades resource visibility since they
    contain overlapping data
    ➡ Use caching proxies! (maybe ESI???)
    ➡ Each client needs a different composite.
    37

    View Slide

  38. 38
    It sounded like a good idea at the time...

    View Slide

  39. ➡ Use HTTP (verbs) wisely
    ➡ Etags / If-(not-)modified
    ➡ HTTP codes
    39

    View Slide

  40. ➡ HTTP 1xx : Do I got info for you!
    ➡ HTTP 2xx : We’re cool..
    ➡ HTTP 3xx : Take a look there..
    ➡ HTTP 4xx : your bad!
    ➡ HTTP 5xx : my bad!
    40

    View Slide

  41. ➡ Sometimes hard:
    ➡ 405 Method not allowed
    ➡ 501 Not implemented
    ➡ Who is to blame?
    41

    View Slide

  42. 42
    HTTP/1.1 200 Ok

    my-superduper-code-nobody-understands
    This action is forbidden

    Don’t return OK when it’s not:

    View Slide

  43. ➡ Use a hypermedia format (xhtml / atom)
    ➡ JSON is NOT a hypermedia format
    ➡ JSON-LD http://json-ld.org/
    43

    View Slide

  44. 44
    How to do stuff

    View Slide

  45. How do I login into my API?
    45

    View Slide

  46. You don’t
    46

    View Slide

  47. 47
    Cookie
    PHPSESSID: 1234ABCD
    PHPSESSID: 1234ABCD
    LoggedIn: true
    User: 52
    IsAdmin: false
    Client Server

    View Slide

  48. 48
    Cookie
    Loggedin: true
    User: 52
    IsAdmin:false
    Client Server

    View Slide

  49. 49
    Cookie
    Loggedin: true
    User: 52
    IsAdmin: true
    Client Server

    View Slide

  50. 50
    Cookie:
    0xEncryptedData
    Client Server

    View Slide

  51. ➡ Authenticate / Authorize per request.
    ➡ Caching is possible, just don’t rely on it.
    ➡ If you need state, make sure it’s resource
    state, not session/application state.
    51

    View Slide

  52. 52
    Querying for data

    View Slide

  53. 53
    /entities/search?
    what=restaurants&type=italian&postalcode=1234AB&radius=5000&sor
    t=rating&order=desc
    /restaurants/italian/top10?postalcode=1234AB&radius=5000

    View Slide

  54. 54
    Pagination

    View Slide

  55. 55

    View Slide

  56. 56
    /restaurants?page=5
    /restaurants?page=635

    View Slide

  57. 57
    /restaurants/top1000?page=5


    ...
    ...






    View Slide

  58. 58
    Applying hierarchy

    View Slide

  59. 59
    /directions/brussels/amsterdam
    Not everything implies an hierarchy:

    View Slide

  60. 60
    /directions/brussels,amsterdam
    /directions/amsterdam,brussels
    Parameters, order does matter:
    /directions?from=brussels&to=amsterdam
    /directions?from=amsterdam&to=brussels

    View Slide

  61. 61
    /distance/amsterdam;brussels
    /distance/brussels;amsterdam
    HTTP/1.1 303 See other
    Location: /distance/amsterdam;brussels
    Parameters, order does not matter:
    One cache system:

    View Slide

  62. 62
    Asynchronous updates

    View Slide

  63. 63
    POST /blogs HTTP/1.1
    Content-type: application/vnd.myblog.article+xml ; version=1.0


    My blogpost
    John Doe
    This is the content for my blog article

    Synchronous updates
    HTTP/1.1 201 Created
    Location: /blog/20010101-myblogpost

    View Slide

  64. 64
    POST /blogs HTTP/1.1
    Content-type: application/vnd.myblog.article+xml ; version=1.0


    My blogpost
    John Doe
    This is the content for my blog article

    Asynchronous updates
    HTTP/1.1 202 Accepted
    Location: /queue/621252

    View Slide

  65. 65
    GET /queue/621252 HTTP/1.1
    HTTP/1.1 200 OK


    Pending
    10 minutes


    Asynchronous updates - waiting in queue

    View Slide

  66. 66
    GET /queue/621252 HTTP/1.1
    HTTP/1.1 200 OK


    In progress
    3 minutes, 25 seconds

    Asynchronous updates - in progress

    View Slide

  67. 67
    GET /queue/621252 HTTP/1.1
    Asynchronous updates - done
    HTTP/1.1 303 See Other
    Location: /blog/20010101-myblogarticle

    View Slide

  68. 68
    Transactions

    View Slide

  69. 69
    Don’t make transactions
    through multiple resources.
    Breaks the state constraint
    (plus the rest of the the internet)

    View Slide

  70. 70
    POST /account/1234?amount=-100
    TransIDX: 55A50611FE
    HTTP/1.1 202 Accepted
    POST /account/4567?amount=+100
    TransIDX: 55A50611FE
    HTTP/1.1 202 Accepted
    POST /commit
    TransIDX: 55A50611FE
    Nope! This is state!

    View Slide

  71. 71
    A transaction can been as a resource

    View Slide

  72. 72
    POST /transactions
    201 Created
    Location: /transactions/55A50611FE
    Create a new transaction
    Another attempt:

    View Slide

  73. 73
    POST /transactions/55A50611FE
    POST /transactions/55A50611FE/commit
    POST /transactions/55A50611FE/rollback
    POST /transactions/55A50611FE/snapshot
    POST /transactions/55A50611FE/rollback/1
    But now we are back to XML-RPC or worse..

    View Slide

  74. 74
    POST /transactions/55A50611FE
    POST /transactions/55A50611FE/commit
    POST /transactions/55A50611FE/rollback
    POST /transactions/55A50611FE/snapshot
    POST /transactions/55A50611FE/rollback/1
    Define services:
    POST /booking

    10.000.000
    12.34.56.789, my bank
    X5252P25, Cayman Islands

    View Slide

  75. 75
    Your API is not a RDBMS.
    The internet does not need more ACID.

    View Slide

  76. 76
    ➡ If you do REST, don’t break the constraints.
    ➡ Be realistic about the constraints
    ➡ XML-RPC, HTTP-services (even SOAP) are
    valid for their uses.
    This stuff is hard!

    View Slide

  77. 77
    ➡ Take into account that you probably are not
    building a new twitter API.
    ➡ If you follow the REST constraints, at least
    your API can scale.

    View Slide

  78. http://farm1.static.flickr.com/73/163450213_18478d3aa6_d.jpg
    Questions?
    78

    View Slide

  79. Please rate this talk on joind.in:
    http://joind.in/6466
    Thank you
    79
    Find me on twitter: @jaytaph
    Find me for development or training: www.noxlogic.nl
    Find me on email: [email protected]
    Find me for blogs: www.adayinthelifeof.nl

    View Slide