Nella progettazione dell'API, se richiedo un elenco di oggetti per ID e uno di questi ID non è valido / eliminato, in caso di esito negativo della richiesta?

0

Diciamo che sto richiedendo un elenco di ID per il quale mi piacerebbe ricevere le entità DB rilevanti (ad esempio my-restaurant-api.com?restaurants=1,2,3 ).

In questo esempio, diciamo che l'ID 3 è stato cancellato e non dovrebbe essere restituito.

Dovrebbe la risposta dell'API:

  1. restituisce un 404
  2. restituisce un 200 e include le entità esistenti
  3. restituisce un 404 e include entità esistenti
  4. restituisce un 200 e include un messaggio di eccezione ed entità esistenti

O, in questo caso, dovrebbe spettare al consumatore determinare cosa è meglio per l'applicazione? C'è una risposta ?

    
posta Himmel 02.11.2018 - 21:17
fonte

4 risposte

2

Restituisce 200 OK e (facoltativamente) includono alcune informazioni di stato nel tuo JSON che indicano che alcune entità non esistono più.

Se non si restituiscono entità, si costringe l'utente a creare una nuova richiesta che esclude le entità mancanti. Basta notare nella documentazione che il tuo endpoint non restituirà entità che non esistono più, il che è comunque il comportamento più intuitivo.

    
risposta data 03.11.2018 - 18:20
fonte
1

Lascia che il client specifichi usando un'intestazione HTTP come deve essere rigorosa (per esempio in OData c'è un'intestazione "continua su errore" per le richieste batch).

Se il client non desidera la modalità rigorosa, restituire semplicemente 200 con le entità esistenti.

Se il cliente desidera la modalità rigorosa, restituisce 400 con le entità valide e le informazioni di errore che indicano quali entità non sono state trovate.

Il motivo per cui suggerirei 400 anziché 404 è che i tuoi ID fanno parte della query e non fanno parte del percorso dell'URL. Quindi non è come se il client tentasse di accedere a una "risorsa" che non esiste (nel senso più stretto), è solo che alcuni dati nella richiesta non sono validi. Se l'ID faceva parte del percorso URL, allora 404 sarebbe più appropriato. Riconosco comunque che c'è una linea sottile qui e questo è un po 'aperto all'interpretazione.

    
risposta data 03.11.2018 - 20:37
fonte
0

Idealmente, un URL incl. qualsiasi parametro di query dovrebbe rappresentare una risorsa . Ma il tuo URL rappresenta una raccolta di risorse. Questo tipo di richieste batch è comune, ma per quanto riguarda HTTP, ora sei da solo. Non esiste un approccio chiaramente valido per gestire l'errore parziale di una richiesta batch.

Un paio di soluzioni:

  • Non eseguire richieste batch. Grazie a HTTP / 2 è possibile inviare più richieste sulla stessa connessione in parallelo, e grazie alla programmazione asincrona è diventato più facile gestire più richieste in sospeso in modo efficiente. Un vantaggio è che le risposte non verranno ritardate se un elemento della raccolta richiede più tempo.

  • Pensa con più attenzione a come l'API verrebbe utilizzata e fai in modo che i codici di risposta si riferiscano alla raccolta, piuttosto che agli elementi della raccolta. La raccolta sarebbe inutilizzabile se mancasse qualche elemento? Se è così, scegli un errore 4xx. Oppure il fallimento di una richiesta secondaria è accettabile? In questo caso, contrassegna l'elemento come mancante nella risposta (altrimenti riuscita).

  • Accetta di eseguire richieste batch e inserisci le risposte secondarie in una busta che gestisca gli errori a livello individuale. In modo efficace, crea il tuo protocollo su HTTP. Il codice di stato HTTP è quindi in gran parte irrilevante. Ad esempio, la tua richiesta potrebbe restituire:

    [
      { "id": "1", "success": true, "data": { ... } },
      { "id": "2", "success": true, "data": { ... } },
      { "id": "3", "success": false, "error": "..." }
    ]
    
  • Invece di creare il tuo protocollo su un'API pseudo-REST, usa un approccio esistente come GraphQL.

risposta data 04.11.2018 - 13:31
fonte
-4

ok lasciati andare. Citi l'url:

my-restaurant-api.com?restaurants=1,2,3

consente di correggere gli errori evidenti con questo. Prima il protocollo e le barre mancanti

https://my-restaurant-api.com/?restaurants=1,2,3

Ora consente di aggiungere un percorso, o "risorsa"

https://my-restaurant-api.com/restaurants/id=1,2,3

Ora la stringa di query è problematica. L'id non è "1,2,3" quindi la struttura corretta è:

?id=1&id=2&id=3

Ma puoi vedere come questo può facilmente incorrere in problemi di lunghezza massima dell'URL. La migliore pratica è quella di inviarlo nel corpo e quando si invia un corpo si dovrebbe essere POST. Dal momento che non esegui il POST di un ristorante, vorremmo cambiare il percorso verso qualcosa che corrisponde a ciò che stiamo cercando di fare, quindi:

POST https://my-restaurant-api.com/GetRestaurantsByIds

{
    "Ids" : ["1","2","3"]
}

Solo ora possiamo iniziare a parlare di errori sensibili.

First off non usa mai 404 per indicare "hai raggiunto l'endpoint giusto ma il risultato dell'operazione era un set vuoto". Quindi questo è chiaro

Una risposta non di errore è una matrice JSON di oggetti ristorante, giusto? quindi una matrice vuota è la risposta "nulla trovata" corretta.

Ora, nel caso di risultati parziali, potremmo considerare la richiesta come una ricerca, "seleziona * dai ristoranti dove id in (...)", nel qual caso ci si aspetterebbe di restituire una risposta vuota o parziale.

O potremmo trattarlo come un comando "I miei tre migliori ristoranti sono questi!" e ci aspetteremmo un errore se ce ne fossero solo due. ad esempio

500 restaurant 3 not found, you must specify 3 restaurants

Potresti riflettere il comportamento previsto nella scelta del nome del percorso

SearchRestaurantsByID //expect 200 empty set or partial result

vs

GetCompleteRestaurantSet // expect 500 error message

Ma ovviamente la tua documentazione lo renderebbe completamente chiaro.

    
risposta data 03.11.2018 - 17:15
fonte

Leggi altre domande sui tag