È corretto restituire HTML da un'API JSON?


25

Nel mio attuale progetto sono responsabile dell'implementazione di un servizio che prevede il consumo di API RESTful di nuova creazione, documentate come supporto esclusivo di JSON.

Il client effettua costantemente richieste con l'intestazione accetta di "application / json" e il tipo di contenuto di "application / json". Tuttavia, alcuni endpoint inviano una risposta con un tipo di contenuto di HTML, persino un corpo HTML. Per me questo è chiaramente un approccio sbagliato e non può mai essere giustificato.

Durante tutto il progetto questa stessa pratica è stata applicata a due diversi fornitori e due diversi servizi. Mi sono ritrovato a dover giustificare il motivo per cui i servizi dovevano essere cambiati. I venditori hanno dichiarato che il cliente dovrebbe far fronte a questo e anche la mia libreria REST di scelta è stata messa in discussione (RestEasy) perché non lo fa di default "out the box".

Questo è stato un grande punto di frustrazione. Non riesco a trovare molti riferimenti a sostegno della mia tesi, presumo che ciò sia dovuto al fatto che il punto è controverso in quanto è così ovvio.

La domanda è: mi sto perdendo qualcosa? sono pedante per questo? È corretto avere un'API JSON che non ha un tipo di contenuto di application / json in questo scenario? I riferimenti sarebbero apprezzati. Come risolvi questa situazione da un punto di vista commerciale?


1
Per tipo di contesto intendi l'intestazione HTTP del tipo di contenuto?
Marjan Venema,

Sì, mi riferisco all'intestazione del tipo di contenuto HTTP. Modificato.
phillip.darley,

Bene, almeno non devono chiamarlo "API REST JSON" quando è un'API REST HTML.
Bergi

Risposte:


28

Quando si invia acceptun'intestazione che richiede un tipo di supporto specifico, il server non dovrebbe rispedire qualcos'altro e sicuramente non con un codice di stato 200 OK

Da Restpatterns.org :

Se non è presente alcun campo di intestazione Accetta, si presuppone che il client accetti tutti i tipi di supporto. Se è presente un campo di intestazione Accept e se il server non è in grado di inviare una risposta accettabile in base al valore del campo Accept combinato, il server DOVREBBE inviare una risposta 406 (non accettabile).

(Enfasi mia)

Restpatterns.org prende questo dallo standard HTTP attuale: Definizioni dei campi di intestazione - Accetta

In breve: non sei pedante. I servizi non seguono lo standard HTTP se restituiscono HTML quando l'intestazione accetta dice loro di restituire application/jsone nient'altro.


1
+1. Sono d'accordo con questa risposta, ma purtroppo la parola shouldè usata ripetutamente nelle specifiche HTTP. Dobbiamo avviare una petizione online per cambiare quelle parole must.
Reactgular

3
@MarjanVenema "dovrebbe" è corretto perché nella sezione 10 dello stesso rfc c'è una nota: "I server HTTP / 1.1 sono autorizzati a restituire risposte che non sono accettabili in base alle intestazioni di accettazione inviate nella richiesta. In alcuni casi, questo può anche essere preferibile inviare una risposta 406 ".
imel96

1
Se un client richiede una risorsa che in realtà non ha una rappresentazione JSON, quindi non importa quanto voglia JSON, forse è meglio ricevere qualcos'altro che sia definitivo; non hai la certezza di ottenere un 406. L'importante è che il server descriva effettivamente il tipo di contenuto della risposta.
Donal Fellows l'

6
@DonalFellows: No, sarebbe meglio essere informati di ciò che è effettivamente il caso. Il server non dovrebbe semplicemente inviare qualcosa che ritiene appropriato, ma inviare una risposta 406 non accettabile come indicato nello standard. Tenere presente che quando il client richiede specificamente un tipo di supporto e non specifica alcun fallback, probabilmente non ha modo di elaborare nessun altro tipo di supporto.
Marjan Venema,

2
@ imel96: il fatto che Internet non sia mai stato rigoroso è esattamente ciò che ha portato alle difficoltà nel provare a supportare vari browser e ai server ora costretti a rimanere retrocompatibili con HTML non valido poiché ce n'è semplicemente troppo là fuori (e purtroppo è ancora in fase di creazione).
Marjan Venema,

9

Cosa intendi con "RESTful JSON API" - Penso che il primo problema qui sia che stai mescolando concetti (o forse qualcuno tra te e le tue controparti tecniche presso i tuoi "fornitori").

Un'API RESTful (sia che tu non stia affatto parlando di livello 1 o qualcosa di livello 3 o superiore cfr http://martinfowler.com/articles/richardsonMaturityModel.html ) riguarda il modo in cui interagisci con l'API e non il formato del contenuto inviato o ricevuto da. Non si tratta nemmeno di protocolli o meccanismi di trasporto ...

Allo stesso modo un'API JSON è un'API che supporta l'uso di JSON come formato di dati: può essere o meno riposante, può o non può essere implementato tramite HTTP e (e questo è il punto chiave) può o meno supportare JSON esclusivamente.

Una buona API in esecuzione su HTTP (è ragionevole supporre che nel contesto si stia parlando di un'API esposta su HTTP) dovrebbe consentire di richiedere contenuti in una varietà di formati e quei formati possono (e possibilmente dovrebbero) includere HTML e JSON e XML. Perché? Beh, renderebbe l'apprendimento dell'API molto più semplice, concettualmente fornisce una UX istantanea basata su browser per qualsiasi scopo e così via ...

La domanda interessante diventa quindi se la mia API, che supporta una varietà di formati di contenuto, viene chiamata senza che venga detto quale formato il client si aspetta quindi quale formato dovrebbe restituire ...? Questo tende verso un argomento religioso - ma l'HTML offre al provider la possibilità di includere informazioni utili (come "ricorda di impostare il contenuto accetta l'intestazione").

Per rispondere alla domanda un'API, una che è riposante e una che supporta json dovrebbe assolutamente essere in grado di restituire HTML se questo è il contenuto richiesto.


1
Prendo entrambi i punti e ho modificato la mia domanda di conseguenza. Il fatto che il servizio sia RESTful non è rilevante e ho spiegato in dettaglio che il client accetta "application / json" in ogni richiesta.
phillip.darley,

Direi che "RESTful JSON API" ha un significato molto ovvio.
gnasher729,

1
Direi che i miei insegnanti hanno fatto uno sforzo tremendo per assicurarsi che capissimo perché "non dare per scontato" fosse una parte fondamentale dell'essere un buon programmatore
Murph,

5

Il client effettua costantemente richieste con l'intestazione accetta di "application / json" e il tipo di contenuto di "application / json"

Sì, questa è la cosa corretta da fare, ma non significa che il fornitore si preoccupi. Anche se capisco perfettamente la tua frustrazione, perché penso anche che un servizio JSON dovrebbe sempre dare una risposta JSON, ma ci sono molti esempi in cui non è così.

Durante tutto il progetto questa stessa pratica è stata applicata a due diversi fornitori e due diversi servizi. Mi sono ritrovato a dover giustificare il motivo per cui i servizi dovevano essere cambiati. I venditori hanno dichiarato che il cliente dovrebbe far fronte a questo e anche la mia libreria REST di scelta è stata messa in discussione (RestEasy) perché non lo fa di default "out the box".

Bene, devo essere d'accordo con il venditore. È il loro servizio e fintanto che documentano chiaramente i casi speciali per usarlo, non puoi davvero imporre che lo cambino. È uno svantaggio per loro in quanto gli sviluppatori saranno lenti ad adottare la loro API e se ascoltassero ciò di cui gli sviluppatori hanno bisogno, lo cambieranno, ma purtroppo non c'è alcuna regola che debbano seguire gli standard.

La domanda è: mi sto perdendo qualcosa?

Le intestazioni della richiesta non significano nulla a meno che non vengano interrotte correttamente dall'altra parte. So che se sviluppo un'API Web utilizzando PHP, allora al diavolo le intestazioni della richiesta. Posso rispondere con quello che voglio. Considerando che, un servizio configurato in IIS con C # offre una gestione molto più semplice delle intestazioni di richiesta, il loro tipo e la gestione del tipo di risposta. Ha molto a che fare con gli strumenti utilizzati dal fornitore per creare l'API.

Sono pedante per questo?

Sì e No. Ho amici degli sviluppatori che non sarebbero in grado di superarlo. Sarebbero così risolti dal problema e incapaci di procedere con altre attività fino a quando l'API funziona nel modo previsto. Questo è pedante.

È un problema perché il fornitore ha creato "più lavoro" per completare le attività. Chiunque ne sarebbe frustrato. So che lo sarei.

È corretto avere un'API JSON che non ha un tipo di contenuto di application / json in questo scenario?

Assolutamente, ma non è una buona pratica.

Un client può solo dire al server qual è il tipo di contesto di a request. Non ha la capacità di imporre un tipo di contenuto per il response. Il client può solo informare il server che sarà acceptuna raccolta di possibili tipi di contenuto.

Definizioni dei campi di intestazione

Il campo Accetta intestazione richiesta può essere utilizzato per specificare alcuni tipi di supporti che sono accettabili per la risposta. Le intestazioni Accetta possono essere utilizzate per indicare che la richiesta è specificamente limitata a un piccolo set di tipi desiderati, come nel caso di una richiesta per un'immagine in linea.

È possibile per un client richiedere un'immagine di image/jpeg, ma il server risponde text/htmle un codice di stato 404se l'immagine non è stata trovata. I server possono anche rispondere in modo errato. Ci sono molti siti Web Wordpress là fuori che rispondono con text/htmle codice di stato 200per le pagine di file non trovati.

Ora questa è tutta una cattiva pratica da parte del server. Quello che sto cercando di dirti è che è assolutamente possibile e succede spesso. Le persone non sanno cosa stanno facendo quando configurano queste cose.

I riferimenti sarebbero apprezzati. Come risolvi questa situazione da un punto di vista commerciale?

Ho riscontrato questo problema in alcuni progetti. Si postdati JSON al server e restituisce una risposta JSON o HTML.

Non è davvero un grosso problema sapere quale tipo era nella risposta. Se il primo carattere è {o [puoi assumere JSON. In tal caso, <puoi assumere HTML. È così che l'ho gestito in passato. A volte il programmatore che ha scritto l'API sa tutto sulle intestazioni HTTP. Tutto ritorna come text/htmlrisposte. Se sei fortunato hanno Apache configurato per impostazione predefinita a text/plaincui a volte può aiutare.

Questi problemi esistono e continueranno ad esistere in futuro. La comunicazione da server a server è di gran lunga un'attività non regolamentata. Non esiste un organo di governo che espellerà un fornitore da un sindacato per un server che fornisce risposte HTTP errate.


Questo è in linea con la risposta di @Marjan Venema, ma un altro punto chiave che sollevi è la documentazione di questo comportamento. Per aggiungere alla mia frustrazione il venditore non ha documentato questo comportamento. Il tipo di contenuto varia in base allo stato della sessione, tuttavia è documentata solo la risposta JSON.
phillip.darley,
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.