I've read that a key portion of a RESTful interface is that the client doesn't have to know what options are available before they hit the page/access the resource. The client starts with the initial URI, and gets enough information to do whatever the application allows them to do afterwards.
In the context of manipulating state, there's a fracture, where we have application/client state on one side, and resource state on the other; leading to an impression that REST is really just a thin layer on top of the persistence mechanism (database/file system/etc).
Most of the state manipulation examples I've read are tied to HTTP verbs, and the semantics that come with them (PUT here, POST there, PATCH in this case). In each case, the example provides the happy-path. We PUT this resource on this URI, and get a 200 back. But there's this implicit understanding of the structure of the request that isn't really mentioned; how does the client know what the request looks like?
If the server really is just serving a thin layer over the persistence, then that would imply that the client needs to be aware of, and be responsible for, all of the business logic surrounding a resource. This seems wrong, as the client could decide at any point in the future to do something different, and the server would trust it, and make the change to the resource ("You want me to put a $1,000,000 deposit into your /bank-account/deposits
? No problem!").
This would imply that the server is more than just a layer over persistence. In some examples, actions are mentioned as relative links, like a withdraw
on a /bank-account
, or a renewal
on a /subscription
. But in both of these cases, the link only provides the URI to the resource. It doesn't mention whether it's a PUT or a POST or a PATCH, and it also doesn't mention what the server is expecting.
Does a withdraw
look like this
{
"bankAccount": "12345",
"date": "2021-12-11",
"withdrawalAmount": 100.00
}
or like this
{
"amount": "100 USD",
"accountName": "Checking"
}
One of these is probably correct, one of them probably is not. Some of the articles mention defining custom media types (hundreds, if needed), something like application/vnd.myapp.bank-account-withdrawal+json
, and others say that there's no need to define a new media type, because it's still just JSON data.
There's also cases where multiple resources may be modified due to a single action. For instance, adding a transaction to your checking account ledger, updating your balance, upgrading your loyalty tier after spending enough money at a store, or even preventing the action from succeeding due to something the server knows, but the client doesn't; like trying to withdraw $1,000 when you only have $10. The relative link would still be present, because you can still definitely withdraw some money, but if you try to withdraw more than $10, the operation will fail (400 Bad Request, or 200 OK with an error message, depending on opinion, and how coupled you think REST should be to HTTP).
We could tell the client "send me JSON content in an HTTP POST", but there's lots of JSON content we could create, but only very specific types of content that will lead to a successful interaction.
Where does business logic (validation, processing, state changes) happen in a RESTful application? How does the client know the right way to send the right data to the server?