A lot of what I've read about REST seems to contradict itself, depending on who's writing the article/tutorial.
To me, it feels like a way of designing an application that can be used like a Human.
For instance, we go to a known base address (http://google.com). From here, we are provided with a representation of actions the user can perform (enter text into a field and search). Afterwards, we get a representation of the search results, with other links as well (next page, previous page, first page, etc).
Everything I've read indicates 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. The client starts with the initial URI, and gets enough information to do whatever the application allows them to do afterwards (ie. next page come after a search).
But a lot of what I've read kind of stops here. There's talk of HATEOAS, and examples of specifying Accept headers in the HTTP GET request, and parsing JSON/XML representations to get the links that lead to other places, etc.
But there also seems to be some confusion about thinking about REST in terms of HTTP. In some of the documentation and articles I've read, the focus is on how to setup a RESTful HTTP Web API, and centers the content around how REST applies to HTTP. Others state that REST shouldn't depend on the HTTP protocol, or any protocol even, and doing so keeps us limited to thinking about resources via HTTP verbs.
In the context of manipulating state, there's another 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 article 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?