ShaunP
ShaunP

Reputation: 473

Verbs in a RESTFUL (hypermedia) API

I'm having some trouble with RPC style verbs starting to appear in my API.

My question is: Is it okay to have these verbs, "Submit", "SendForApproval", "Accept" and "Reject" in a Restful API? Is that going against the Restful principles? What's best practice for naming these Actions?

Our business case: I have an order. It starts out at status "pre-ordered". I want to then make a call to validate the order against our business logic. Depending on the validation results, I then either submit it or send it for approval. The approval process happens externally to our solution and then when it has been through the approval process the Api is called to mark the order as either Accepted or Rejected.

There is a bit more going on than simply updating statuses - we send things to print queues, spin off tracking documents etc.

So the URI's that we have defined are

https://api.site.com/orders               // A list of orders
https://api.site.com/orders/{orderId}     // An order
https://api.site.com/orders/{orderId}/ValidationErrors   // Get a list of validation results
https://api.site.com/orders/{orderId}/Submit             // Submit the order for processing
https://api.site.com/orders/{orderId}/SendForApproval    // Send to supervisor
https://api.site.com/orders/{orderId}/Accept             // Supervisor Accepts the order for processing
https://api.site.com/orders/{orderId}/Reject             // Supervisor can Reject the order

Upvotes: 1

Views: 298

Answers (3)

Marlon
Marlon

Reputation: 898

You must avoid inserting verbs in your URIs as much as you possibly can. Furthermore, I disagree with user1438038, because the QueryString filters should be used for search purposes instead of specifying actions.

I believe that there're better approaches to solve this problem. First off, take into account that you shouldn't model your RESTful API in a way that it's highly tied to your business objects (supposing that you're using a OO approach). Moreover, remember that in a REST perspective, everything you expose is a resource rather than objects with its state and behavior.

I'm going to suggest you a different approach but I'm not sure if it's going to fulfill your system requirements but maybe it can be useful to give you some ideas. In your case, you can have multiple resources like PreOrders, Orders, Supervisors...

https://api.site.com/preorders

GET - Display all pre-orders.
POST - Create a new pre-order.

Creating a new order:

https://api.site.com/preorders/1 

POST - approves the pre-order. This action's gonna create a new Order.

Displaying all orders that are waiting for approval (by the supervisor with ID=1).

https://api.site.com/supervisors/1/orders

Searching for approved and canceled orders:

https://api.site.com/supervisors/1/orders?status=canceled
https://api.site.com/supervisors/1/orders?status=approved

To cancel or approve an order:

https://api.site.com/supervisors/1/orders/1 (DELETE cancels the order)
https://api.site.com/supervisors/1/orders/1 (POST approves the order)

I'm unsure if it's the best approach to solve your problem but I'm pretty sure it's better than using verbs in your URI.

Upvotes: 3

Juan de Parras
Juan de Parras

Reputation: 778

Not is a good practice have verbs in REST uris.

So, if you want change a status in any order, you may send a PUT/POST to https://api.site.com/orders/{orderId} updating only the values you want for your bussines logic.

Upvotes: 0

user1438038
user1438038

Reputation: 6059

I'd be fine with that, we are using a very similar setup for order management.

However, another possibility would be passing an action parameter, such as:

https://api.site.com/orders/{orderId}/?action=accept
https://api.site.com/orders/{orderId}/?action=reject
...

The general idea of REST is to have resources (such as order or customer). What you want is more of a RPC semantics, but there is no right or wrong. Your approach is reasonable.

Upvotes: 1

Related Questions