Ist es in Ordnung, HTML von einer JSON-API zurückzugeben?

25

In meinem aktuellen Projekt bin ich für die Implementierung eines Dienstes verantwortlich, bei dem neu erstellte RESTful-APIs verwendet werden, von denen dokumentiert ist, dass sie ausschließlich JSON unterstützen.

Der Client stellt konsistent Anforderungen mit dem Accept-Header "application / json" und dem Inhaltstyp "application / json". Einige Endpunkte senden jedoch eine Antwort mit einem inhaltlichen HTML-Typ, sogar einem HTML-Text. Für mich ist dies eindeutig der falsche Ansatz und kann niemals gerechtfertigt werden.

Während des gesamten Projekts wurde dieselbe Vorgehensweise bei zwei verschiedenen Anbietern und zwei verschiedenen Diensten angewendet. Ich musste rechtfertigen, warum die Dienste geändert werden mussten. Die Anbieter gaben an, dass der Client damit fertig werden sollte, und sogar meine REST-Bibliothek der Wahl wurde in Frage gestellt (RestEasy), da sie dies standardmäßig nicht „out the box“ erledigt.

Dies war ein wichtiger Punkt der Frustration. Ich kann nicht viele Referenzen finden, um meine Argumentation zu stützen. Ich gehe davon aus, dass dies darauf zurückzuführen ist, dass der Punkt umstritten ist, da er so offensichtlich ist.

Die Frage ist, fehlt mir etwas? Bin ich pedantisch dabei? Ist es in Ordnung, eine JSON-API zu haben, die in diesem Szenario keinen Anwendungstyp / json für Inhalte hat? Hinweise würden geschätzt. Wie lösen Sie diese Situation aus kommerzieller Sicht?

phillip.darley
quelle
1
Mit Kontexttyp meinen Sie den HTTP-Header vom Inhaltstyp?
Marjan Venema
Ja, ich beziehe mich auf den HTTP-Content-Type-Header. Bearbeitet
phillip.darley
Nun, zumindest dürfen sie es keine "JSON REST API" nennen, wenn es sich um eine HTML REST API handelt.
Bergi

Antworten:

28

Wenn Sie einen acceptHeader senden , der einen bestimmten Medientyp anfordert, sollte der Server nicht etwas anderes zurücksenden, und ganz sicher nicht mit einem 200-OK-Statuscode

Aus Restpatterns.org :

Wenn kein Accept-Header-Feld vorhanden ist, wird davon ausgegangen, dass der Client alle Medientypen akzeptiert. Wenn ein Accept-Header-Feld vorhanden ist und der Server keine Antwort senden kann, die gemäß dem kombinierten Accept-Feldwert akzeptabel ist, MUSS der Server eine 406-Antwort (nicht akzeptabel) senden.

(Betonung meiner)

Restpatterns.org übernimmt dies aus dem aktuellen HTTP-Standard: Header-Felddefinitionen - Akzeptieren

Kurz gesagt: Sie sind nicht pedantisch. Die Dienste folgen nicht dem HTTP-Standard, wenn sie HTML-Code zurückgeben, wenn der Accept-Header ihnen ausdrücklich sagt, dass sie zurückgeben sollen, application/jsonund sonst nichts.

Marjan Venema
quelle
1
+1. Ich stimme dieser Antwort zu, aber leider wird das Wort shouldin den HTTP-Spezifikationen wiederholt verwendet. Wir müssen eine Online-Petition starten, damit diese Wörter in geändert werden must.
Reactgular
3
@MarjanVenema "sollte" ist korrekt, da in Abschnitt 10 von demselben RFC ein Hinweis steht: "HTTP / 1.1-Server dürfen Antworten zurückgeben, die gemäß den in der Anfrage gesendeten Accept-Headern nicht akzeptabel sind. In einigen Fällen kann dies sogar der Fall sein Senden einer 406-Antwort vorzuziehen. "
imel96
1
Wenn ein Client eine Ressource anfordert, die wirklich keine JSON-Repräsentation hat, ist es für ihn möglicherweise besser, eine andere definitive Ressource zu erhalten, unabhängig davon, wie sehr er JSON möchte. Es ist nicht garantiert, dass Sie eine 406 erhalten. Wichtig ist, dass der Server den Inhaltstyp der Antwort beschreibt.
Donal Fellows
6
@DonalFellows: Nein, sie sollten besser darüber informiert werden, was tatsächlich der Fall ist. Der Server sollte nicht nur alles zurücksenden, was er für angemessen hält, sondern auch eine Antwort senden, die nicht akzeptabel ist, wie im Standard angegeben. Bedenken Sie, dass der Client, wenn er speziell einen Medientyp anfordert und keine Ausweichmöglichkeiten angibt, wahrscheinlich keinen anderen Medientyp verarbeiten kann.
Marjan Venema
2
@ imel96: Die Tatsache, dass das Internet nie streng war, hat genau dazu geführt, dass Schwierigkeiten bei der Unterstützung verschiedener Browser und bei Servern bestehen, die mit ungültigem HTML abwärtskompatibel bleiben müssen, da es einfach zu viel davon gibt (und es wird leider noch erstellt).
Marjan Venema
9

Was meinen Sie mit "RESTful JSON API"? Ich denke, das erste Problem besteht darin, dass Sie Konzepte vertauschen (oder möglicherweise jemanden zwischen Ihnen und Ihren technischen Kollegen bei Ihren "Lieferanten").

Bei einer RESTful-API (unabhängig davon, ob Sie sich auf Stufe 1 oder auf Stufe 3 oder höher ausruhen ) geht es um die Art und Weise, wie Sie mit der API interagieren, nicht darum das Format des Inhalts, der gesendet oder empfangen wird. Es geht nicht einmal um Protokolle oder Transportmechanismen ...

In ähnlicher Weise ist eine JSON-API eine API, die die Verwendung von JSON als Datenformat unterstützt - sie kann oder kann nicht erholsam sein, sie kann oder kann nicht mithilfe von HTTP implementiert werden und (und dies ist der entscheidende Punkt) unterstützt JSON möglicherweise oder unterstützt JSON nicht ausschließlich.

Eine gute API, die über HTTP ausgeführt wird (es ist vernünftig anzunehmen, dass Sie von einer über HTTP bereitgestellten API sprechen), sollte es Ihnen ermöglichen, Inhalte in einer Vielzahl von Formaten anzufordern. Diese Formate können (und sollten möglicherweise) auch HTML enthalten JSON und XML. Warum? Nun, es würde das Erlernen der API viel einfacher machen, konzeptionell bietet es eine sofortige browserbasierte UX für jeden Zweck und so weiter ...

Die interessante Frage lautet dann, ob meine API, die eine Vielzahl von Inhaltsformaten unterstützt, aufgerufen wird, ohne dass mitgeteilt wird, welches Format der Client erwartet, und welches Format es zurückgeben soll ...? Dies tendiert zu einem religiösen Argument - aber HTML gibt dem Anbieter die Möglichkeit, hilfreiche Informationen einzuschließen (z. B. "Denken Sie daran, die Überschrift zum Akzeptieren von Inhalten festzulegen").

Um die Frage einer API zu beantworten, sollte eine API, die erholsam ist und json unterstützt, in der Lage sein, HTML zurückzugeben, wenn dies der angeforderte Inhalt ist.

Murph
quelle
1
Ich nehme beide Punkte und habe meine Frage entsprechend bearbeitet. Die Tatsache, dass der Service RESTful ist, ist nicht relevant, und ich habe ausgeführt, dass der Client in jeder Anfrage "application / json" akzeptiert.
Phillip.Darley
Ich würde sagen, dass "RESTful JSON API" eine sehr offensichtliche Bedeutung hat.
gnasher729
1
Ich würde sagen, meine Lehrer haben sich sehr viel Mühe gegeben, um sicherzustellen, dass wir verstanden haben, warum "Niemals annehmen" ein wesentlicher Bestandteil eines guten Programmierers ist
Murph,
5

Der Client stellt konsistent Anforderungen mit dem Accept-Header "application / json" und dem Inhaltstyp "application / json".

Ja, dies ist die richtige Vorgehensweise, bedeutet jedoch nicht, dass sich der Anbieter darum kümmert. Ich verstehe Ihre Frustration zwar vollkommen, da ich auch der Meinung bin, dass ein JSON-Service immer eine JSON-Antwort geben sollte, aber es gibt viele Beispiele, bei denen dies nicht der Fall ist.

Während des gesamten Projekts wurde dieselbe Vorgehensweise bei zwei verschiedenen Anbietern und zwei verschiedenen Diensten angewendet. Ich musste rechtfertigen, warum die Dienste geändert werden mussten. Die Anbieter gaben an, dass der Client damit fertig werden sollte, und sogar meine REST-Bibliothek der Wahl wurde in Frage gestellt (RestEasy), da sie dies standardmäßig nicht „out the box“ erledigt.

Nun, ich muss dem Verkäufer zustimmen. Es ist ihr Service und solange sie die speziellen Fälle für die Verwendung klar dokumentieren, kann man nicht wirklich aufzwingen, dass sie es ändern. Dies ist ein Nachteil für sie, da Entwickler ihre API nur langsam einführen. Wenn sie sich anhören, was die Entwickler benötigen, ändern sie dies. Leider gibt es keine Regel, dass sie Standards einhalten müssen.

Die Frage ist, fehlt mir etwas?

Anforderungsheader haben nur dann eine Bedeutung, wenn sie am anderen Ende korrekt unterbrochen werden. Ich weiß, wenn ich eine Web-API mit PHP entwickle, dann zum Teufel mit den Request-Headern. Ich kann mit allem antworten, was ich will. Während ein in IIS mit C # konfigurierter Dienst die Handhabung von Anforderungsheadern, ihres Typs und des Antworttyps erheblich vereinfacht. Dies hat viel mit den Tools zu tun, mit denen der Anbieter die API erstellt hat.

Ich bin ich pedantisch darüber?

Ja und Nein. Ich habe Entwicklerfreunde, die nicht in der Lage wären, daran vorbeizukommen. Sie würden durch das Problem so fixiert und könnten erst dann mit anderen Aufgaben fortfahren, wenn die API so funktioniert, wie sie es erwartet haben. Das ist pedantisch.

Dies ist ein Problem, da der Anbieter "mehr Arbeit" erstellt hat, um Ihre Aufgaben abzuschließen. Das würde jeden frustrieren. Ich weiß, dass ich es sein würde.

Ist es in Ordnung, eine JSON-API zu haben, die in diesem Szenario keinen Anwendungstyp / json für Inhalte hat?

Absolut, aber es ist keine gute Übung.

Ein Client kann dem Server nur mitteilen, welcher Kontexttyp ein requestist. Es kann keinen Inhaltstyp für das erzwingen response. Der Client kann dem Server nur mitteilen, dass er accepteine Sammlung möglicher Inhaltstypen erstellt.

Header-Felddefinitionen

Im Feld Anforderungsheader akzeptieren können bestimmte Medientypen angegeben werden, die für die Antwort akzeptabel sind. Accept-Header können verwendet werden, um anzuzeigen, dass die Anforderung speziell auf einen kleinen Satz gewünschter Typen beschränkt ist, wie im Fall einer Anforderung für ein Inline-Image.

Es ist für einen Client möglich, ein Image von anzufordern image/jpeg, der Server antwortet jedoch mit text/htmlund einem Statuscode, 404ob das Image nicht gefunden wurde. Server können auch falsch reagieren. Es gibt viele Wordpress-Websites, die mit text/htmlund Statuscode 200für nicht gefundene Seiten antworten .

Nun, das ist alles schlechte Praxis seitens des Servers. Ich versuche Ihnen zu sagen, dass dies absolut möglich ist und häufig vorkommt. Die Leute wissen nicht, was sie tun, wenn sie diese Dinge konfigurieren.

Hinweise würden geschätzt. Wie lösen Sie diese Situation aus kommerzieller Sicht?

Ich bin auf dieses Problem bei einigen Projekten gestoßen. Sie postJSON-Daten an den Server und es gibt entweder eine JSON oder HTML-Antwort zurück.

Es ist wirklich keine große Sache zu wissen, welcher Typ in der Antwort war. Wenn das erste Zeichen {oder ist [, können Sie JSON annehmen. Wenn <ja, können Sie von HTML ausgehen. So habe ich es in der Vergangenheit gehandhabt. Manchmal weiß der Programmierer, der die API geschrieben hat, alles über HTTP-Header. Alles kommt als text/htmlAntwort zurück. Wenn Sie Glück haben, haben sie Apache auf Standard konfiguriert, text/plainwas manchmal helfen kann.

Diese Probleme bestehen und werden auch in Zukunft bestehen bleiben. Server-zu-Server-Kommunikation ist bei weitem keine regulierte Aktivität. Es gibt kein Leitungsorgan, das einen Anbieter aus einer Gewerkschaft für einen Server ausschlägt, der schlechte HTTP-Antworten liefert.

Reactgular
quelle
Dies stimmt mit der Antwort von @Marjan Venema überein. Ein weiterer wichtiger Punkt, den Sie ansprechen, ist die Dokumentation dieses Verhaltens. Um meine Frustration zu verstärken, hat der Verkäufer dieses Verhalten nicht dokumentiert. Der Inhaltstyp hängt vom Sitzungsstatus ab, es wird jedoch nur die JSON-Antwort dokumentiert.
phillip.darley