2. Sample REST API for “more than CRUD”
Examples
Shopping Cart
Book printing
3. Shopping cart
Create a new cart
Obtain its contents
Add an item
Remove an item
Empty the cart
Calculate full charges
Proceed to checkout
4. Base URI
Cart as top level resource
http://example.org/carts/
Or
Cart as sub resource of user
http://example.org/users/{id}/cart
5. Creating a cart
Cart as top level resource
POST example.org/carts/
Would return a new cart resource URI
201 Created
Location: http://example.org/carts/123
Cart as sub resource of user
Not necessary, cart is already available
http://example.org/users/{id}/cart
6. Obtain the content of the cart
Issue a GET to the resource
GET /carts/{id}
or
GET /users/{id}/cart
On begining, would return a representation of the empty cart
200 Ok
{itens: []}
Otherwise would return the current content of the cart
200 Ok
{itens: [{id:..., qty:...}, ...]}
7. Add an item
PUT an updated representation of the entire cart
PUT /carts/{id}
{itens: [{id: ..., qty: ...},{id: ..., qty: ...}]}
Or
Treat the cart as a collection and POST a new item
POST /carts/{id}/itens
{id: ..., qty: ...}
Would return the URI of the newly added item
201 Created
Location: http://example.org/carts/123/itens/456
8. Remove an item
PUT an updated representation of the entire cart
PUT /carts/{id}
{itens: [{id: ..., qty: ...}]}
Or
Treat the cart as a collection and DELETE an item
DELETE /carts/{id}/itens/{itemid}
9. Empty the cart
PUT an updated representation of the empty cart
PUT /carts/{id}
{itens: []}
Or
Treat the cart as a collection and DELETE the itens
DELETE /carts/{id}/itens
10. Calculate full charges
If the calculation is transitory, just GET the result of the calculation
GET /carts/{id}/fullcharges
or
GET /users/{id}/cart/fullcharges
Would return
{itens: 100, taxes: 23, shipping: 12, total: 140, currency:
EUR}
Or an updated shopping cart representation with charges element
{itens: [...], charges: {...}}
This element should be considered transient and not part of the resource
Former approach is “better” as it is a separate resource
11. Calculate full charges (2)
If charges are to be considered a persistent part part of the
resource
By doing the calculation you are in fact changing the resource
i.e., Have side effect, so GET is to be avoided
POST the request for the calculation,
e.g.
POST /carts/{cid}
{fullcharges: yes}
Would return updated shopping cart
{itens: [...], charges: {...}}
12. Procceed to checkout
POST an order with the content of the shopping cart?
GET /carts/{id}/as-order
POST /orders
Or
POST to a check-out controller?
POST /carts/{id}/checkout
or
POST /checkout?cart={id}
or
POST /salesprocess/checkout
14. Book printing example
Download a pdf representation of a book for
printing at the client
GET /books/{id}?template={tmpl}
Accept: application/pdf
15. Book printing example
Print a book (at the server)
POST /books/{id}/print?printer=hp01
In fact what we want is to order a printing service...
POST /printorders/
{what: “/books/{id}”, quality: ..., ... }
202 Accepted
Location: /printorders/3Af42X
Not very
beatiful
16. Book printing example
Query the status
GET /printorders/{id}
200 Ok
{status = “pending”, ...}
17. Book printing example
Cancel the printing order
DELETE /printorders/{id}
200 Ok
If the order could not be deleted anymore
(e.g., already printing), the service would
return a 405 Method Not Allowed