Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST API with multiple commands per resource

Tags:

rest

http

api

I have a question regarding REST API design. Here is a simple (maybe too simple) API:

GET /ecommerce/order/123

POST /ecommerce/order (create a new order)

PUT /ecommerce/order/123 (update an existing order)

DELETE /ecommerce/order/123 (cancel order)

But what if I wanted the customer to enter a reason for an order to be cancelled? I would need to send post data to the API, but that wont work with DELETE. To cater for this the I would have to change DELETE to PUT. I would then post two different resources for update and cancel.

Another solution would be to change the API:

GET /ecommerce/order/123

POST /ecommerce/order/create (create a new order)

PUT /ecommerce/order/update/123 (update an existing order)

DELETE /ecommerce/order/cancel/123 (cancel order)

I'm not sure which is the best option.

There is a more general question about how REST API's handle multiple commands for a single resource.

Any input would be appreciated! I'm going to be reading REST in Practice very soon but this question is niggling away at me.

like image 635
Junior Developer Avatar asked Jun 13 '11 20:06

Junior Developer


2 Answers

One option might be to create a new resource. CancelledOrder, perhaps.

You might then POST a new CancelledOrder:

POST /ecommerce/cancelledOrder
Entity:
    order: /ecommerce/order/123
    reason: "Problem with order"

You could also/instead PUT a CancelledOrder:

PUT /ecommerce/cancelledOrder/123
Entity:
    reason "Problem with order"

The application could then delete order 123 or update its status to "Cancelled", or do whatever it is your business rules require. To top it off, you could then not support the DELETE method directly for /ecommerce/order/N, returning a 405 Method Not Allowed.

The PUT solution can use idempotence to its advantage; PUTting the CancelledOrder multiple times would always still result in the order being cancelled.

It should be noted that your suggestions for changing the API (e.g. /ecommerce/order/create) are likely not to be RESTful, since you're defining methods in the resource identifiers.

like image 169
Rob Hruska Avatar answered Sep 28 '22 01:09

Rob Hruska


I know this is a very late answer, but I suggest to use the first set of commands, but change the cancel order command to:

POST /ecommerce/order/123/cancel

Which is a generic way to handle various operations on an existing resource. I don't see why an order cancellation would lead to deletion of the order itself, at least not instantly. The users would probably still want to see the order in the system. The order is also where you would store the reason for the cancellation.

like image 32
Thomas Emil Hansen Avatar answered Sep 28 '22 00:09

Thomas Emil Hansen