Trying to understand REST HATEOAS:
Suppose I have a service that has state; they are: initial, ready, running. I have a client that connects to the service, obtains a page with links that allow it to mutate the service state.
It uses one of the links to change the service's state and obtains another page with new links.
As long as there is 1 client, the state the client holds is identical with the service. But if there is a second client and it changes the service's state, the first client's representation is stale.
How is this resolved in HATEOAS? From what I've read it seems that REST is not applicable and I should maybe look at something else. If so, what?
Thanks!
This is not resolved by HATEOS (entirely). As REST is stateless this is kind of a paradox use case to keep state in client and server aligned.
Assuming I understand your requirements, yes, you're state in client 1 is stale and not the same as the one on the server. But what if the client would make a periodic call to the server to see whether some other client changed it? If so, with HATEOAS you could provide a link to serve the current state and omit the link to change the state.
#Kay - Thanks for answering.
I'm going to try to answer my own question. I realized after reading your answer that the "application" in HATEOAS is really the virtual application the client experiences when it retrieves and processes the resources it gets from the server. Its states are the pages (resources) it transitions between. The server (service?) may have its own state but it's not the same as the client's.
As long as this distinction is kept in mind, it is not unRESTful to have stale links in client 1. The server simply responds with new links reflecting its own state. And the client makes new transitions based on the updated links.
Still trying to understand. If I have it wrong, I'd appreciate some help.
Thanks!
The stateless requirement of REST refers to the ability of the server to understand and process the client request independent from any previous interactions it has made with said client. In other words, the client should be able to send a request "out of the blue" to the server (I.e., without a session saved on said server) and have the request processed. Hence there isn't a concept of login and logout in a purely RESTful architecture.
That's a different constraint than HATEOAS. Basically, "hypermedia as the engine of application state" means that all state is conveyed through the media type being used and not the connection itself. The client can (and often does) keep its own state, and can request snapshots of the state of resources from the server through resource representations (a.k.a media types).
If you want to be notified when a resource changes state, REST is (probably) the wrong choice. You'd likely want to use a different application protocol than, say, HTTP.
As Fielding says: it's not REST without HATEOAS. Don't call your service REST if it's ignore HATEAOS and stateful service can not be REST. You understood HATEOA. The server provides hyperlinks for the client which should be use to change the state located at the CLIENT SIDE.
To solve your problem: omit tend server from any state information. It will easier your life. Then implement REST as using the Richardson Maturity Model while consider information's from here.
Related
According to this in property 3 and property 4,
Stateless
Roy fielding got inspiration from HTTP, so it reflects in this
constraint. Make all client-server interactions stateless. The server
will not store anything about the latest HTTP request the client made.
It will treat every request as new. No session, no history.
No client context shall be stored on the server between requests. The
client is responsible for managing the state of the application.
But then again,
In REST, caching shall be applied to resources when applicable, and
then these resources MUST declare themselves cacheable. Caching can be
implemented on the server or client-side
How is the server being stateless if it can cache information?
tldr: Stateless refers the behavior of a server to not record any information on the client's behalf between calls.
Caches are used as a server optimization strategy for resources that are requested often (and do not change frequently).
If a server is "stateless" this mean that no information will be held on the server side on the clients behalf between requests. Thus each request that a client makes must contain all of the required information for the server to perform the desired action. Irrespective of how many calls the client has made on this server previously.
Stateless means there is no memory of the past. Every request is performed as if it were being done for the very first time.
Stateful means that there is memory of the past. Previous request are remembered and may impact behavior of the current Request
Caching is merely holding a copy of a resource that the server is responsible of serving. Caching is commonly used for highly requested resources. Caching strategies can be used by both stateless and stateful services.
In REST when designing an api, you can have Stateless iteration with your clients and you can use caching to store highly requested items in memory to save IO calls to disk.
The authoritative reference for REST is Fielding's dissertation.
Fielding's definition of stateless is found in the discussion of network-based architectural styles
The client-stateless-server style derives from client-server with the additional constraint that no session state is allowed on the server component. Each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is kept entirely on the client.
It may help to contrast this idea with FTP, where the server is expected to track session state.
RETR example.txt
In FTP, to interpret that RETR command correctly, you need to know what the current working directory is for the session, and the clues that tell you that are stored in earlier messages.
Because HTTP requests are self contained, you don't need "sticky" session management.
As Fielding himself notes, Cookies violate the stateless rest constraint:
The same functionality should have been accomplished via anonymous authentication and true client-side state.
Normally I would consider any system that changes its behaviour over time as stateful.
Now let's consider a REST service. You GET a resource, later you or someone else modifies the resource with PUT and then you GET the resource again. Obviously, according to the above definition, this would be a stateful system.
But in the context of web services it would still be considered as stateles. So the definition of state must be different here.
What I think is actually meant by stateless webservices, is that the result of a given request should be the same for each client at a given time.
Is that correct? And why does it differ from my usual definition of state? Is stateless the same as connectionless here?
The reference you are looking for is Architectural Styles and
the Design of Network-based Software Architectures, by Roy Fielding. Specifically, chapter three, where he enumerates a number of architectural styles, in particular client-stateless-server.
The client-stateless-server style derives from client-server with the additional constraint that no session state is allowed on the server component. Each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is kept entirely on the client.
Edit:
So is it correct to say that state in this context does not refer to the state of the server but to the state of a (non-existing) session? Or in other terms, that stateless is a synonym for sessionless here?
Yes.
Someone asked me this question a couple of days ago and I didn't have an answer:
As HTTP is a stateless protocol. When we open www.google.com, can it
be called a REST call?
What I think:
When we make a search on google.com all info is passed through cookie and URL parameters. It looks like a stateless request.
But the search results are not independent of user's past request. Search results are specific to user interest and behavior. Now, it doesn't look like a stateless request.
I know this is an old question and I have read many SO answers like Why HTTP is a stateless protocol? but I am still not able to understand what happens when user activity is tracked like on google or Amazon(recommendations based on past purchases) or any other user activity based recommendation websites.
Is it RESTful or is it RESTless?
What if I want to create a web app in which I use REST architecture and still provide user-specific responses?
HTTP is stateless, however the Google Application Layer is not. The specific Cookies and their meaning is part of the Application Layer.
Consider the same with TCP/IP. IP is a stateless protocol, but TCP isn't. The existence of state in TCP embedded in IP packets does not mean that IP protocol itself has a state.
So does that make it a REST call? No.
Although HTTP is stateless & I would suspect that www.google.com when requested with cookies disabled, the results would be the same for each request, making it almost stateless (Google still probably tracks IP to limit request frequency).
But the Application Layer is not stateless. One of the principles of REST is that the system does not retain state data about about the client between requests for the purpose of modifying the responses. In the case of Google, that clearly is not happening.
It seems that the meaning of "stateless" is being (hypothetically) taken beyond its practical expression.
Consider a web system with no DB at all. You call a (RESTful) API, you always get the exactly the same results. This is perfectly stateless... But this is perfectly not a real system, either.
A real system, in practically every implementation, holds data. Moreover, that data is the "resources" that RESTful API allows us to access. Of course, data changes, due to API calls as well. So, if you get a resource's value, change its value, and then get its value again, you will get a different value than the first read; however, this clearly does not say that the reads themselves were not stateless. They are stateless in the sense that they represent the very same action (or, more exact, resource) for each call. Change has to be manually done, using another RESTful API, to change the resource value, that will then be reflected in the next call.
However, what will be the case if we have a resource that changes without a manual, standard API verb?
For example, suppose that we have a resource that counts the number of times some other resource was accessed. Or some other resource that is being populated from some other third party data. Clearly, this is still a stateless protocol.
Moreover, in some sense, almost any system -- say, any system that includes an authentication mechanism -- responds differently for the same API calls, depending, for example, on the user's privileges. And yet, clearly, RESTful systems are not forbidden to authenticate their users...
In short, stateless systems are stateless for the sake of that protocol. If Google tracks the calls so that if I call the same resource in the same session I will get different answers, then it breaks the stateless requirement. But so long as the returned response is different due to application level data, and are not session related, this requirement is not broken.
AFAIK, what Google does is not necessarily related to sessions. If the same user will run the same search under completely identical conditions (e.g., IP, geographical location, OS, browser, etc.), they will get the very same response. If a new identical search will produce different results due to what Google have "learnt" in the last call, it is still stateless, because -- again -- that second call would have produced the very same result if it was done in another session but under identical conditions.
You should probably start from Fielding's comments on cookies in his thesis, and then review Fielding's further thoughts, published on rest-discuss.
My interpretation of Fielding's thoughts, applied to this question: no, it's not REST. The search results change depending on the state of the cookie header in the request, which is to say that the representation of the resource changes depending on the cookie, which is to say that part of the resource's identifier is captured in the cookie header.
Most of the problems with cookies are due to breaking visibility,
which impacts caching and the hypertext application engine -- Fielding, 2003
As it happens, caching doesn't seem to be a big priority for Google; the representation returned to be included a cache control private header, which restricts the participation by intermediate components.
Assume the following scenario A web application serves up resources through a RESTful API. A number of clients consume this API. The goal is to keep the data on the clients synchronized with the web application (in both directions).
The easiest way to do this is to ask the API if any of the resources have changed since the client last synchronized with the API. This means that the client needs to ask the API for the appropriate resources accompanied by timestamp (to see if the data needs to be updated). This seems to me like the approach with the least overhead in terms of needless consumption of bandwidth.
However, I have the feeling that this approach has a few downsides in terms of design and responsibilities. For example, the API shouldn't have to deal with checking whether the resources are out of date. It seems that the only responsibility of the API should be to serve up the resources when asked without having to deal with the updating aspect. By following this second approach, the client would ask for a lot of data every time it wants to update its data to keep it synchronized with the web application. In other words, the client would check whether the data it got back is newer than the locally stored data. If this process takes place every few minutes, this might become a significant burden for the system.
Am I seeing this correctly or is there a middle road that I am overlooking?
This is a pretty common problem, and a RESTful approach can help you solve it. HTTP (the application protocol typically used to build RESTful services) supports a variety of techniques that can be used to keep API clients in sync with the data on the server side.
If the client receives a Last-Modified or E-Tag header in a HTTP response, it may use that information to make conditional GET calls in the future. This allows the server to quickly indicate with a 304 – Not Modified response that the client’s previously stored representation of the resource is still valid and accurate. This will allow the server (or even better, an intermediate proxy or cache server) to be as efficient as possible in how it responds to the client’s requests, potentially reducing costly round-trips to a back-end data store.
If a response contains a Last-Modified header and the client wishes to take advantage of the performance optimization available with it, they must include an If-Modified-Since directive in a subsequent GET call to the same URI, passing in the same timestamp value it received. This instructs the server to only GET the information from the authoritative back-end source if it knows it has changed since that time. Your server will have to be built to support this technique, of course.
A similar principle applies to E-Tag headers. An E-Tag is a simple hash code representing a specific state of the resource at a particular point in time. If the resource changes in any way, so does its E-Tag value. If the client sees an E-Tag in a response it should pass it in subsequent GET requests to the same URI, thereby allowing the server to quickly determine if the client has an up-to-date representation of the resource.
Finally, you should probably look at the long polling technique to reduce the number of repeated GET requests issued by your clients to the server. In essence, the trick is to issue very long GET requests to the server to watch for server data changes. The GET will not return a response until either the data has changed or the very long timeout fires. If the latter, the client just re-issues the same long-lived request to watch for changes again. See also topics like Comet and Web Sockets which are similar in approach.
I am currently struggling with a design issue involving REST. The application I am designing has a requirement to send out events and also support pub/sub style of interaction. I am unable to come up with a design to provide these interaction style without breaking the REST’s “Stateless interaction” constraint. I am not against polling as some people seem to be (polling sucks) , but my application demands a event based and pub/sub style of interaction (polling is not an option for me). So, my question is:
Can I design a RESTful application that supports event based and pub/sub interactions without breaking the REST contraint?
Is REST style suitable for this kind of interaction style?
I'd recommend the Distributed Observer Pattern by Duncan Cragg as a good read (bit difficult to grok but worth the effort).
As others have indicated its likely you'll need to use polling but as you rightly say subscribers could register their own interest (POST to create subscription). If you view the subscription as its own resource, a contract between the publisher and subscriber, then I wouldn't view it as a breaking REST constraints (see State and Statelessness at page 217 of RESTful Web Services for the difference between application and resource state)
I assume you mean the server should notify the clients about events. I don't see how the specific technology matters here: you will face the same problems, and have to pick a solution from the same pool, regardless of using REST, SOAP-based web services, or any other alternative.
The basic question is, can your server initiate connections? Complementing this, can the clients listen to a port? If so, the client registers (sub), and the server notifies of events (pub). Both the registration operation and the notification events can be RESTful.
You need both server-initiated connections and listening clients. If either is not an option (e.g., because the client is a web browser), you will have to make do with polling (you can also look into something like websockets, if you're dealing with a browser). Design your polling carefully: the server response to the polling event should indicate a minimum delay before the client may poll again. The initial implementation of the server can return a constant for this delay value, but later on (assuming the clients are well-behaved) this will allow you to control the load on the server, differentiate between critical and less-critical clients, and so on.
And of course, the polling can be RESTful.
I don't see a reason why RESTful interfaces should not support events.
It will have to be done through polling, mind you; and that would be true even if you were to use SOAP instead.
While your web servers should definitely remain stateless, you probably do have a DB somewhere on the back end. You can use this DB to handle subscriptions to events by adding a subscription table.
Webhooks are the answer to this problem. They allow events without violating the REST principles.
Just a fast check on the REST constraints:
client-server architecture
stateless
cache
uniform interface
identification of resource
manipulation of resource through representations
self-desriptive messages
hypermedia of the engine of application state
layered system
code on demand (optional)
From the Fielding dissertation:
The client-server style is the most frequently encountered of the
architectural styles for network-based applications. A server
component, offering a set of services, listens for requests upon those
services. A client component, desiring that a service be performed,
sends a request to the server via a connector. The server either
rejects or performs the request and sends a response back to the
client.
Btw. an event based system would probably violate most of the constraints. It is hard to define things like hypermedia the engine of application state without clients (since the other name of application state is client state) and hyperlinks (since they are meaningless by pub/sub), and so on...
Anyways it is an interesting question how to design an event based system somewhat similar to REST. I think you should publish self-descriptive messages containing RDF, but that's just a tip. Polling can be a viable solution, but if I were you I would not try to force REST on an event based system...
update 2016.05.15.
As far as I understand the client - server architecture - Fielding describes here and here in his dissertation - uses always REQ/REP communication. The client sends the request and the REST service responds. If you want to have something like PUB/SUB without the violation of the client - server constraint, the only way to do that is the usage of polling. If you don't want to use polling, then ofc. you can use a REST service and a websocket service together, it is not forbidden...