> Or is the assumption that it should generally work for anything if you model it right?
It should generally work for anything if you model it right.
> I ask this because the API I'm building is for a B2B product and lot of the "actions" are not state change requests.
How can anything both be an action and not be a state change request?
> In fact, they are a lot of verbs which fire off lots of business logic and don't really map well to a single entity.
A "verb that firest off lots of business logic" sounds like a RPC-style metaphor.
In a REST architecture -- and they don't necessarily map perfectly so with more description I might characterize this differently -- I'd characterize that as most likely a entity creation (HTTP POST) action (the entity being a particular invocation of the underlying logic, and containing all the necessary parameters.)
> Some endpoints also need to return very large and deeply filled entities in a single call.
How does this conflict with REST. REST has nothing against "large and deeply filled entities". (Remember that HTTP is itself a RESTful API, and obviously is designed for a use case where "large and deeply-filled entities" are frequently returned.)
You may want to define specific media types for each of these types of entities to do REST properly, but since in practice you are going to have to define the structure of the entity returned no matter what application architectural style you are using, this isn't really a substantial extra workload for REST.
> It should generally work for anything if you model it right.
No, this is not true. Each constraint of REST comes with drawbacks, and if you can't afford those drawbacks, you can't do it RESTfully. Fielding's thesis is very upfront about this.
The biggie: latency. If you need sub-10ms responses, REST is the wrong way to go about modelling your problem domain.
The second: client-server. If you want the server to initiate behavior on the client, REST is the wrong way to go. See the wealth of WebSockets/Meteor/Real Time Web (tm) frameworks and their hype for examples of when you'd want to do this.
First, I think that you misunderstood what I meant by "anything" -- I meant any logical model of what an API does, which seemed in context to be what the post I was responding to was asking about. I wasn't saying "anything" in the sense of any combination of performance requirements.
That being said, I'm not convinced that your particular objections, aside from responding to "anything" in a different sense than intended in context, are really accurate.
> The biggie: latency. If you need sub-10ms responses, REST is the wrong way to go about modelling your problem domain.
HTTP might be problematic here, but I don't see why REST is problematic. (REST doesn't rely on HTTP -- in fact, HTTP is itself a REST-based system -- and can be implemented over protocols with different performance characteristics.)
Its obviously a problem for every request to navigate from the API root if you have tight latency constraints, but there is nothing unRESTful about having a client cache the locations of the key resources it is interested in after the first access. In fact, reducing latency by encouraging cacheability is an explicitly-cited motivation for REST.
> The second: client-server. If you want the server to initiate behavior on the client, REST is the wrong way to go.
If you want system A to initiate a behavior on system B, then in the context of REST with regard to the behavior at issue, A is a client consuming an API and B is a server providing an API. If it is necessary for other reasons for A to be an HTTP server and B to the HTTP client, then you obviously aren't going to be doing typical REST-over-HTTP to implement the API that A is consuming and B is providing. But there is no reason that you can't use a REST architecture for the API. (OTOH, since, in simple cases, the API implementation will likely be being provided as Code-on-Demand to B by A, there's may not be a lot of reason to use REST, but it could help reduce coupling between different components on A.)
Gotcha. You're right that I got this wrong, but I think my objection still stands; a peer-to-peer interaction model is still not RESTful.
> Its obviously a problem for every request to navigate from the API root if you have tight latency constraints,
Even in truly RESTful systems, 'every request' wouldn't navigate from the root; the first interaction starts there, but it's not like you keep going back to the root every single time you want to do anything.
> In fact, reducing latency by encouraging cacheability is an explicitly-cited motivation for REST.
On latency and the layered system constraint you have a point.
> Even if it's 'oh they're just two different APIs working together', it's not a singular API, which is what we're talking about here.
I thought we were talking about the utility of REST architecture for the API(s) involved. Obviously, if you have requirements which require two different APIs where the consumers of one API are the providers of the other API, then regardless of architecture, it won't be one API, but that's orthogonal to the architecture appropriate to either or both APIs.
Send a message to the server to process all approved cases, which has no connection to an individual resource. The client has no fundamental knowledge of all server-side resources that may or may not be affected, and may not even be allowed that information.
It's an action, but it's not really a post. You're not creating a new resource. You're not patching anything, you're not really getting anything... It's closest to a PUT, but you're not really updating a particular resource...
This may not be a document-based API like REST expects, but it is a fairly common enterprise requirement for a system.
> Send a message to the server to process all approved cases, which has no connection to an individual resource.
"Individual resources" are defined by the needs of the API. If you need an endpoint that can be given a command to process all approved cases, then that is an "individual resource".
The particular kind of resource I'd normally model it as is one which is or has a collection resource in which individual command instances are the members of the collection.
> It's an action, but it's not really a post.
I disagree. Submitting a new request to initiate the action is exactly a request to create a new command resource subordinate to the collection of commands subordinate to the command processing endpoint resource, which naturally maps to an HTTP POST action to the collection. The processing of approved cases, and the resulting changes to the backend data store, are consequences (side effects) of the creation of that resource.
> This may not be a document-based API like REST expects
REST doesn't expect a "document-based API". It expects a resource based API. Commands, collections of commands, and endpoints which have collections of commands as well as other subordinate resources are all, themselves, valid resources, whether or not they are sensibly described as "documents".
"REST doesn't expect a "document-based API". It expects a resource based API. Commands, collections of commands, and endpoints which have collections of commands as well as other subordinate resources are all, themselves, valid resources, whether or not they are sensibly described as "documents"."
Ah, well said. It's so hard to find good examples of this though. Most REST tutorials focus on simple nouns that happen to map nicely to tables. But you're suggesting that "resources" could be far more abstract. But, if I were to treat Commands as resource and perhaps make it my only resource, isn't that essentially RPC?
> But, if I were to treat Commands as resource and perhaps make it my only resource, isn't that essentially RPC?
If you have a root URL for the API, and all the endpoints are located via links from the document at the root URL, and submitting commands gives back a results resource that either is or provides a URL for the output, and all the different resources have media types that define what is needed to understand/process them without requiring out-of-band information beyond that describing the media types and the root URL of the API, then it can still be REST.
I think its probably fairly common that there are situations where the "active" side of a REST API will largely look that way, even if there is a read-only component that looks like of the collection-resources-as-tables, individual-resources-as-table-rows business data view.
That being said, its probably not really good REST if things being modelled as abstract commands with side effect of changes on multiple entities really could be modeled as changes to some particular business entity that also had side effects on other business entities. But whether that applies to the commands you are using will depend on your use case.
It should generally work for anything if you model it right.
> I ask this because the API I'm building is for a B2B product and lot of the "actions" are not state change requests.
How can anything both be an action and not be a state change request?
> In fact, they are a lot of verbs which fire off lots of business logic and don't really map well to a single entity.
A "verb that firest off lots of business logic" sounds like a RPC-style metaphor.
In a REST architecture -- and they don't necessarily map perfectly so with more description I might characterize this differently -- I'd characterize that as most likely a entity creation (HTTP POST) action (the entity being a particular invocation of the underlying logic, and containing all the necessary parameters.)
> Some endpoints also need to return very large and deeply filled entities in a single call.
How does this conflict with REST. REST has nothing against "large and deeply filled entities". (Remember that HTTP is itself a RESTful API, and obviously is designed for a use case where "large and deeply-filled entities" are frequently returned.)
You may want to define specific media types for each of these types of entities to do REST properly, but since in practice you are going to have to define the structure of the entity returned no matter what application architectural style you are using, this isn't really a substantial extra workload for REST.