1

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?

3
  • 3
    REST api has become a synonym for http web api. That’s clearly wrong, but it is what it is. The question is too broad imo, can you focus on a single question?
    – Rik D
    Dec 11, 2021 at 10:09
  • 2
    What you've discovered there is the difference between the actual (Roy Fielding's) REST that describes the architecture of the Internet (in a generalized way), and the industry RESTful services that are really an approach to writing RPC-based web services, don't use HATEOAS, require clients to understand closely the details of the API, aren't applied to Internet-scale applications, don't have the kinds of constraints REST adresses, and basically have nothing to do with REST beyond the borrowed name. IMO, it's best to treat them as two different things, and asses advice in light of that. Dec 11, 2021 at 10:43
  • @RikD most of the question was context, illustrating the issues I ran into when trying to effect stateful changes. I'll try to focus it more on the stateful portion.
    – Zymus
    Dec 12, 2021 at 2:01

2 Answers 2

5

REST have come to mean two different things:

  1. The architecture of the web, as described by R.T.Fielding (who coined the term REST). This is the original definition.

  2. A HTTP API called from JavaScript or external software systems. This is the most common definition these days, at least in the context of software development.

These two meanings are partially overlapping and partially contradictory, which leads to a great deal of confusion.

To start with the original definition:

The web is an architecture designed for humans interacting with a distributed system through a user agent (e.g. a browser).

The user agent knows how to send requests and parse responses, but it is the human who interprets the response and decides on what to do next based on the information in the response.

The response should provide the means to perform the next valid operation and the information which allows the user to determine the meaning of these operations. In the simplest form, it could be links which the user might decide to follow. Or it could be a form that the user could fill out and post to the server. So the client knows how to structure valid requests because all necessary information is provided by the server, typically encoded in HTML.

The relationship between HTTP and REST is confusing. REST is an abstract architecture model derived from how the web works, in particular the interaction between HTTP, URL's, content types, and hypertext. So the web is an implementation of the REST architecture more or less by definition, but REST is defined in more abstract terms than any particular protocol. Other implementations of the REST architecture therefore could exist in theory, but in practice REST always implies web architecture, in particular HTTP.

The second definition is about HTTP API's called by software, e.g a web service called by another server or a backend called from a JavaScript SPA. Since we haven't invented a general artificial intelligence yet, software can only do what it is programmed to do. Any meaningful operation has to be programmed into the software upfront. So there is no purpose in the server sending the "options" dynamically. Any information about the allowed interactions and their semantics and the expected content types has to be provided upfront to the developers of the client in some form of documentation.

2

TLDR: It chooses from the options provided by the server.

It doesn't really know the "resources", "methods" nor formats involved, the same way you don't know what resources you're manipulating when you order on amazon. When was the last time you cared what URIs that process goes through, or what HTTP methods are involved?

Long answer: I find your question refreshingly insightful actually. What you've discovered is that there are two completely opposing interpretations of what REST is. Confusingly enough, both think they are the thing that Roy Fielding originally described.

So the colloquial usage of "REST", is anything that is JSON over HTTP. That's it. Most articles, examples, tutorials, even software, even those that mention HATEOAS are in this camp.

These usually think URIs matter, or talking about HTTP Methods, or using Swagger/OpenAPI. These are all just JSON over HTTP, mostly RPC-like constructs, where the whole process, URIs and what happens when is hardcoded into the client.

The other interpretation tries to closely follow the original idea of Roy Fielding, which is basically how the Web works. Not HTTP, but HTML. As in, some hypertext format, with links and forms, each page representing some state in a workflow for the user. Here the workflow is not hardcoded into the client (the browser), but the user chooses by manipulating the currently presented representation (the web page).

So machine-readable REST should obviously behave the same. The client doesn't really know the individual resources at all, instead it knows the hypermedia formats involved! It knows how to follow a link, how to submit a form. That form may or may not describe technical things like HTTP Methods (just like a HTML Form does), but that is irrelevant to the client. The representation tells the client what it can do. At all times. The client doesn't suddenly know how to construct a specific json format for a specific URI. That would be completely preposterous.

HTH.

Update to the last paragraph: When I say it knows the hypermedia formats involved, I don't just mean it knows that it is json. It must know what it means too. That it is an order page for example. One crucial difference between REST for humans and machines is, that humans interpret based on text on the page, while machines interpret based on media-types, at least for now. This is why you see custom media-types, or 100, proposed. That is not necessarily needed, but it is a valid option.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.