2009-06-23 6 views
6

sto sviluppando un'API REST, e mi chiedo quanto segue:utilizzando HTTP PUT, ma non sostituire completamente l'entità

voglio usare HTTP PUT per aggiornare alcune entità nel webservice. Il formato sarà un corpo con codifica elettronica. È accettabile aggiornare solo i campi che sono stati effettivamente specificati, piuttosto che l'intera entità?

Sto chiedendo, perché PUT sarebbe un metodo molto conveniente per fare alcuni aggiornamenti, ma non voglio che rimuovano i campi se gli capita di sbagliare alcuni di essi. Inoltre, non voglio forzare l'implementor a fare sempre prima un GET e copiare ogni singolo campo che potrebbero non utilizzare.

risposta

2

Inserire è solo per la sostituzione completa. C'è una proposta per il verbo PATCH per risolvere il problema che hai (http://www.ietf.org/internet-drafts/draft-dusseault-http-patch-14.txt)

Patch, tuttavia, potrebbe non essere quello che vuoi. Ciò che viene inviato è una risorsa di aggiornamento che può fare cose come i contatori di incremento e quindi, a differenza di put, non è idempotente.

È possibile esporre ciascun campo come risorsa e eseguire più posizionamenti in ogni campo. È possibile effettuare il pipeline per mitigare la latenza aggiuntiva.

+0

PATCH è, come hai detto, ancora una bozza .. PUT multipli sarebbero molto fastidiosi :) Potrei usare POST per tutto questo invece .. PUT sarebbe molto più bello però .. – Evert

+0

Concordato che il POST è probabilmente la tua migliore opzione - ma considera le piazzate in pipeline se il numero di campi aggiornati è piccolo rispetto al numero totale di campi. –

1

Direi che può avere senso. Considero l'idea REST molto flessibile, quindi se aggiorni un'entità perché non solo trasferisci i campi che devono essere aggiornati nella tua implementazione. È vero, però, che ha bisogno di più sforzi sul lato server. È necessario verificare se l'entità è disponibile e può essere aggiornata con i dati trasferiti e sono necessari controlli di convalida (anziché dati orientati ai documenti senza schema).

<!-- PUT books/1337 --> 

<book> 
    <title>Hello</title> 
    <author>John Doe</author> 
</book> 

<!-- PUT books/1337 --> 

<book> 
    <title>Hello here I am</title> 
</book> 
+0

L'idea REST può essere flessibile, ma afferma che i verbi utilizzati devono avere un comportamento uniforme. HTTP è abbastanza specifico su come PUT dovrebbe essere gestito.Il consenso è che PUT dovrebbe sostituire l'entità e non fare ciò che stai suggerendo. –

+0

Yepp Sono d'accordo che POST è la scelta migliore allora. Per quanto flessibile, non bisognerebbe infrangere le idee/regole di base. – Daff

4

Si potrebbe semplicemente POSTARE le proprietà aggiornate alla risorsa. Ricorda POST è il verbo catch-all che puoi usare per fare tutto ciò che devi fare quando gli altri verbi non funzionano per te.

Partenza articolo di Roy It's ok to use POST

1

mi è mai piaciuto una delle soluzioni per gli aggiornamenti parziali, sia. Se stavo progettando un servizio web per uso diffuso, probabilmente andrei con POST. Se fosse usato da un numero abbastanza piccolo di persone, cioè potrei parlare con tutte le persone che mi aspettavo di chiamarlo, ho avuto due idee diverse per affrontarlo.

  1. PUT ad una nuova risorsa 'aggiornamento'. In pratica registrerebbe l'aggiornamento che si desidera applicare e quindi si occuperà di non applicare i duplicati. Immagino che questo funzioni in qualche modo come un sistema di controllo delle versioni che mantiene un elenco di patch/changeset e diventa piuttosto complicato ogni volta che provo a pensare a tutti i casi d'angolo.

  2. PUT alla risorsa, ma non modificare alcun campo che non è presente. È necessario che i campi che si desidera NULL siano presenti con un attributo speciale che indica che si desidera NULL. Questo sembra molto più pratico, ma non si accorda molto bene con il consenso sul fatto che PUT dovrebbe essere un aggiornamento completo.

Se qualcuno ha indicazioni su discussioni di idee simili, modificare/commentare di conseguenza.

+0

Ho gli stessi sentimenti ... Anche se potrebbe non essere esattamente ciò a cui PUT era destinato; Farò comunque post-processing sulla richiesta (entrerà nel DB e avrà diverse rappresentazioni/formati quando le persone lo richiederanno). Ho solo la sensazione che questo è il modo in cui le persone si aspettano che funzioni. Voglio anche mantenere il POST solo per creare elementi figlio (ad es .: inserti) quindi mi sento alla fine è il più semplice – Evert

+0

@Hank - Qual è la ragione per usare PUT se stai per violare la sua semantica? Se metto qualcosa, GET dovrebbe restituirlo. Perché non usare il POST indipendentemente da chi lo consuma? –

+0

@Tony Per prima cosa, il PUT sarebbe ancora idempotente e il POST non lo farebbe ancora. Inoltre, il mio processo di pensiero naturale * non * cancella cose che non sono presenti; per me quella è una NON-CURA, non un DELETE; DELETE/NULL dovrebbe essere esplicito, non implicito. Se il sovraccarico della comunicazione è piccolo, cioè poche persone coinvolte, preferirei che concordassimo su ciò che si adatta al mio naturale processo di pensiero piuttosto che su quello che considero un difetto progettuale. Il sovraccarico della comunicazione è il motivo per cui non lo farei per un vasto pubblico; a quel punto, l'overhead extra supererebbe i benefici di ridurre il mio attrito mentale. –