PRG. Post/Redirect/Get design pattern

L’argomento è vecchiotto (il pattern risale al 2004) ma ogni tanto qualcuno se ne riesce col classico problema del “doppio submit” dei forms html, quindi prendo lo spunto per scrivere qualcosina.

Il problema

L’utente esegue il submit di un form tramite richiesta HTTP POST, sul server eseguiamo delle operazioni che alterano il nostro modello dei dati, tipo una INSERT in un database sql; l’operazione va a buon fine, e noi lo comunichiamo al client in risposta alla sua richiesta. L’utente (non chiedetemi perchè) effettua il refresh della pagina, oppure esegue il back nel suo browser; il browser avvisa l’utente che sta effettuando di nuovo il submit, ma lo fa violando una decina di canoni di usabilità del software. A questo punto o l’utente fugge spaventato (male) o riposta i dati eseguendo una seconda INSERT nel database (malissimo).

La soluzione

Potremmo usare il metodo GET invece del POST nel nostro form HTML. Dico potremmo perchè in realtà non lo faremo! Vogliamo essere RESTful e così facendo violeremmo la semantica del GET! Si passa quindi all’uso del pattern PRG: il browser effettua una richiesta POST, il server elabora i dati e invece di ritornare immediatamente una risposta effettua una REDIRECT alla pagina che mostra all’utente l’esito dell’operazione; tramite una GET, poi, il server può comunicare alla pagina dei risultati lo stato attuale del modello dei dati.

Le conseguenze

Cosa succede una volta applicato il PRG? Siamo sulla pagina dei risultati, generata con una richiesta di tipo GET. Se si effettua il refresh della pagina viene ripetuta la richiesta, senza danni al modello dei dati sul server e senza che l’utente riceva strani messaggi dal browser. Se si esegue il back nel browser si torna al form, da qui con un forward si torna alla pagina dei risultati. Liscio come l’olio.

Rimane il “problema” che l’utente potrebbe fare un back dalla pagina dei risultati, tornare al form e ripostarlo. Questa problematica secondo me esula dal PRG, e può essere gestita in maniera più o meno elegantecon l’utilizzo di cookies e sessioni; rimando il lettore ai riferimenti qui di seguito per approfondire.

Riferimenti

Redirect After Post, Michael Jouravlev, Agosto 2004

GET after POST Adam Vandenberg