Reputation: 473
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
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
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
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