Thinking about RESTful dynamic web applications
"For example, I do want to say, "Welcome, John" on the top of every page
once you've signed in. But I'm currently planning on attempting to have only
two representations of each page, one for signed in users and one for
the Welcome greeting and insert it dynamically on the page. If a client
because that's one of the two representations sent from the server, but they
won't see their name in a welcome message. To me that's a graceful
for improved cache effectiveness. (The signed in/anonymous representations
only work for clients with cookies enabled. Otherwise I have to fall back to
URL rewriting, where the caching will be less effective, because I'll have a
different URI per resource per session.)"
Obviously it would need to be idententical for every client accessing the ressource. We'd otherwise get different ETags and instantly loose the whole caching point. That is, we can't include something like
for the simple reason that it's different from the URL any other user would be served with.
Probably I'm blind but I can't see any other reasonable way than to use a cookie here. But aren't cookies unRESTfully evil? Luckily there are some statements from highly respected RESTafarians ;) who declare that cookies are ok to use as long they don't mean to store application state on the server. From my point of view there's nothing against it.
Instead of tailoring the whole page on the server (producing uncachable pages) we'd pass the same sceleton (or "shell") page to every client - along with a cookie that does not need to store anything else than a unique ID on the client.
Afterwards the client can pull further content (be it a simple message or full fledged "components") from the server because she now knows how to construct the apropriate URLs:
var url = 'http://www.domain.com/user/' + cookie.userId + '/welcome.js';
Again, welcome.js could now be cached - or (in case we'd want to get more nifty) itself be a "shell" pulling further, specialized content.
I don't know if this is what Bill meant by "conversational state" - I'd simply call that a "session" (which has been a recent and very interesting debate on the above mentioned mailing list). The server "initializes" the client (by issuing the cookie) to use certain ressources for further lookups. This "initialization" will remain as long as the cookie remains. There's no particular "state" to be maintained on the server.
The REST FAQ over at blueoxen.net explains it like this:
Interaction is stateless when a single request can be processed without knowing which requests have been made previously. Consider an authenticated request for a person's phone number. You could have a conversation that goes like this:
Me: I would like your phone number, please. You: Who are you? Me: I'm your old buddy Frank, don't you recognize me? You: Oh, well then my number is...
That's a stateful conversation because I supplied my credentials without resubmitting my request. This next conversation is stateless:
Me: I would like your phone number, please. You: Who are you? Me: I'm your old buddy Frank, and I would like your phone number please. You: Oh, well then my number is....
In our "Welcome John!" example the dialog would look like this:
Client: "Hi! I think you know me by my [username] and [password]" Server: "Year, hi again! You'll find your stuff by using the ID 1." Client: "Cool. Than please hand me over the welcome message with the ID 1." Server: "Ok, here it is: Welcome John!"
As far as I can see two issues remain. One is authorization to restricted ressources. I'd love to use the HTTP auth scheme here also. I've never done so because of the usual problems with it - like being nasty, not styleable, no logout etc. But on the one hand, I think this should be possible to solve with some JS/AJAX style approach. On the other hand it seems as if I'm going to be on Ruby on Rails with my next upcoming project and I don't know about how this would actually fit together.
The other one is degradation.
For some projects a noscript message could do it - like:
<noscript> Too bad! With JS turned on, you could [rule the world]. </noscript>
Another approach could have the cachability of the served pages itself depend on whether the client hast JS turned on or not - and serve a different etagged page to people without JS along with the appropriate headers to prevent these pages from being cached at all.
if client.isJsEnabled(): headers(cachable) + shell page else: headers(no-cache) + classical user-customized page endif
By the way, from reading this article I think, this same issue evolves with Ruby on Rails concerning these nifty "flash" messages when using page caching.