Home > front end >  RESTful way to convert between orders and carts
RESTful way to convert between orders and carts

Time:10-29

A) When the content of a shopping cart is purchased the cart is copied to a fixed order and the cart is deleted.

B) If a placed order will be changed a shopping cart is created that allows for editing of the order. (Cancellations may result in cancellation fees). When the changes are accepted the changes are transferred from the cart to the order. The cart will be deleted again.

I'm struggling to model those state changes in a RESTful API using resources? How would I express the changes of the resources? Purchasing the cart content deltes the cart and creates a new one. Here are some ideas...

a) Creating the order:

POST Orders?cart=cartId or PATCH Cart/:id {status: purchased}

(the response would hold the link to Orders/:newid)

b) Saving the updated cart of an existing order:

PUT Orders/:id?cart=cartId or PATCH Cart/:id {status: changeConfirmed} or PUT Orders/:id/:cartID

CodePudding user response:

Heuristic: think about how you would do it on the web.

  1. You are looking at a web page that describes the contents of your shopping cart. On that same page is a "Place Order" form. When you submit that form, the browser sends an HTTP POST request to your web server, targeting whichever resource was described by the form's action metadata. This triggers some business activity behind your HTTP facade, manipulating the shopping cart and order entities in your domain model.

  2. You are looking at a web page that describes your order. On that same page is an "Edit Order" form. When you submit that form, the browser sends an HTTP POST request to your web server, targeting whichever resource was described by the forms action metadata. This triggers some business activity behind your HTTP facade, manipulating the shopping card and order entities in your domain model.

That's REST.

The request targets can be anything you want; but the general purpose transfer of documents over a network uses request targets for caching, and cache invalidation. That means if you choose your request targets cleverly, you can ensure that successful requests invalidate stale copies of resources.

For your first example, the obvious resource that would be changed by the Place Order request is the shopping cart resource itself, so that's a reasonable first guess at what the form action should be.

In the second example, the order resource is a reasonable first guess.


Does it have to be POST? No - you can use PUT instead with similar effect; the client sends edited copies of the resources back to the server (PUT) and then the server triggers the business activities.

(PATCH is an alternative to PUT, where instead of sending the entire document, we send a description of the edits in a form that the server has advertised that it understands; for resources with JSON representations, we'd normally use something like JSON Patch or JSON Merge Patch).


Creating the order

PATCH /Cart/12345 HTTP/2
Content-Type: application/merge-patch json

{ "status": "purchased" }

Saving the updated cart of an existing order

PATCH /Cart/12345 HTTP/2
Content-Type: application/merge-patch json

{"status": "changeConfirmed" }

Both perfectly reasonable. PUT - including an entire copy of the /Cart/12345 representation with the changes - might be a better answer if that document isn't too big (compared to the HTTP headers): requests with idempotent semantics can be retried if an HTTP response is lost on an unreliable network.

Note that the HTTP method and request target can be the same even though the intent is to trigger two different business activities. That's perfectly normal in REST (but not necessarily common - your server's HTTP routing framework probably won't be able to discriminate between the two cases, so you'll have to write some bespoke code to trigger the correct activities).

  •  Tags:  
  • rest
  • Related