The problem is that people want an RPC mechanism, and REST gives them a document transfer mechanism.
If your API will never be navigated by a human operating a browser, a lot of the REST specification is inapplicable (navigation links, etc.)
So you're throwing out a lot of REST regardless, and the question becomes where to draw the line between ease of implementation and compliance with a standard that doesn't really fit your needs.
Another problem is that people want an RPC mechanism, when what they need is a state-transfer mechanism.
It turns out that the semantics of RPC — attractive as they undeniably are — are pretty poor for building real-world distributed systems, while those of REST as a pretty good (or at least better) fit.
People need both. REST works well for CRUD operations that don't have complex side effects or constraints. What's often missing in this is intent. I just want to do "the thing" to this particular account or whatever.
Personally I like to very selectively add RPC actions on top of the base resource. Tacking an RPC action onto the resource URI allows you to encapsulate the intent of the user's action, handle all the updates required server side, and then return the updated representation.
I almost always have both. I tend to use event sourcing and the intent is mandatory. There might be 20 reasons to modify one resource, each with its own list of side effects to later perform.
So it's usually POST resource/:id/action
and that's fine.
> So it's usually POST resource/:id/action and that's fine.
There's nothing wrong with that. It's not anti-REST or anything, assuming you satisfy the other REST constraints, ie. each request is self-contained and any stateful resources are designated by URLs.
As an aside, I'm personally not a huge fan of human-readable URLs because it encourages API consumers to rely on/construct URLs client-side, which is not REST.
I think a more properly-REST approach would be to PUT a representation of the resource with the action applied. That is, rather than POSTing to /resources/:id/close, one would PUT a closed version of the resource to /resources/:id.
I don't see why that would be more REST. POST is to be used for side-effecting operations, PUT is an optimization over POST for idempotent effectful operations.
Certainly a PUT solution might have some advantages for replayability in case of network partitions, but REST doesn't this choice dictate one way or the other.
> If your API will never be navigated by a human operating a browser, a lot of the REST specification is inapplicable (navigation links, etc.)
That's incorrect. REST was designed for services of all kinds, not just human interfacing services.
The point of links is to support service upgrade via good old encapsulation. Consumers of your API shouldn't just guess links like is commonly trumpeted as REST, they should navigate to the part of your service they need from a well-defined endpoint, and this navigation path has a well-defined lifetime specified by cache control headers (HATEOAS).
The service promises to honour the lifetime of any visited URL on that path as specified by said headers, and any client trying to use that path after the expiry date must be prepared to possibly receive error codes.
If your API will never be navigated by a human operating a browser, a lot of the REST specification is inapplicable (navigation links, etc.)
So you're throwing out a lot of REST regardless, and the question becomes where to draw the line between ease of implementation and compliance with a standard that doesn't really fit your needs.