How to distinguish application state and resource state - rest

I know that to make a stateless application, we need to transfer the user state back and forth instead of server holds the user state.
However, there must be some states stored in the server, I read this article that the state stored in server is called resource state.So if I am right, client state which we often call should be the same as application state.
So, how do I distinguish these two, since it will determine that whether they should stored in server or transferred.
Take a shopping cart as an example.
If there is 5 steps before a user to complete his purchase, the user's phase where he is(#3,#4) in seems to be an application state, but does this mean if they close the browser and click on pay again, he will have to start from the step1?
What about the items in his chart? If we treat it as application state, we need to put all of the items in the request. But if we do this, when user close the browser and login again, he will not able to find his items again, since the browser can not remember all the items. So it seems we should treat it as a resource state. But if so, when a user click on pay , they will have a different page: go to pay or say "your cart is empty" based on whether his shopping cart is empty or not. So , the same requests with exactly the same param input, comes out the different result, can we still say it is stateless?
Maybe I understand something wrong, can any body please answer how to distinguish different kinds of state and how to treat them differently?

Resource state is a state that needs to be persistent and survivable even after client disconnect/restart/session end/whatever.
Application state should live on the client and should be supplied with each client request(if we are talking about REST architecture and planning to scale our application well).
How to distinguish application state and resource state?
It depends on the task your are working on. E.g. if you are trying to figure out where to save index of the picture that is currently viewed in your gallery, probably, you could do it in your Application state, because you, likely, don't need this state to survive for the next session of this client. Of course, you can save it in your Resource state(database), but it would be overhead(a lot of effort for a very small gain).
But if your are working on multistep purchasing process, probably, it's better to save state of this process in your Resource state(database), because you want this state to be saved permanently. Otherwise, your clients need to refill a lot of information after disconnect/restart/whatever.
Of course you could do it in cookies for example(and it would be Application state), and this state can live after browser restart. But it has the two downsides: 1)This state unavailable on other user's devices, 2)If you are creating genuine REST service, cookies would complicate client's life, because not all clients operate cookies well(except browsers).

Let me just quote one paragraph of the book RESTful Web Services :
The Flickr
web service lets you upload pictures to your account, and those pictures are stored on
the server. It would be crazy to make the client send every one of its pictures along with
every request to flickr.com, just to keep the server from having to store any state
The application state is related to the path that the client can follow to make some actions.
For example, when consulting an article, a link "add to cart" appears. When consulting his cart, a link "pay your order" is provided if you have one article in your cart otherwise this link does not appears. Feel free to the user to make its own application state based on the link that he follows. Basically, application state is a matter of context.
One other quote from the same book mentionned earlier before I go back to you example:
Resource state stays on the server and is
only sent to the client in the form of representations. Application state stays on the
client until it can be used to create, modify, or delete a resource. Then it’s sent to the
server as part of a POST, PUT, or DELETE request, and becomes resource state.
So let's say that you have some authentification mechanism (based on token). And to one user account is associated one cart.
When you are adding items in your cart, you are modifying your cart resource. As resource state are server-side, it's on server.
Suppose that you disconnect, and reconnect like described in your first point. The cart is still here.
As long as the client send the different authentification credential at each request, your application remains stateless.
A good discussion on SO about how to manage it: Do sessions really violate RESTfulness?
Now, what about the fact that: consulting your cart can leads you to 2 different action depending on whether it has items or not.
Pretty simple. What is served by the server to the client depends on the resource state maintains by the server.
A very simple example on this good website. You can see that depending on the amount of money on the account, the server provides a link to the client to make a withdraw or not.
Feel free to the client to make its own application (again) and to follow the link or not.
I recommand you to take a look at HATEOAS and the Richardson Maturity Model that explains it.
By the way, the quotes from the 2 paragraphs are from the same author that this model.

Related

Handling User Preferences/States in REST API

We're starting to migrate our Website to a REST Service based system and are in the process of developing the core right now.
In our current setup a user has one or more "accounts" assigned which define what data he can see on the website. Only one account can be active for a given user at any time. Right now we store the selected account in the database and use it to filter all queries.
Now I'm not sure how to handle this properly in a REST environment. Possible solutions I found are:
Sending the requested account with every request
Storing the current account in the auth token. (We're using JWT for that)
Having the current account stored on the server and calling a specific resource to change it
Each of these has its pros and cons for our setup. Currently we're using the 3rd approach in our Website. But what would be the correct way to handle such a thing in a REST environment?
Yea the design you are dealing with is fairly bad, and what you really want to do is remove the state completely out of this system.
For that reason the first option is by far superior:
Sending the requested account with every request
If this is simply an id, there's a very simple way to do this, just prefix all your (relevant) routes / uris with this account id. For example:
http://api.example.org/accounts/{id}/...
This way the 'state' is maintained by virtue of which url you are accessing, and the server can be unaware of the state.

How to make initial request for nested resource from self describing REST API

Background:
I have a single page application that pulls data from a REST API. The API is designed such that the only URL necessary is the API root, ie https://example.com/api which provides URLs for other resources so that the client doesn't need to have any knowledge of how they are constructed.
API Design
The API has three main classes of data:
Module: Top level container
Category: A sub-container in a specific module
Resource: An item in a category
SPA Design
The app consuming the API has views for listing modules, viewing a particular module's details, and viewing a particular resource. The way the app works is it keeps all loaded data in a store. This store is persistent until the page is closed/refreshed.
The Problem:
My question is, if the user has navigated to a resource's detail view (example.com/resources/1/) and then they refresh the page, how do I load that particular resource without knowing its URL for the API?
Potential Solutions:
Hardcode URLs
Hardcoding the URLs would be fairly straightforward since I control both the API and the client, but I would really prefer to stick to a self describing API where the client doesn't need to know about the URLs.
Recursive Fetch
I could fetch the data recursively. For example, if the user requests a Resource with a particular ID, I could perform the following steps.
Fetch all the modules.
For each module, fetch its categories
Find the category that contains the requested resource and fetch the requested resource's details.
My concern with this is that I would be making a lot of unnecessary requests. If we have 100 modules but the user is only ever going to view 1 of them, we still make 100 requests to get the categories in each module.
Descriptive URLs
If I nested URLs like example.com/modules/123/categories/456/resources/789/, then I could do 3 simple lookups since I could avoid searching through the received data. The issue with this approach is that the URLs quickly become unwieldy, especially if I also wanted to include a slug for each resource. However, since this approach allows me to avoid hardcoding URLs and avoid making unnecessary network requests, it is currently my preferred option.
Notes:
I control both the client application and the API, so I can make changes in either place.
I am open to redesigning the API if necessary
Any ideas for how to address this issue would by greatly appreciated.
Expanding on my comment in an answer.
I think this is a very common problem and one I've struggled with myself. I don't think Nicholas Shanks's answer truly solves this.
This section in particular I take some issues with:
The user reloading example.com/resources/1/ is simply re-affirming the current application state, and the client does not need to do any API traversal to get back here.
Your client application should know the current URL, but that URL is saved on the client machine (in RAM, or disk cache, or a history file, etc.)
The implication I take from this, is that urls on your application are only valid for the life-time of the history file or disk cache, and cannot be shared with other users.
If that is good enough for your use-case, then this is probably the simplest, but I feel that there's a lot of cases where this is not true. The most obvious one indeed being the ability to share urls from the frontend-application.
To solve this, I would sum the issue up as:
You need to be able to statelessly map a url from a frontend to an API
The simplest, but incorrect way might simply be to map a API url such as:
http://api.example.org/resources/1
Directly to url such as:
http://frontend.example.org/resources/1
The issue I have with this, is that there's an implication that /resource/1 is taken from the frontend url and just added on to the api url. This is not something we're supposed to do, because it means we can't really evolve this api. If the server decides to link to a different server for example, the urls break.
Another option is that you generate uris such as:
http://frontend.example.org/http://api.example.org/resources/1
http://frontend.example.org/?uri=http://api.example.org/resources/1
I personally don't think this is too crazy. It does mean that the frontend needs to be able to load that uri and figure out what 'view' to load for the backend uri.
A third possibility is that you add another api that can:
Generate short strings that the frontend can use as unique ids (http://frontend.example.org/[short-string])
This api would return some document to the frontend that informs what view to load and what the (last known) API uri was.
None of these ideas sound super great to me. I want a better solution to this problem, but these are things I came up with as I was contemplating this.
Super curious if there's better ideas out there!
The current URL that the user is viewing, and the steps it took to get to the current place, are both application state (in the HATEOAS sense).
The user reloading example.com/resources/1/ is simply re-affirming the current application state, and the client does not need to do any API traversal to get back here.
Your client application should know the current URL, but that URL is saved on the client machine (in RAM, or disk cache, or a history file, etc.)
The starting point of the API is (well, can be) compiled-in to your client. Commpiled-in URLs are what couple the client to the server, not URLs that the user has visited during use of the client, including the current URL.
Your question, "For example, if the user requests a Resource with a particular ID", indicates that you have not grasped the decoupling that HATEOAS provides.
The user NEVER asks for a resource with such-and-such an ID. The user can click a link to get a query form, and then the server provides a form that generates requests to /collection/{id}. (In HTML, this is only possible for query strings, not path components, but other hypermedia formats don't have this limitation).
When the user submits the form with the ID number in the field, the client can build the request URL from the data supplied by the server+user.

REST Shopping cart

Can a shopping cart be implemented using REST architecture constraints?
I would like to focus my question with respect to session state. In a typical MVC application implementing a shopping cart, it most likely, session object will be managed in session, shopping cart as a list of products.
How would this same shopping cart be managed in if the application had followed REST architecture. One of the REST constraints is state management is responsibility of clients.
Should a shopping cart and it's progress be managed by client? Any examples? Any disadvantages of managing state in client with respect to a simple shopping cart or any other enterprise applications?
There is nothing wrong with storing the shopping cart as a resource on the server. It is session state that should be stored on the client. https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_3
In order to be stateless, your shopping-cart URI should be able to identify a unique cart without needing to rely on any session information.
For example, /shopping-cart is probably not sufficient unless there will only ever be one shopping cart throughout your application.
Likely, there will be at least one cart per user. So, you could use something like /user/1234/shopping-cart or /shopping-cart?userID=1234.
Even more likely, you will probably need to have multiple shopping-carts per user. So, you will want to give your carts a unique ID like /user/1234/shopping-cart/5678 or just /shopping-cart/5678.
The point is, everything needed to process the request should be in the request.
In REST applications, the session state is entirely managed by the client and the request must contain all the necessary information to be understood by the server. If the server requires authentication, for example, each request must contain the credentials.
The REST stateless constraint is defined as the following:
5.1.3 Stateless
[...] 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 therefore kept entirely on the client. [...]
However, the stateless constraint doesn't mean the server shouldn't store any data.
In applications which the session state is managed by the server, it's a common approach storing the shopping cart data in the HTTP session. But a shopping cart is not a session state. And, probably, it should not be entirely managed by the client.
In REST, a shopping cart, can be a resource identified by a URL such as /shopping-cart and operations can be performed over it. All the shopping cart data can be persisted to a database on the server.
Any information that can be named can be a REST resource, even a shopping cart:
5.2.1.1 Resources and Resource Identifiers
The key abstraction of information in REST is a resource. Any information that can be named can be a resource: a document or image, a temporal service (e.g. "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. a person), and so on. In other words, any concept that might be the target of an author's hypertext reference must fit within the definition of a resource. A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time. [...]
You can perform operations like these on your shopping cart:
GET /shopping-cart: Get the shopping cart.
POST /shopping-cart: Add an item to the shopping cart (sending some data with the item you are adding and the amount in the request body).
DELETE /shopping-cart/1: Remove an item with id 1 from the shopping cart.
PATCH /shopping-cart: Update the shopping cart (sending some data to be updated in the request body).
PUT /shopping-cart: Replace the whole content of the shopping cart (sending some data with the content of your shopping cart in the request body).
DELETE /shopping-cart: Remove the shopping cart
POST /shopping-cart/order: Order the shopping cart content
So, observe the client won't store any information about the shopping cart at any time. All the information related to the shopping cart will be stored in the server.
For more information about REST, I do recommend reading the chapter 5 of Roy T. Fielding's dissertation.
A lot of confusion about REST exists because lots of people hear about REST constraints and think they are rules that are applied for no reason other than following the architecture as an end in itself.
The real question you should be asking is why the stateless constraint exists in REST, and what advantages do you get from following it. Keep in mind that REST is an architectural style intended for long-term evolution of large-scale distributed systems. You simply won't have the problems REST is supposed to solve in a small-scale application where a single database holds all your information.
The stateless constraint induces the property of visibility,
reliability and scalability. Visibility is improved
because a monitoring system does not have to look beyond a single
request datum in order to determine the full nature of the request.
Reliability is improved because it eases the task of recovering from
partial failures. Scalability is improved because not having to
store state between requests allows the server component to quickly
free resources, and further simplifies implementation because the
server doesn't have to manage resource usage across requests.
So, being stateless means the client request should have all the information required to process it.
How important is visibility for you? Do you want to be able to see the whole contents of the shopping cart from the client request when you are debugging something, or are you ok with having to get that information from the databases?
How important is reliability? Do you have a large distributed system with several servers and databases, where that matters? If you have a large distributed system where the shopping cart information might be stored in different databases depending on the exact HTTP server that responded the request, if a server fails only another server from that group will be able to fulfill the request and finish the session, or a server from another group will force the client to restart the session. If all the information is contained in the request, then any server can do it.
How important is scalability? If you have a distributed system and you're storing shopping cart information on a single database, it becomes a funnel for all your requests and you lose scalability. If you store it on several databases, you lose reliability as explained above.
So, do you have ambitious long-term goals or is your application going to be large enough that you'll face the problems REST attempts to solve? If you'll always have a few servers and a single database, and you'll use it for every single request, then it doesn't matter if you go stateless or not. You can just have a /shopping_cart resource or something like that, add stuff to it with POST requests, and close or delete it when you're done.
If you'll have your data sharded across multiple databases, lots of HTTP servers responding requests, cache servers, etc, and you want to have the ability to provision capacity dynamically by setting up new servers as they're needed and removing them when load is reduced, then go full stateless and leave the shopping cart with the client.
I think somebody chose very unfortunate name for STATELESS concept and that's why the whole misunderstanding is caused. It's not about storing any kind of resources, but rather about the relationship between the client and the server.
Client: I'm sending you the "task list", which needs to be processed. Do your job.
Server: All right.. let me take the responsibility of processing the data that is important for you, in order to give you the proper response.
Meaning, the server is the "slave" of the client and has to forget about his "master" after each request.
Yes you can,
Shopping cart data (added products) can be saved on the clients session, that ain't a problem.
Then once the user hits /checkout, the shopping cart should be persisted on the DB on the server. The key about rest is that every petition the client makes has to contain all data to identify himself, I suggest reading something about JWT or OAuth.
The app itself would work as any other shopping cart app you have seen, most of them do not persist the shopping cart in DB, just store it the clients session.
I think that is where SPA(Single page applications) come into use since the SPA are loaded at once and after that the variables maintain the state and between components you can pass them if the components are hierarchical or otherwise as well you can use stores(like Redux) to maintain state.
However I feel ideally in real scenario you would want to persist the shopping cart for users for following scenarios:
1)User adds items to shopping cart but does not order.Later, maybe next day he wants to continue from where he left.So it should be persisted
2)User is logged on from multiple devices, say multiple family members using the same account. Here as well the cart should be in sync.

RESTful client - how to process an external link?

By RESTful best services there is the HATEOAS principle which told us that we should not allow the client to build resource URL-s. If we follow this principle, it will be pretty hard to share the current state of the client. For example if you have a REST service on the server, and you gets data via AJAX with a single page javascript client, then you will have 2 urls. One for the client state, and one for the result you got from the REST service. You can share only the client state with the use due to pushState... If somebody runs the client with a previously shared url, then her client won't know about the url of the REST service it should call, because the client cannot build URL-s, just receive from the REST service and utilize it.
For example:
I browse the http://my.client.com
the page gets the root resource from the http://my.api.com, and return a link
the link contains the http://my.api.com/users url, with rel user collection
after that the client displays a button with label: userlist
I click on that button, the client get the data from the api, and prints the user list
if I want to share the user list with my girlfriend, then I have to change the browser url from the client with pushState, for example from http://my.client.com to http://my.client.com/users
after that I send that url to my girlfriend
she copy-pastes that into her browsers address bar and presses enter. after that the client says a huge wtf, because - like John Snow - it knows nothing about what state that url means...
This problem can be solved, if we allow the client to build GET http://my.api.com/users from the url: http://my.client.com/users, but this won't be RESTful, because the client should not build api urls...
If I want to display a nested menu in the client, then that is another problem, because I don't want to send the whole menu tree in every answer. I could create a menu projection for every resource, or use the OPTIONS method, or a custom method to send that data, but that would be a pain in the back. This can be solved by following the rel=up links - got from the REST service - in series, but if I don't know from where should I follow, it will not work...
This problem occurs by google bots too...
How can I both solve this problem, and stay inside the boundaries of the HATEOAS principle?
Normally we don't want to share all of that information with anybody, so we cannot export all of that just the current page we are in.
There is nothing wrong with storing the whole resource on the client and then pushing it up to the server to change the state on the server. If you are worried your resources are getting too large though you could break the resources out a bit. So say you have an order resource and that needs to associate with an address. You don't need to put the address in the order resource, just a link to the address to use. The user can add or alter that address independently. So you might have something like
www.myapi.com/users/1234/shippingaddresses/default
And the client can PUT a new address to this resource. Then in the body of the order resource you can have a link to this resource
POST www.myapi.com/users/1234/orders
{
...order information...
"shipping_address": "www.myapi.com/users/1234/shippingaddresses/default"
}
To be RESTful the client should not build that URL, it should have been given it by the server at some point in the recent past, possibly when the users is selecting which address to use. For example, in the previous step the client could have requested all addresses
GET www.myapi.com/users/1234/shippingaddresses
And presented the list of addresses to the user in a drop down list.

Recovery from page refresh in Web Applications?

Is there a standard or accepted way to recover from a page refresh in an Ajax web application?
My interest now lies mainly in a web app with a Java (JSP/Servlet) Back end. My page is initially rendered from a JSP and then the user progressed through the interface using javascript events.
Is there a design pattern which covers this, I'm assuming that the refresh button is someting that web developers need to worry about quite often so there should be a way of recovering from it, while maintaining state.
There are a number of way to handle this.
Anchors - This is what Gmail does when it tacks on #inbox/123 which means that it should show the email id 123 with the label inbox. This is not very expressive and is useful for simple states. However, it does provide users the ability to bookmark the page and use navigate through browser history.
Cookies - This has the advantage that this can be managed entirely on the client side. You can set cookies via Javascript and restore them via Javascript. It's cheap and doesn't require and post backs. The state information usually doesn't need to be persisted on the server because typically the state is temporary.
Sessions - This will need you to post back the state information back to the server via AJAX as the client updates the page. If the client refreshes the page, the new page incorporates the changed state into the newly rendered page. This is quite costly in terms of performance and also complicates design but may be useful for certain applications.
My suggestion would be keeping a state machine for each user on server side which changes states with the AJAX calls. That way on the refresh, you'll already know in which state position the user was in, allowing you to recover from this.
This might bring you a problem with scalability if you are not careful while coding it.
Another solution might be storing the state variable in the cookie (assuming the user has active cookies). And on page load, the state variable would be submitted to your web application, allowing you to recover.
Here's one solution we used in a project:
You assign a sequence number / random guid to the page eash time the user visits the page. You can put that into the get part of the url (such as yourpage.jsp?pid=1337 where 1337 is the page view sequence number)
When you process the AJAX requests, you maintain a "mirror" of the page state on the server side in the session or whatever mechanism you can use in JSP to store state.
When the user requests the page, you check if the given sequence number already exists, and if it does, it means that it's a refresh so you render the page using the mirror data you have in your session.