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

REST: Not an Intro

REST: Not an Intro

In this session, some common misconceptions about REST are addressed and used as a means to introduce some of the more advanced concepts. Topics include using hypermedia for machine-to-machine interactions, the difference between GET/PUT/POST/DELETE and CRUD, how to (not) do versioning, and why to prefer formats over service interfaces.

Stefan Tilkov

July 03, 2013
Tweet

More Decks by Stefan Tilkov

Other Decks in Technology

Transcript

  1. There is no such thing as a “RESTful URI” example.com

    /customers/delete?id=13 Scheme Path Host Param :// http Opaque ID
  2. Why you shouldn’t care about URIs <customer> <...> <orders href='

    '> </customer> http://example.com/customers/13/orders http://xyz.org/838892AEF28CDAEFD1234/3 Hypermedia context
  3. POST GET PUT DELETE Create Read Update Delete ‣ When

    used for creation, server decides about URI ‣ Can also invoke arbitrary processing ‣ Can also be used for creation with known URI ‣ Not to be used for partial updates, idempotent
  4. GET PUT POST DELETE (+ Representations + URIs + Hypermedia)

    ‣Di erent interface style ‣No change in logic responsibilities
  5. Data Data Access Business Rules Service Logic Service Interface WSDL

    SOAP WS-* XML Operations Parameters Messages HTTP JSON XML Resources Hypermedia Representations
  6. URI Method Meaning http://ex.org/v1/customers POST create new customer http://ex.org/v1/customers/{id} GET

    get customer details http://ex.org/v1/customers{id}/orders GET get list of customer’s details ... ... ... Versions in URIs cause change for no good reason Documented URIs become APIs Assumptions about server details become facts
  7. Postel’s law http://tools.ietf.org/html/rfc761 “TCP implementations should follow a general principle

    of robustness: Be conservative in what you do, be liberal in what you accept from others.”
  8. Don’t break URI structure unnecessarily Evolve via additional resources Support

    older formats Server rules Don’t depend on URI structure Support unknown links Ignore unknown content Client rules
  9. <?xml version="1.0" encoding="UTF-8"?> <serviceDescription xml:base="http://om.example.com"> <link rel="all" href="/orders/" /> <link

    rel="received" href="/orders/received/" /> <link rel="accepted" href="/orders/accepted/" /> <link rel="rejected" href="/orders/rejected/" /> <link rel="cancelled" href="/orders/cancelled/" /> <link rel="fulfilled" href="/orders/fulfilled/" /> <link rel="cancellations" href="/cancellations/" /> <link rel="reports" href="/reports/" /> </serviceDescription> <link rel="fulfilled" href="http://om.archive.com/orders/" /> { "serviceDescription" : { "base": "http://om.example.com", "links": [ { "rel": "all", "href": "/orders/" }, { "rel": "all", "href": "/orders/" }, { "rel": "received", "href": "/orders/received/" }, { "rel": "accepted", "href": "/orders/accepted/" }, { "rel": "rejected", "href": "/orders/rejected/" }, { "rel": "cancelled", "href": "/orders/cancelled/" }, { "rel": "fulfilled", "href": "/orders/fulfilled/" }, { "rel": "cancellations", "href": "/cancellations/" }, { "rel": "reports", "href": "/reports/" } ] } }
  10. JSON Home { "resources": { "http://example.org/rel/widgets": { "href": "/widgets/" },

    "http://example.org/rel/widget": { "href-template": "/widgets/{widget_id}", "href-vars": { "widget_id": "http://example.org/param/widget" }, "hints": { "allow": ["GET", "PUT", "DELETE", "PATCH"], "representations": ["application/json"], "accept-patch": ["application/json-patch"], "accept-post": ["application/xml"], "accept-ranges": ["bytes"] } } } } http://tools.ietf.org/html/dra -nottingham-json-home-03
  11. GET /order/123 { "order": { "date": "2013-07-02", "total": 1240.02, "..."

    : "...", "links" : [ {"rel" : "self", "href" : "http://example.com/orders/123"}, {"rel" : "contacts", "href" : "http://example.org/A3BEF1"}, ... ] } }
  12. GET /order/123 { "order": { "date": "2013-07-02", "total": 1240.02, "..."

    : "...", "links" : { "self": "http://example.com/orders/123", "contacts": "http://example.org/A3BEF1", ... } } } Your future extensions
  13. { "order": { "state" : "received", "..." : "...", "links"

    : [ {"rel" : "cancel", "href" : "http://..."}, {"rel" : "accept", "href" : "http://..."}, {"rel" : "reject", "href" : "http://..."}, ... ] } }
  14. Web Linking (RFC 5988) HTTP/1.1 200 OK Link: <http://om.com/orders/?page=2>;rel="prev" Link:

    <http://om.com/orders/?page=4>;rel="next" HTTP/1.1 200 OK Link: <htt://xyz.com>;rel="http://example.com/rels/own" Link: <http://xyz.com>;rel="prev" Link: <http://xyz.com>; rel="http://www.iana.org/assignments/relation/prev"
  15. <form action='http://example.com/search' method='GET'> Search for: <input type='text' name='query'> <input type='submit'>

    </form> { "rel": "search", "template": "http://example.com/search?q={query}" }
  16. <form action='http://example.com/add' method='POST'> First: <input type='text' name='first'> Last: <input type='text'

    name='last'> Birthday: <input type='date' name='bdate'> <input type='Add'> </form> {"target": "http://example.com/add", "rel": "add", "template": { "first": "...", "last": "...", "bdate": "..." } }
  17. <order> <shippingAddress>Paris, France</shippingAddress> <items> <item> <productDescription>iPad</productDescription> <quantity>1</quantity> <price>699</price> </item> </items>

    <link href="http://om.example.com/cancellations" rel="cancel" /> <link href="https://om.example.com/orders/123/payment" rel="payment" /> </order>
  18. <html xmlns="http://www.w3.org/1999/xhtml"> <body> <div class="order"> <p class="shippingAddress">Paris, France</p> <ul class="items">

    <li class="item"> <p class="productDescription">iPad</p> <p class="quantity">1</p> <p class="price">699</p> </li> </ul> <a href="http://om.example.com/cancellations" rel="cancel">cancel</a> <a href="https://om.example.com/orders/123/payment" rel="payment">payment</a> </div> </body> </html>
  19. <div> <h1>Avatar</h1> <span>Director: <span>James Cameron</span> (born August 16, 1954)</span> <span>Science

    fiction</span> <a href="../movies/avatar-theatrical-trailer.html"</a> </div>
  20. <div itemscope itemtype="http://schema.org/Movie"> <h1>Avatar</h1> <span>Director: <span>James Cameron</span> (born August 16,

    1954)</span> <span>Science fiction</span> <a href="../movies/avatar-theatrical-trailer.html"</a> </div>
  21. <div itemscope itemtype="http://schema.org/Movie"> <h1 itemprop="name">Avatar</h1> <span>Director: <span itemprop="director">James Cameron</span> (born

    August 16, 1954)</span> <span itemprop="genre">Science fiction</span> <a href="../movies/avatar-theatrical-trailer.html" itemprop="trailer">Trailer</a> </div>
  22. Q&A Stefan Tilkov, @stilkov [email protected] Phone: +49 170 471 2625

    innoQ Deutschland GmbH Krischerstr. 100 40789 Monheim am Rhein Germany Phone: +49 2173 3366-0 innoQ Schweiz GmbH [email protected] Gewerbestr. 11 CH-6330 Cham Switzerland Phone: +41 41 743 0116 www.innoq.com Ohlauer Straße 43 10999 Berlin Germany Phone: +49 2173 3366-0 Robert-Bosch-Straße 7 Germany Phone: +49 2173 3366-0 Radlkoferstraße 2 D-81373 München Telefon +49 (0) 89 741185-270