Dat "vrij simpel" is gewoon niet waar.
Een cookie is een
heel grof mechanisme. Het is niets meer of minder dan 1 key-value pair die in de HTTP request header voor elke request naar een domain of sub-domain wordt gestuurd.
Om zoiets 'schraals' als basis voor een stateful application te gebruiken is gewoon -heel- erg veel werk. In de huidige web frameworks moesten we wel, want het was zo'n beetje de enige houvast die we hadden (het alternatief is URL rewriting, waar je nog minder gelukkig van wordt).
Als ik even Java EE als uitgangspunt neem (dezelfde principes gelden voor andere platformen als ASP.NET, etc), dan is er allereerst de Servlet API die bovenop de cookie bouwt. Deze alleen al heeft
enkele jaren gekost om te ontwikkelen en nog wat jaren meer om te perfectioneren.
Met de servlet API kun je state al iets meer finegrained bijhouden; effectief krijg je bovenop de cookie een session scope, een request scope, en een page scope. Helaas zijn deze voor de meeste toepassingen nog steeds te grof. Session scope houdt data bij gerelateerd aan alle requests van 1 gebruiker, terwijl request scope data bij houdt gerelateerd aan 1 enkele request. Dikwijls is session scope veels te groot en request scope te klein.
Stel je de volgende situatie voor; een 3-tal pages om een hotel uit te zoeken, te selecteren en te boeken. Ik moet data tussen pages bewaren, dus ik kies voor de session scope. Een gebruiker kiest een hotel uit, maar voordat ie voor boeken kiest besluit ie in een andere tab nog even een ander hotel te bekijken. Geschrokken van de prijzen besluit ie toch maar voor de eerste keus te gaan, gaat terug naar de eerste tab en bevestigt de boeking. BOEM. Gebruiker heeft het verkeerde hotel geboekt omdat het vorige hotel nog in de sessie scope stond, en mijn server nix van de 'stiekume' navigatie van de gebruiker af weet.
Wat doen we nu dus?
We slaan de state op in de afzonderlijke pagina's en sturen deze telkens heen en weer. Alsof dit opzich al niet veel gedoe is, zit je ook nog met het feit dat je je Java datastructuren telkens moet serializen en weer de-serializen. In Java EE zit er daarom nog een layer bovenop de Servlet API; de JSF API met oa een (pluggable) StateManager die dit voor je regelt. In de JSF API heeft echter ook alweer
velen jaren werk gezeten en zal nog eens velen jaren gaan zitten om het te perfectioneren.
Met de JSF API en een simpele hulp-tag uit TomaHawk (savestate) kan ik state tussen pagina requesten bijhouden binnen 1 'conversation', maar het blijft een heel gedoe. Als ik state op de client (in de pagina's) save kan ik er niet al te grote dingen in stoppen, save ik alleen IDs op de page die verwijzen naar een structuur op de server, dan kom ik mogelijk in de problemen met memory op de server.
Namelijk, via HTTP weet ik nooit of een gebruiker de browser window of tab nog daarwerkelijk open heeft. Ik moet dus in de praktijk veels te veel dingen bewaren (dit probleem heb je overigens ook bij alleen de session scope).
Alsof dit nog niet genoeg problemen oplevert, kan de gebruiker ook nog eens de page midden in de conversation 'refreshen' door alleen in de addressbar op enter te drukken -> weg state.
Vanwege al dit handmatige gedoe met savestate tags, doen nog steeds veel mensen dit fout en blijven er veel gaten in implementaties van dergelijke conversaties zitten. Op naar de volgende layer dan maar weer: Web Beans. Deze zal een kant & klare conversation scope toevoegen. Natuurlijk kost de ontwikkeling hiervan ook
weer enkele jaren en zal het ongetwijfeld daarna nog enkele jaren kosten om de onvolkomenheden eruit te halen.
Op welk punt was state ook alweer vrij makkelijk met cookies bij te houden????
Weet je wat makkelijk, krachtig en volkomen intuïtief is?
De manier waarop het in de desktop applicaties gebeurd. Ik instantieer een dialog en geef deze een referentie (pointer) mee naar een structuur waar de data in moet komen.
That's it.
Geen gotcha's, geen moeilijke dingen. Gewoon een pointer naar een structuur die ik direct kan benaderen en die alleen voor die dialoog gebruik wordt. Wil de gebruiker tegelijk een andere dialoog open hebben, dan maak ik een compleet onafhankelijk instantie aan met een referentie naar een compleet onafhankelijke data structuur.
Een aantal van de bovengenoemde problemen is direct terug te voeren op het HTTP protocol zelf. Cookies zijn in te stellen per domain, of per sub-domain, maar niet per window of per tab en het protocol heeft zelf geen mogelijkheden om door te geven dat een window afgesloten is, of dat er een back navigatie of refresh heeft plaatsgevonden, of dat een click voortkomt uit een window waarvoor de originele request in 'sessie request nummer 23' was gedaan, etc etc etc.
Al met al is de industrie nu al een ruim tien jaar bezig om een voor de programmeur stateful model bovenop de cookie te bouwen, en hoewel we ver gekomen zijn, zijn we er nog lang niet. Misschien over 5 jaar... wie weet.
"vrij simpel" ???
It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.