2010-04-22 16 views
5

Sto costruendo un archivio dati RESTful e sfruttando GET e PUT condizionali. Durante un PUT condizionale il client può includere l'Etag da un precedente GET sulla risorsa e se la rappresentazione corrente non corrisponde, il server restituirà il codice di stato HTTP di 412 (Precondition Failed). Nota questo è un server/protocollo basato su Atom.HTTP Response 412 - puoi includere il contenuto?

La mia domanda è, quando restituisco lo stato 412 posso anche includere la nuova rappresentazione della risorsa o l'utente deve emettere un nuovo GET? Le specifiche HTTP non sembrano dire sì o no e nemmeno le specifiche Atom (sebbene il loro esempio mostri un corpo entità vuoto sulla risposta). Sembra piuttosto inutile non restituire la nuova rappresentazione e fare in modo che il cliente lo OTTIENE in modo specifico. Pensieri?

risposta

2

Sebbene i GET condizionali e i PUT siano riassunti come "richieste condizionali", sono molto diversi dal punto di vista concettuale. I GET condizionali sono un'ottimizzazione delle prestazioni e i PUT condizionali sono un meccanismo di controllo della concorrenza. È difficile discuterli insieme.

Alla domanda relativa al GET condizionale: se si invia GET e si include un'intestazione If-None-Match il server invierà 200 OK se la risorsa è stata modificata e 304 non modificato se non lo ha fatto (se la condizione non è riuscita) . 412 deve essere usato solo con PUT condizionali.

AGGIORNAMENTO: Sembra che abbia letto male la domanda. Per quanto riguarda il 'refresh' della copia locale su un PUT condizionale fallito: potrebbe essere che una cache abbia già la versione più recente e che il tuo refresh-GET sia servito da qualche cache. Avere il server restituisce l'entità corrente con il 412 potrebbe effettivamente darti prestazioni peggiori.

+0

Sì, non stavo seguendo la tua risposta iniziale, ma il tuo punto sull'eventuale cache intermedia è molto buono. Onestamente la migliore risposta che ho visto finora. – Gandalf

3

No, tecnicamente non dovresti. I codici di errore generalmente indicano che qualcosa è andato storto. Sebbene nulla ti impedisca di restituire il contenuto (e in effetti, alcuni errori come un 404 restituiscono una bella pagina che dice che non hai trovato quello che stai cercando), il punto della risposta non è quello di restituire altro contenuto, ma per restituire qualcosa che ti dice cosa c'era che non andava. Tecnicamente non dovresti restituire i dati perché hai passato If-None-Match: etag (presumo che sia quello che hai passato?)

In un'altra nota, hai davvero bisogno di ottimizzare una chiamata http aggiuntiva?

Più penso a questo, più sono convinto che sia una cattiva idea - Hai intenzione di restituire il contenuto su altri errori? Mettere la semantica è PUT. GET semantica dovrebbe essere utilizzata per GET.

+0

L'ottimizzazione di una chiamata HTTP può facilmente significare milioni di richieste salvate al giorno - quindi sì, sarei favorevole.La semantica del POST è POST, ma è del tutto valido restituire il contenuto su un POST, quindi non sono d'accordo con la tua tesi. – Gandalf

+0

Non stai facendo un post, stai facendo un put. La semantica del POST è diversa da entrambe, ed è valida per restituire il contenuto di un post, perché lo stato della semantica: La differenza fondamentale tra le richieste POST e PUT è riflessa nel diverso significato della richiesta-destinazione. L'URI in una richiesta POST identifica la risorsa che gestirà l'entità inclusa . Tale risorsa potrebbe essere un processo di accettazione dati, un gateway in qualche altro protocollo o un'entità separata che accetta annotazioni . Ciò significa che il POST ha la flessibilità di restituire contenuto non correlato all'URI. – Kylar

2

Se il numero di richieste aggiuntive sostenute, a causa di una richiesta aggiuntiva dopo un conflitto di aggiornamento, è abbastanza significativo da causare problemi di prestazioni, suggerirei che si potrebbero avere problemi con la granularità delle risorse.

Ti aspetti veramente milioni di volte al giorno che più utenti modificheranno la stessa risorsa contemporaneamente? Forse è necessario memorizzare le modifiche delta alla risorsa, invece di aggiornare direttamente la risorsa. Se c'è davvero molta contesa per queste risorse, gli utenti continueranno a lavorare costantemente su dati non aggiornati.

Se il tuo problema era che la tua risorsa contiene la data dell'ultima modifica e l'ultimo utente modificato e dovevi fare una GET dopo ogni PUT, allora sarei più convinto della necessità di stravolgere le regole.

Tuttavia, penso che il successo in termini di prestazioni della richiesta aggiuntiva valga la pena per la chiarezza per lo sviluppatore del cliente.

Problemi correlati