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

REST in practice - PHPTwente meetup

Joshua Thijssen
March 07, 2013
160

REST in practice - PHPTwente meetup

Joshua Thijssen

March 07, 2013
Tweet

Transcript

  1. PHPTwente, Enschede
    7 maart 2013
    REST
    in practice?
    How to deal with

    View Slide

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

    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?
    ➡ Depends....
    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? (tip: blame client!)
    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/
    ➡ HAL http://stateless.co/hal_specification.html
    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
    “This information is of no concern to
    you. Just bring it with you every time.. ”

    View Slide

  51. 51
    “This information is of no concern to
    you. Just bring it with you every time.. ”
    Are we still stateless?
    Does the server use the client as an (extended) file storage?
    Why doesn’t the client have any say in what to send?

    View Slide

  52. ➡ 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.
    52

    View Slide

  53. 53
    Querying for data

    View Slide

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

    View Slide

  55. 55
    Pagination

    View Slide

  56. 56

    View Slide

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

    View Slide

  58. 58
    /restaurants/top1000?page=5


    ...
    ...






    View Slide

  59. 59
    Applying hierarchy

    View Slide

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

    View Slide

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

    View Slide

  62. 62
    /distance/amsterdam;brussels
    /distance/brussels;amsterdam
    HTTP/1.1 303 See other
    Location: /distance/amsterdam;brussels
    Parameters, order does not matter:
    One cache system:
    http://cyberroadie.wordpress.com/2012/01/05/varnish-reordering-query-string/

    View Slide

  63. 63
    Asynchronous updates

    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

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

    View Slide

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

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


    Pending
    10 minutes


    Asynchronous updates - waiting in queue

    View Slide

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


    In progress
    3 minutes, 25 seconds

    Asynchronous updates - in progress

    View Slide

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

    View Slide

  69. 69
    Transactions

    View Slide

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

    View Slide

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

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

    View Slide

  73. 73
    A transaction can been as a resource

    View Slide

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

    View Slide

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

  76. 76
    POST /transactions/55A50611FE
    POST /transactions/55A50611FE/commit
    POST /transactions/55A50611FE/rollback
    POST /transactions/55A50611FE/snapshot
    POST /transactions/55A50611FE/rollback/1
    So, define services:
    POST /booking

    10.000.000
    12.34.56.789, my bank
    X5252P25, Cayman Islands

    View Slide

  77. 77
    ➡ 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

  78. 78
    ➡ Take into account that you probably are not
    building the next Twitter API.
    ➡ If you follow the REST constraints, at least
    your API can scale.

    View Slide

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

    View Slide

  80. 80
    https://leanpub.com/restfulapis
    It’s almost finished!

    View Slide

  81. Techademy Workshopdag
    81
    Aanmeldingen: [email protected]
    Workshopdag:
    Varnish + PHP Speedups
    vrijdag 22 maart - Apeldoorn
    php5.[34] + http essentials, gearman + activemq,
    solr + solarium, html5+css3, mongodb + caching, scrum,
    git+github+travisCI, phpdocumentor

    View Slide

  82. Thank you
    82
    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