Quale codice di risposta dello stato HTTP dovrei usare se nella richiesta manca un parametro richiesto?


Risposte:


388

Lo stato 422 sembra più appropriato in base alle specifiche .

Il codice di stato 422 (entità non elaborabile) indica che il server comprende il tipo di contenuto dell'entità richiesta (quindi un codice di stato 415 (tipo di supporto non supportato) è inappropriato) e la sintassi dell'entità richiesta è corretta (quindi un 400 (richiesta non valida) ) il codice di stato non è appropriato) ma non è stato in grado di elaborare le istruzioni contenute. Ad esempio, questa condizione di errore può verificarsi se un corpo di richiesta XML contiene istruzioni XML ben formate (cioè sintatticamente corrette), ma semanticamente errate.

Dichiarano che xml non valido è un esempio di sintassi errata (che richiede un 400). Una stringa di query non valida sembra analoga a questa, quindi 400 non sembra appropriato per una stringa di query ben formata a cui manca un parametro.

UPDATE @DavidV sottolinea correttamente che questa specifica è per WebDAV, non per HTTP di base. Ma alcune API non WebDAV popolari usano comunque 422, per mancanza di un codice di stato migliore ( vedi questo ).


2
IMO lo userei per quando il valore nella stringa della query era errato, non quando c'era un valore extra o un valore mancante. vale a dire. In attesa di un'e-mail e il suo valore è "123123"
Derek Litz il

2
Tendo a pensare ai parametri GET e POST come alla firma del metodo del percorso URL, quindi 404 ha senso per me. In un'API RESTful destinata al consumo pubblico è prudente restituire i parametri mancanti / extra. Nel contesto di un URL, i parametri della stringa di query sono in genere importanti per identificare una risorsa e parametri extra o mancanti rappresentano una risorsa che non esiste, senza ipotesi. Naturalmente, ci sono compromessi con solidità essendo espliciti e parametri opzionali rendono una risorsa potenzialmente altrettanto vulnerabile all'errore silenzioso. Poi c'è l'usabilità ...
Derek Litz il

13
La specifica a cui si fa riferimento è per WebDAV e non è la specifica standard HTTP.
David V,

1
@Kelvin Grazie per aver sottolineato quel post sul blog. È utile vedere che Twitter, ad esempio, sta usando 422. Penso che la risposta potrebbe essere migliore se chiarisci che la specifica è WebDAV nella prima riga. Quando ho letto la tua risposta per la prima volta, ho pensato che intendevi le specifiche standard HTTP fino a quando non ho seguito il link.
David V,

3
Vale la pena leggere: bennadel.com/blog/… Non userei nemmeno 422 per i parametri mancanti. Penso che 400sia più appropriato.
Zelphir Kaltstahl,

184

Non sono sicuro che ci sia uno standard stabilito, ma avrei usato 400 Bad Request , che l'ultima specifica HTTP (dal 2014) documenta come segue :

6.5.1. 400 Richiesta non valida

Il codice di stato 400 (Richiesta non valida) indica che il server non può o non elabora la richiesta a causa di qualcosa che viene percepito come un errore client (ad es. Sintassi della richiesta non valida, framing del messaggio di richiesta non valido o instradamento della richiesta ingannevole).


65
400 Bad Requestintende indicare problemi a livello di protocollo, non errori semantici. Se dirottiamo i codici di stato HTTP per indicare errori a livello di applicazione (piuttosto che a livello di protocollo), perché non andare fino in fondo e utilizzarli 412?
Matt Zukowski,

36
L'implementazione di OAuth 1.0 di Google concorda con questa risposta. Viene fornita una risposta 400 quando i parametri POST mancano o non sono supportati: code.google.com/apis/accounts/docs/OAuth_ref.html
Tom,

1
@ matt-zukowski: "412: la condizione preliminare fornita in uno o più campi dell'intestazione della richiesta è stata valutata falsa quando è stata testata sul server." da RFC2616 - Se si tratta di un POST, i parametri si trovano nel corpo della richiesta e non nei campi header-richiesta. Tecnicamente, il metodo GET invia i suoi parametri nelle intestazioni della richiesta ma preferirei avere un po 'di coerenza?
Toong

6
@MattZukowski 400 è un codice di stato a livello di applicazione. Se osservi la riformulazione nella versione bozza di RFC 7231, vedrai che. Sfortunatamente, il testo dell'ultima versione non è così chiaro perché l'autore delle ultime modifiche ha inventato anche 422.
Darrel Miller,

9
@DarrelMiller ha ragione ( collegamento diretto ): "Il codice di stato 400 (Bad Request) indica che il server non può o non elabora la richiesta a causa di qualcosa che viene percepito come un errore client (ad es. Sintassi della richiesta non corretta, messaggio di richiesta non valido framing o instradamento di richieste ingannevoli). " A seconda della semantica e delle aspettative di estensibilità (sarà possibile un giorno emettere una richiesta senza il parametro?) Allora solo 400 e 404 sembrano appropriati nell'HTTP standard. Altrimenti, inventa un nuovo codice per la tua API, ma non sovraccaricare la semantica.
TNE

31

L' API WCF in .NET gestisce i parametri mancanti restituendo un HTTP 404errore "Endpoint non trovato" quando si utilizza webHttpBinding .

Il 404 Not Foundgrado di dare un senso se si considera il servizio di web nome del metodo con la sua firma parametro. Cioè, se si espone un metodo di servizio Web LoginUser(string, string)e si richiede LoginUser(string), quest'ultimo non viene trovato.

Fondamentalmente ciò significherebbe che non è possibile trovare il metodo del servizio Web che si sta chiamando, insieme alla firma del parametro specificata.

10.4.5 404 non trovato

Il server non ha trovato nulla corrispondente all'URI di richiesta. Non viene fornita alcuna indicazione se la condizione è temporanea o permanente.

Il 400 Bad Request, come suggerito Gert , rimane un codice di risposta valida, ma penso che è normalmente usato per indicare i problemi di livello inferiore. Potrebbe essere facilmente interpretato come una richiesta HTTP non valida, forse intestazioni HTTP mancanti o non valide o simili.

10.4.1 400 Richiesta non valida

La richiesta non è stata compresa dal server a causa di una sintassi non corretta. Il client NON DOVREBBE ripetere la richiesta senza modifiche.


Questo è ciò che CherryPy fa per impostazione predefinita.
Derek Litz,

Che dire di quando gestisci una richiesta di post in cui stai accettando un modello e manca una parte del modello? In quel caso non ottieni un 404. Invece ottieni un modello che non è valido se non sbaglio e devi decidere cosa fare ora.
Shane Courtrille,

1
Questa interpretazione sembra un tratto ed esprime un RPC piuttosto che un pov REST. L'URI è l'identificatore, esiste ed è stato trovato. Ciò che viene inviato nel corpo non fa parte dell'identificatore di risorsa. 422 è più appropriato.
Giona

404 è la risposta giusta, basta andare a modificare alcuni URL sul web per trovare il consenso!
jenson-button-event,

8

È possibile inviare un codice 400 Bad Request. È uno dei codici di stato 4xx più generici, quindi puoi usarlo per indicare ciò che intendi: il client sta inviando una richiesta in cui mancano informazioni / parametri richiesti dall'applicazione per elaborarlo correttamente.


7

In uno dei nostri progetti API decidiamo di impostare uno stato 409 su qualche richiesta, quando non possiamo riempirlo completamente al 100% a causa del parametro mancante.

Il codice di stato HTTP "409 Conflict" è stato per noi un buon tentativo perché la sua definizione richiede di includere informazioni sufficienti affinché l'utente possa riconoscere l'origine del conflitto.

Riferimento: w3.org/Protocols/

Quindi, tra le altre risposte come 400 o 404, abbiamo scelto 409 per imporre la necessità di esaminare alcune note nella richiesta utile per impostare una nuova e giusta richiesta.

In ogni caso, il nostro caso è stato particolare perché abbiamo bisogno di inviare alcuni dati se la richiesta non era completamente corretta, e dobbiamo imporre al cliente di guardare il messaggio e capire cosa non andava nella richiesta.

In generale se abbiamo solo qualche parametro mancante andiamo per un 400 e un array di parametri mancanti. Ma quando abbiamo bisogno di inviare qualche informazione in più, come un caso particolare e vogliamo essere più sicuri che il cliente se ne occuperà, inviamo un 409


2
Questo è chiaramente sbagliato. 409 è per problemi di concorrenza poiché @ MaximeGélinas indica situazioni OR in cui una risorsa è già presente e non sono consentiti duplicati.
gimlichael,

Per specifica, "Il codice di stato 409 (Conflitto) indica che non è stato possibile completare la richiesta a causa di un conflitto con lo stato corrente della risorsa di destinazione." . Usarlo per un parametro mancante è semplicemente sbagliato; è un tipo di errore totalmente diverso.
Mark Amery il

5

Di solito vado per 422 (entità non elaborabile) se qualcosa nei parametri richiesti non corrispondesse a quello richiesto dall'endpoint API (come una password troppo breve) ma per un parametro mancante andrei per 406 (inaccettabile).


8
Bene, 406 Unacceptable viene utilizzato con l'intestazione Accept (se il server non può inviare la risposta, il client capirà). "La risorsa identificata dalla richiesta è solo in grado di generare entità di risposta con caratteristiche di contenuto non accettabili in base alle intestazioni di accettazione inviate nella richiesta." . Sono bloccato con 422 in quanto non esiste una scelta "giusta" con le specifiche correnti: - /
JakubKnejzlik

L'uso di 406 per questo è sbagliato. Un codice 406 non significa che la richiesta non era accettabile; significa che non puoi soddisfare la richiesta perché le risposte che sei in grado di servire sono quelle che il cliente troverebbe inaccettabili, in base alle intestazioni Accetta che ha inviato nella richiesta. (Ad esempio, la richiesta inclusa Accept-Language: de, indicando che accetterà solo risposte in tedesco, ma le uniche versioni del documento richiesto che il tuo server ha disponibile sono in inglese o francese.) Usarlo per indicare un parametro mancante nella richiesta non è corretto, secondo la definizione in spec.
Mark Amery il

3

Per gli interessati, Spring MVC (almeno 3.x) restituisce un 400 in questo caso, il che mi sembra sbagliato.

Ho testato diversi URL di Google (account.google.com) e rimosso i parametri richiesti e in genere restituiscono un 404 in questo caso.

Vorrei copiare Google.


18
Perché Google non significa automaticamente che Google lo fa nel modo giusto!
rve

4
Sono d'accordo, non necessariamente "giusto", ma a volte ciò che è giusto e ciò che è sensato sono due cose diverse. Comunque .. fino al lettore :)
Neromancer

Alcune API di Google restituiscono un 400, ad esempio github.com/google/google-api-nodejs-client/issues/404
Dennis,

che è sbagliato (e perché spring mvc non è conforme a jax-rs)
jenson-button-event

3

Si potrebbe sostenere che a 404 Not Founddovrebbe essere usato poiché non è stato possibile trovare la risorsa specificata.


3
Questo è il comportamento predefinito di Java JAX-RS quando un parametro di query non può essere convertito nel tipo di dati corretto. Non sono d'accordo però. La risorsa è stata trovata: i parametri di query servono per filtrare la risorsa e uno dei filtri è stato fornito con un valore inaccettabile. Penso che questo corrisponda a 422 Entità non elaborata più vicina e 400 Seconda richiesta più vicina.
Ryan,

è il comportamento predefinito di jax-rs perché è il comportamento giusto!
jenson-button-event,

L'uso di un 404 è ragionevole quando il parametro della stringa di query ha lo scopo di identificare una risorsa, è stato dato un valore, ma quel valore non corrisponde a una risorsa esistente - ad esempio, se stai richiedendo example.com/show-user -profile? user_id = 123 e l'utente 123 non esiste. Ma non è questa la domanda posta; riguardava lo scenario in cui un parametro richiesto è stato completamente omesso. Non vedo come ciò non corrisponda a una risorsa specificata.
Mark Amery il

2

Uso spesso un errore 403 proibito. Il ragionamento è che la richiesta è stata compresa, ma non ho intenzione di fare come richiesto (perché le cose sono sbagliate). L'entità response spiega cosa non va, quindi se la risposta è una pagina HTML, i messaggi di errore si trovano nella pagina. Se si tratta di una risposta JSON o XML, le informazioni sull'errore sono presenti.

Da rfc2616 :

10.4.4 403 Proibito

Il server ha compreso la richiesta, ma si rifiuta di soddisfarla.
L'autorizzazione non aiuterà e la richiesta NON DOVREBBE essere ripetuta.
Se il metodo di richiesta non era HEAD e il server desidera rendere
pubblico il motivo per cui la richiesta non è stata soddisfatta, DOVREBBE descrivere il motivo del rifiuto nell'entità. Se il server non desidera rendere disponibili queste informazioni al client, è
possibile utilizzare invece il codice di stato 404 (Not Found).


4
All'inizio suona bene, anche se lo assocerei naturalmente a errori di autenticazione o di autorizzazione. Inoltre, le specifiche suggeriscono ciò in cui si dice "se il server non desidera rendere queste informazioni disponibili al client". Anche quel 404 potrebbe essere un'opzione migliore.
Andrei

21
Questa è un'idea terribile, anche se tecnicamente valida. 403 è universalmente usato per le risposte agli errori di autenticazione e confonderai i tuoi clienti se provi a usarlo per indicare errori nei parametri. Ad esempio Twitter fa questo - 403 viene utilizzato sia quando si forniscono credenziali OAuth non valide, sia quando c'è qualcosa di semanticamente sbagliato nella richiesta - ed è una fonte costante di confusione per i client API.
Matt Zukowski,

1
@MattZukowski bene, è solo sbagliato. Le specifiche dicono Authorization will not help, quindi Twitter non dovrebbe inviarlo per credenziali OAuth non valide.
torvin,

Invece @torvin Twitter dovrebbe inviare un 401 Unauthorized. Tuttavia, puoi capire perché non lo fanno se guardi le descrizioni dei documenti MDN di questi due codici, che sono molto simili.
Agi Hammerthief,

-1

Solo per utilizzare ASP.NET Core come riferimento o esempio, ASP.NET Core ti consente di impilare un controller con azioni, ecco come appare l'azione "Dettagli".

    // GET: Cars/Details/5
    public async Task<IActionResult> Details(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }

        var car = await _context.Cars.FirstOrDefaultAsync(m => m.CarId == id);
        if (car == null)
        {
            return NotFound();
        }

        return View(car);
    }

Se il parametro idnon è impostato, restituisce 404 Not Found.


-5

Restituisce un 404 , il che significa che non è stato possibile trovare la risorsa.

Prova a modificare un URL di un sito che contiene un ID. Ne ho provati alcuni:

  • problema repo gitub
  • pagina di confluenza
  • vista del prodotto amazon
  • elenco ebay
  • articolo di notizie bbc

Tutti restituiscono 404, anche perché quegli sviluppatori stanno interpretando correttamente lo standard, cosa che la risposta qui e molti altri non lo sono!


1
Credo che la maggior parte degli sviluppatori definisca "parametro" come una delle coppie nome / valore in una stringa di query o forma un corpo POST. Una richiesta di rilascio repo Github non contiene questo.
Kelvin,

@Kelvin noi sviluppatori includiamo anche i parametri del percorso nell'elenco. se QUALUNQUE parametro url è obbligatorio, rappresenta la posizione di una risorsa e non è incluso, è necessario restituire 404. Questo esclude il requestBody.
jenson-button-event,

-6

Vorrei andare con un 403.

Da RFC 2616 - Hypertext Transfer Protocol - HTTP / 1.1

403 proibito

Il server ha compreso la richiesta, ma si rifiuta di soddisfarla. L'autorizzazione non aiuterà e la richiesta NON DOVREBBE essere ripetuta. Se il metodo di richiesta non era HEAD e il server desidera rendere pubblico il motivo per cui la richiesta non è stata soddisfatta, DOVREBBE descrivere il motivo del rifiuto nell'entità. Se il server non desidera rendere disponibili queste informazioni al client, è possibile utilizzare invece il codice di stato 404 (Not Found).

Dovresti descrivere la ragione del fallimento nella tua risposta. Se preferisci non farlo, usa solo 404.


3
downvoted perché questa è una risposta duplicata. Considera di aggiungere la tua ultima frase come commento alla risposta precedente che offre di utilizzare 403
utente il
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.