anybody doing non-trivial things with REST sooner or later runs into interactions beyond the simple CRUD (create/read/update/delete) operations. there often are cases where operations might be tied to a specific resource (or mainly to that resource), and then the question is how model this in a RESTful way. a pattern that is seen frequently is the
action URI, which is a URI that specifically represents one action on one resource.
for example, if there is an open order
https://example.com/order/42, then the
payment action will be represented at the URI
https://example.com/order/42/payment. clients will interact with that by using either PUT or POST (PUT seems to be the preferred way) to submit a payment.
this clearly works, as demonstrated by many existing APIs, but is it really the best or only way of doing it? there are some issues with this design:
- no linking: if this is just a payment service, why not use
https://example.com/order/paymentinstead and have a payment media type that links to the order being paid? that would not only make the payment resource a more reasonable interaction point (it's basically like a cashier accepting many different things to be paid for), it also would allow for richer functionality such as paying for multiple orders (simply link to all the orders you're paying for) or even paying for third-party orders (simply link to these 3rd-party orders).
- contrived resource model: if the action indeed is bound to a single resource (in contrast to the potentially more general action mentioned in issue 1), then why is it a resource? it seems that the interaction taking place is to submit a state change to the actual resource, and then that resource is changing state (from
paid) as a result of that interaction. what is the reasoning behind turning the payment into an action, and why is it significantly better than the dreaded
action=paymentin URI query parameters
- not media type centric: if payment is done using a payment request, then there has to be a self-describing document conveying the payment data. this could be submitted to a general payment resource (as described in issue 1) or to the resource itself (as described in issue 2), but there really does not seem to be a good reason why it would need to be submitted to a specific URI just minted for that particular operation on that particular resource.
please keep in mind that even if you would use a general-purpose payment URI or POST a payment to the order URI, clients would still only be linked to the payment URI when payment would be a state change permitted by the server. as usual, a rel="payment" link would only be included if paying was an option, and the only difference to the resource-specific action URI approach would be that it would point to either a general-purpose payment URI, or to the URI of the order accepting the payment media type.
after a quick but non-representative look at some books and APIs, it seems to me that the resource-specific action URI is a pretty common pattern, and i would be interested in opinions about the alternatives, and also whether people have looked at all these patterns and have made decisions between them because of constraints that made one pattern a better fit that the other. as usual, there are many ways to solve a given problem, but the resource-specific action URI may be one pattern that could be replaced by others, at least in some scenarios.