If REST applications are supposed to be stateless,

2018-12-31 14:20发布

I'm in need of some clarification. I've been reading about REST, and building RESTful applications. According to wikipedia, REST itself is defined to be Representational State Transfer. I therefore don't understand all this stateless gobbledeygook that everyone keeps spewing.

From wikipedia:

At any particular time, a client can either be in transition between application states or "at rest". A client in a rest state is able to interact with its user, but creates no load and consumes no per-client storage on the set of servers or on the network.

Are they just saying don't use session/application level data store???

I get that one goal of REST is to make URI access consistent and available, for instance, instead of hiding paging requests inside posts, making the page number of a request a part of the GET URI. Makes sense to me. But it seems like it is just going overboard saying that no per client data (session data) should ever be stored server side.

What if I had a queue of messages, and my user wanted to read the messages, but as he read them, wanted to block certain senders messages coming through for the duration of his session? Wouldn't it make sense to store this in a place on the server side, and have the server only send messages (or message ID's) that were not blocked by the user?

Do I really have to send the entire list of message senders to block each time I request the new message list? The message list pertinent to me wouldn't/shouldn't even be a publicly available resource in the first place..

Again, just trying to understand this. Someone please clarify.


Update:

I have found a stack overflow question that has an answer that doesn't quite get me all the way there: How to manage state in REST which says that the client state that is important should all be transferred on every request.... Ugg.. seems like a lot of overhead... Is this right??

14条回答
萌妹纸的霸气范
2楼-- · 2018-12-31 15:07

There is no spoon. Don't think of statelessness like "sending all your stuff to the server again and again". No way. There will be state, always - database itself is a kind of state after all, you're a registered user, so any set of client-side info won't be valid without the server side. Technically, you're never truly stateless.

But what you can do, and what makes real sense, is thin your webserver footprint to the minimum. Languages like PHP make it very easy to just stuff everything in the session storage; you can do this, but if you have many webservers, they must use something shared among them (NFS, Redis, Memcached, something) so that your next request knows what you've done one click earlier. It's because of load balancing - you might end up on another webserver with your next request. And while there MUST be a shared storage among them (mostly because they will have to tell if you're logged in or not), you should not use it as an alternative database. It's not for that.

So you're saying, keep session storage to the minimum?

Again, it's your decision. You can store stuff there for performance reasons (database is almost always slower than Redis), you can store information redundantly, implement your own caching, whatever - just keep in mind that web servers will have a bigger load if you store a lot of rubbish on them. Also, if they break under heavy loads (and they will), you lose valuable information; with the REST way of thinking, all that happens in this case is the client sends the same (!) request again and it gets served this time.

How to do it right then?

No one-fits-all solution here. I'd say choose a level of statelessness and go with that. Sessions may be loved by some and hated by others but they're not going anywhere. With every request, send as much information as makes sense, a bit more perhaps; but don't interpret statelessness as not having a session, nor as logging in every time. Somehow the server must know it's you; PHP session ids are one good way, manually generated tokens are another.

Think and decide, don't let design trends think for you.

查看更多
几人难应
3楼-- · 2018-12-31 15:09

Have a look at this presentation.

http://youtu.be/MRxTP-rQ-S8

According to this pattern - create transient restful resources to manage state if and when really needed. Avoid explicit sessions.

查看更多
不再属于我。
4楼-- · 2018-12-31 15:10

Are they just saying don't use session/application level data store???

No. They aren't saying that in a trivial way.

They're saying do not define a "session". Don't login. Don't logout. Provide credentials with the request. Each request stands alone.

You still have data stores. You still have authentication and authorization. You just don't waste time establishing sessions and maintaining session state.

The point is that each request (a) stands completely alone and (b) can be trivially farmed out to a giant parallel server farm without any actual work. Apache or Squid can pass RESTful requests around blindly and successfully.

What if I had a queue of messages, and my user wanted to read the messages, but as he read them, wanted to block certain senders messages coming through for the duration of his session?

If the user wants a filter, then simply provide the filter on each request.

Wouldn't it make sense to ... have the server only send messages (or message ID's) that were not blocked by the user?

Yes. Provide the filter in the RESTful URI request.

Do I really have to send the entire list of message senders to block each time I request the new message list?

Yes. How big can this "list of message senders to block" be? A short list of PK's?

A GET request can be very large. If necessary, you can try a POST request even though it sounds like a kind of query.

查看更多
柔情千种
5楼-- · 2018-12-31 15:14

REST is very abstract. It helps to have some good, simple, real-world examples.

Take for example all major social media apps -- Tumblr, Instagram, Facebook, and Twitter. They all have a forever-scrolling view where the farther you scroll down, the more content you see, further and further back in time. However, we've all experienced that moment where you lose where you were scrolled to, and the app resets you back to the top. Like if you quit the app, then when you reopen it, you're back at the top again.

The reason why, is because the server did not store your session state. Sadly, your scroll position was just stored in RAM on the client.

Fortunately you don't have to log back in when you reconnect, but that's only because your client-side also stored login certificate has not expired. Delete and reinstall the app, and you're going to have to log back in, because the server did not associate your IP address with your session.

You don't have a login session on the server, because they abide by REST.


Now the above examples don't involve a web browser at all, but on the back end, the apps are communicating via HTTPS with their host servers. My point is that REST does not have to involve cookies and browsers etc. There are various means of storing client-side session state.

But lets talk about web browsers for a second, because that brings up another major advantage of REST that nobody here is talking about.

If the server tried to store session state, how is it supposed to identify each individual client?

It could not use their IP address, because many people could be using that same address on a shared router. So how, then?

It can't use MAC address for many reasons, not the least of which because you can be logged into multiple different Facebook accounts simultaneously on different browsers plus the app. One browser can easily pretend to be another one, and MAC addresses are just as easy to spoof.

If the server has to store some client-side state to identify you, it has to store it in RAM longer than just the time it takes to process your requests, or else it has to cache that data. Servers have limited amounts of RAM and cache, not to mention processor speed. Server-side state adds to all three, exponentially. Plus if the server is going to store any state about your sessions then it has to store it separately for each browser and app you're currently logged in with, and also for each different device you use.


So... I hope that you see now why REST is so important for scalability. I hope you can start to see why server-side session state is to server scalability what welded-on anvils are to car acceleration.


Where people get confused is by thinking that "state" refers to, like, information stored in a database. No, it refers to any information that needs to be in the RAM of the server when you're using it.

查看更多
临风纵饮
6楼-- · 2018-12-31 15:14

REST is stateless and doesn’t maintain any states between the requests. Client cookies / headers are set to maintain the user state like authentication. Say Client username/password are validated by third part authentication mechanism – 2nd level OTP gerneation etc. Once user get authenticated – headers /cookies comes to rest service end point exposed and we can assume user as auth since user is coming with valid headers/cookies. Now certain info of user like IP is either maintained in the cache and after that if request is coming from same Ip (mac address) for listed resources User is allowed. And cache is maintained for some particular time which get invalidated once time lapses. So either cache can be used or DB entries can be used to persist info b/w the requests.

查看更多
怪性笑人.
7楼-- · 2018-12-31 15:15

You are absolutely right, supporting completely stateless interactions with the server does put an additional burden on the client. However, if you consider scaling an application, the computation power of the clients is directly proportional to the number of clients. Therefore scaling to high numbers of clients is much more feasible.

As soon as you put a tiny bit of responsibility on the server to manage some information related to a specific client's interactions, that burden can quickly grow to consume the server.

It's a trade off.

查看更多
登录 后发表回答