REST DELETE è davvero idempotente?


166

DELETE dovrebbe essere idempotente.

Se elimino http://example.com/account/123 , eliminerà l'account.

Se lo faccio di nuovo, mi aspetto un 404, poiché l'account non esiste più? Cosa succede se provo a ELIMINARE un account che non è mai esistito?


11
Oltre alle risposte, suggerirei di non concentrarsi troppo sulle caratteristiche idempotenti in generale: non dice nulla sulla commutatività e le richieste simultanee. Ad esempio N + 1 della stessa richiesta PUT "R1" dovrebbe avere lo stesso effetto, ma non sai se un altro client ha effettuato una richiesta PUT / DELETE "R2" diversa tra le tue, quindi mentre n R1 = R1 e m R2 = R2, qualcosa in cui si ottengono le richieste "R1" e "R2" interlacciate non necessariamente "apparirà" idempotente se si prende in considerazione solo la prospettiva di un singolo client.
Bruno,

Risposte:


188

L'idempotenza si riferisce allo stato del sistema dopo il completamento della richiesta


In tutti i casi (a parte i problemi di errore - vedi sotto), l'account non esiste più.

Da qui

"I metodi possono anche avere la proprietà di" idempotenza "in quanto (a parte errori o problemi di scadenza ) gli effetti collaterali di richieste identiche N> 0 sono gli stessi di una singola richiesta. I metodi GET, HEAD, PUT e DELETE condividono questa proprietà. Inoltre, i metodi OPTIONS e TRACE NON DOVREBBERO avere effetti collaterali, e quindi sono intrinsecamente idempotenti. "


Il bit chiave in cui si trovano gli effetti collaterali di N> 0 richieste identiche è lo stesso di una singola richiesta.

Sarebbe corretto aspettarsi che il codice di stato sia diverso, ma ciò non influisce sul concetto centrale di idempotenza: è possibile inviare la richiesta più di una volta senza ulteriori modifiche allo stato del server.


3
Effetti collaterali! == stato del server
wprl

2
@wprl C'è un dibattito su cosa sia realmente questo "effetto collaterale". Potrebbe essere "stato del server" o potrebbe essere una risposta inviata al client. leedavis81.github.io/is-a-http-delete-requests-idempotent
Alireza

Ecco un argomento secondo cui 404 su un secondo DELETE potrebbe effettivamente cambiare lo stato del server: stackoverflow.com/a/45194747/317522
Paulo Merson,

1
@PauloMerson Grazie, personalmente non penso che importi se il secondo ritorno è 404 o 200, lo stato del server non è cambiato, quindi ne sono felice.
Chris McCauley,

46

Idempotente riguarda l'effetto della richiesta, non il codice di risposta che ottieni.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.2 dice:

I metodi possono anche avere la proprietà di "idempotenza" in quanto (a parte errori o problemi di scadenza) gli effetti collaterali di richieste identiche N> 0 sono le stesse di una singola richiesta.

Sebbene sia possibile ottenere un codice di risposta diverso, l' effetto dell'invio di richieste DELETE N + 1 alla stessa risorsa può essere considerato lo stesso.


13

La distinzione importante è che idempotente si riferisce agli effetti collaterali , non a tutti gli effetti o le risposte. Se lo fai, DELETE http://example.com/account/123l'effetto è che l'account 123 è ora eliminato dal server. Questo è l'unico e unico effetto, l'unico e unico cambiamento allo stato del server. Ora supponiamo che tu faccia di nuovo la stessa DELETE http://example.com/account/123richiesta, il server risponderà in modo diverso, ma il suo stato è lo stesso.

Non è come se la richiesta DELETE avesse deciso di cambiare lo stato del server in modo diverso perché mancava l'account, come rimuovere un altro account o lasciare un registro degli errori. No, potresti chiamare la stessa richiesta DELETE un milione di volte e puoi essere sicuro che il server sia nello stesso stato della prima volta che l'hai chiamata .


7

Da HTTP RFC :

I metodi possono anche avere la proprietà di "idempotenza" in quanto (a parte errori o problemi di scadenza) gli effetti collaterali di richieste identiche N> 0 sono le stesse di una singola richiesta.

Nota che è "effetti collaterali", non "risposta".


7

Sì. Indipendentemente dal codice di risposta.

Dall'ultimo RFC per HTTP 1.1 (enfasi mio):

I metodi indipendenti si distinguono perché la richiesta può essere ripetuta automaticamente se si verifica un errore di comunicazione prima che il client sia in grado di leggere la risposta del server. Ad esempio, se un client invia una richiesta PUT e la connessione sottostante viene chiusa prima di ricevere qualsiasi risposta, il client può stabilire una nuova connessione e ritentare la richiesta idempotente. Sa che ripetere la richiesta avrà lo stesso effetto previsto, anche se la richiesta originale ha avuto esito positivo, sebbene la risposta potrebbe essere diversa.

Dice esplicitamente che la risposta potrebbe essere diversa. Ancora più importante, sottolinea la ragione del concetto: se un'azione è idempotente, il cliente può ripetere l'azione quando incontra un errore e sa che non si bloccherà nulla facendo così; in caso contrario, il client dovrà effettuare una query aggiuntiva (possibilmente GET) per vedere se la precedente è efficace, prima di ripetere in modo sicuro l'azione. Finché il server può garantire tale garanzia, l'azione è idempotente. Citazione da un altro commento :

L'idempotenza informatica riguarda la solidità di un sistema. Poiché le cose possono fallire (ad es. Interruzione di rete), quando viene rilevato un errore, come si ripristina? Il recupero più semplice è farlo di nuovo, ma funziona solo se farlo di nuovo è idempotente. Ad esempio discard(x)è idempotente, ma pop()non lo è. Si tratta di recuperare errori.


2

Penso la stessa cosa, 404 - L'account non esiste.

Potresti discutere 400 - Richiesta errata. Ma nel senso di REST l'oggetto su cui hai richiesto di eseguire un'azione non esiste. Ciò si traduce in 404.


1
Per generare un 400 dovresti sapere che l'oggetto esisteva, il che è molto irrequieto.
annakata,

1
@annakata, 400 non è nemmeno per le risorse che esistevano (forse hai 410 / andato in mente), è per cattive richieste "La richiesta non può essere compresa dal server a causa della sintassi non corretta."
Bruno,

3
@Bruno - Sono consapevole di cosa significhi, l'OP ha citato.
annakata,

1
Penso che 200 andrebbero bene. Volete che lo stato del server sia che l'account è sparito. Importa quale richiesta effettivamente l'ha fatta andare via? È ancora andato sulla seconda richiesta, lo stato del server non è cambiato.
Andy,

2

Citato dalla mia altra risposta qui :

Storicamente, RFC 2616, pubblicato nel 1999, era la specifica HTTP 1.1 più citata. Purtroppo la sua descrizione sull'idempotenza è stata vaga , il che lascia spazio a tutti questi dibattiti. Ma queste specifiche sono state sostituite da RFC 7231. Citato da RFC 7231, sezione 4.2.2 Metodi idempotenti , sottolineo il mio:

Un metodo di richiesta è considerato "idempotente" se il previsto EFFETTO SUL SERVER di più richieste identiche con quel metodo è lo stesso dell'effetto per una singola di tali richieste. Dei metodi di richiesta definiti da questa specifica, PUT, DELETE e i metodi di richiesta sicuri sono idempotenti .

Quindi, è scritto nelle specifiche, l'idempotenza riguarda tutto l'effetto sul server. Il primo DELETE che restituisce un 204 e quindi il successivo DELETE che restituisce 404, un codice di stato così diverso NON rende DELETE non idempotente. L'uso di questo argomento per giustificare un successivo ritorno 204 è semplicemente irrilevante.


OK, quindi non si tratta di idempotenza. Ma allora potrebbe essere una domanda di follow-up, cosa succede se scegliamo ancora di usare 204 nella successiva ELIMINAZIONE? Va bene?

Buona domanda. La motivazione è comprensibile: consentire al cliente di raggiungere ancora i risultati previsti, senza preoccuparsi della gestione degli errori. Direi che, restituendo 204 nella successiva ELIMINAZIONE, è una "bugia" sul lato server in gran parte innocua, che il lato client non dirà immediatamente la differenza. Ecco perché ci sono persone che lo fanno in natura e funziona ancora. Tieni presente che, tale menzogna può essere considerata semanticamente strana, perché "GET / inesistente" restituisce 404 ma "ELIMINA / inesistente" dà 204, a quel punto il cliente scoprirà che il tuo servizio non è pienamente conforme sezione 6.5.4 404 non trovata .

Ma poi, il modo previsto suggerito da RFC 7231, ovvero restituire 404 alla successiva ELIMINAZIONE, non dovrebbe essere un problema in primo luogo. Molti più sviluppatori hanno scelto di farlo. Questo è presumibilmente perché, qualsiasi client che implementa DELETE HTTP (o qualsiasi metodo HTTP, per quella materia), non supporterebbe ciecamente che il risultato avrebbe sempre successo 2xx. E poi, una volta che lo sviluppatore inizia a considerare la gestione degli errori, 404 Not Found sarebbe uno dei primi errori che viene in mente. A quel punto, si spera che giunga alla conclusione che è semanticamente sicuro che un'operazione di ELIMINAZIONE HTTP ignori un errore 404. Problema risolto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.