Schreiben Sie den Code so, als würde er von einem gewalttätigen Psychopathen begleitet, der weiß, wo Sie leben.
Hallo allerseits!
Ich arbeite als Teamleiter des Integration Development-Teams im Online-Hotelreservierungsservice Ostrovok.ru und möchte heute meine Erfahrungen mit verschiedenen APIs teilen.

Als Entwickler eines Systems, das mit externen Anbietern zusammenarbeitet, stoße ich häufig auf verschiedene APIs - meistens handelt es sich um SOAP / REST oder ähnliches. Die Arbeit mit vielen von ihnen hinterlässt jedoch den Eindruck, dass sie geschrieben wurden, weder nach technischen Regeln noch nach gesundem Menschenverstand - wie aus dem Buch „Bad Advice“ von Grigory Oster. In diesem Artikel werde ich versuchen, solche Fälle im Stil von „schlechten Ratschlägen“ zu beschreiben und Beispiele im Zusammenhang mit XML zu betrachten. Kommentare und Diskussionen sind willkommen.
Historischer Hintergrund
SOAP (aus dem Englischen. Simple Object Access Protocol - ein einfaches Protokoll für den Zugriff auf Objekte) - ein Protokoll für den Austausch strukturierter Nachrichten in einer verteilten Computerumgebung. SOAP war ursprünglich hauptsächlich für die Implementierung von Remote Procedure Call (RPC) gedacht. Jetzt wird das Protokoll zum Austausch beliebiger Nachrichten im XML-Format und nicht nur zum Aufrufen von Prozeduren verwendet.
Gehen Sie zu den Beispielen
1. XML an URL übergeben
Was wollen API-Benutzer am meisten? Natürlich Einfachheit, Zuverlässigkeit und Prägnanz. Lesen wir also nicht den Anforderungshauptteil, sondern akzeptieren XML als URL-codierte Information als Parameter des Anforderungspfads! Was könnte besser sein:
http://exapmple.com/xml/form.jsp?RequestName%3DHotelRequest2%26XML%3D%3C%3Fxml%2Bversion%3D%221.0%22%2Bencoding%3D%22UTF-8%22%3F%3E%0A%3CHotelRequest2%2BBuyerId%3D%22test%22%2BUserId%3D%22test%22%2BPassword%3D%22test%22%2BLanguage%3D%22en%22%2BHotel%3D%22-100%22%2BProductCode%3D%221--%22%2BArrivalDate%3D%2223.12.2018%22%2BDepartureDate%3D%2224.12.2018%22%2BArrivalTime%3D%22%22%2BDepartureTime%3D%22%22%2BCurrency%3D%222%22%2BWhereToPay%3D%223%22%2BNumberOfGuests%3D%220%22%2BNumberOfExtraBedsAdult%3D%220%22%2BNumberOfExtraBedsChild%3D%220%22%2BNumberOfExtraBedsInfant%3D%220%22%2B%2F%3E
Alles wird einfach und es besteht keine Notwendigkeit, einen Körper von der Abfrage zu subtrahieren - Sie wissen nie, welche Probleme damit auftreten können.
SpoilerIch weiß nicht, warum das gemacht wurde. Die Probleme hier sind die folgenden: Viele Server haben eine Begrenzung für die Länge des Anforderungspfads, der sie durchlaufen kann. Wenn das XML-Datenvolumen groß ist, können Sie den Fehler 413 Entity Too Large als eines der Szenarien verursachen. Darüber hinaus nimmt die Informationsmenge zu, da wir vor dem Senden eine URL-Codierung durchführen.
2. Informationsübertragung durch übermäßiges Verschachteln von Datenobjekten
Lassen Sie uns darüber nachdenken, wie Sie die Informationen in den Antworten so schwierig wie möglich gestalten können. Verwenden wir verschachtelte Strukturen und sogar in verschiedenen Formaten! Kaum gesagt als getan -
<Request> <InnerRequest> <RQ>[{"someInfo":"base64Data"}] </RQ> </InnerRequest> </Request>
In der Tat ist die XML-Datei der obersten Ebene eine weitere XML-Datei, und darin befindet sich json, in dem die Daten in base64 und erneut in json dargestellt werden, und sie enthält bereits die Informationen, die wir benötigen! Eine großartige Lösung, fast wie ein Märchen über den Tod von Koshchei, versteckt in einem Ei.
SpoilerEiner der auffälligsten Nachteile ist die Verlangsamung beim Parsen der Antwort, bis alle verschachtelten Strukturen durchlaufen wurden. Danach kann sich herausstellen, dass der Fehlercode in json und nicht auf höheren Ebenen verdrahtet ist. Ich verstehe, dass das Codieren von Binärdaten in base64 in xml / json eine gängige Praxis ist, aber das Codieren eines anderen Formats in einem anderen Format ist bereits jenseits von Gut und Böse.
3. Hinzufügen von Informationen, die sich nicht auf die Anforderungsdaten beziehen und im Datenformat nicht gültig sind
Angenommen, XML kommt im Anfragetext zu uns, wir verarbeiten es und geben eine Antwort. Für ein gut gestaltetes und stark belastetes System sieht es zu kompliziert aus. Lassen Sie uns die Benutzer verpflichten, den Datentyp im Anforderungshauptteil zu senden. Wie geht das? Natürlich genau im Hauptteil der Anfrage.
XML= <Request> ... </Request>
Auf so einfache Weise werden wir immer wissen, dass wir eine Anfrage im XML-Format erhalten haben.
SpoilerEs stellt sich heraus, dass wir dem bereits gebildeten Hauptteil der Anfrage weitere führende Bytes hinzufügen müssen, und erst danach ist es möglich, eine Anfrage zu stellen. Glück, wenn Sie die führenden Bytes nicht abhängig von der Art der Anforderungsdaten ändern müssen. In diesem Fall ist es besser, den http-Header zu verwenden, um den Datentyp anzugeben, und den Anforderungshauptteil nicht zu ändern.
4. Vervielfältigung von Daten ohne die Notwendigkeit
Angenommen, wir haben sehr, sehr wichtige Informationen in der Struktur der XML-Antwort. Wie kann ich dies dem Benutzer zeigen? Das offensichtlichste - lassen Sie es uns mehrmals als Teil der Antwort zeigen, dann wird er definitiv darauf achten.
<Response> <Obj Info="Important"> <ObjSetting Info="Important"/> <Name>SomeName</Name> <Info>Important</Info> </Obj> </Response>
Danach wird der Endbenutzer definitiv auf das Infofeld achten.
SpoilerIn diesem Fall habe ich darüber nachgedacht und sogar das Unternehmen, das die API bereitgestellt hat, nach der Bedeutung des Infofelds gefragt und gefragt, ob sich die Informationen in den Tags auf verschiedenen Ebenen unterscheiden würden. Die Antwort war: Nein, das wird es nicht - sie duplizieren sich gegenseitig. Warum Benutzer irreführen und die Antwort erschweren, wenn dies nicht erforderlich ist?
5. Übergeben von Parametern desselben Typs einzeln, nicht eines Arrays
In einer der APIs, mit denen wir nach Hotels suchen, gibt es Felder, die das Alter der Gäste angeben. Welches Präsentationsformat wird am besten verwendet, um diese Informationen zu vermitteln? Lassen Sie das Format so aussehen: Jedes Alter ist ein separates obligatorisches XML-Tag, und wir betrachten den Wert 0 als das Fehlen dieses Parameters.
<Request> <Age1>20</Age> <Age2>20</Age> <Age3>0</Age> <Age4>0</Age> </Request>
SpoilerHier gibt es mehrere Probleme gleichzeitig: Nicht erweiterbar, redundante Informationen, außerdem kann das Alter wirklich Null sein, wenn die Gäste neugeborene Kinder sind. In diesem Fall müssen Sie ein Array anstelle von eindeutig benannten Tags verwenden.
6. Weiterleiten von Informationen aus früheren Anforderungen als Teil der API-Aufrufkette
Es ist Zeit, über die Sicherheit unserer API nachzudenken. Wie verstehen wir, dass der Benutzer Informationen aus unseren vorherigen Antworten erhält? Lassen Sie ihn uns natürlich unsere Antwort schicken!
<Request> <RequestInfo/> <PreviosResp> ... </PreviosResp> </Request>
SpoilerUm weiterhin mit der API arbeiten zu können, muss die gesamte Antwort des externen Systems aus den vorherigen Schritten der API gesendet werden und nicht einige wichtige Daten davon oder sogar ein Hash, der dieser Antwort definitiv entspricht. Überschüssige Daten in ihrer ganzen Pracht.
7. Verwenden Sie keine Markierungen für einen aufgetretenen Fehler, z. B. ein Fehler-Tag oder einen http-Code
Wir haben unsere wunderschöne API erstellt und der Welt vorgestellt. Aber sobald etwas schief gelaufen ist und wir aufgrund eines internen Fehlers keine Antwort an den Benutzer formulieren konnten. Was ist in diesem Fall zu tun? Geben Sie einfach eine Antwortvorlage ohne Daten, ohne Fehlercodes oder andere Informationen an. Niemand sollte wissen, dass unsere ideale API manchmal nicht funktioniert!
Ein Beispiel für eine solche Antwort:
<Response> <ImportantInfo/> </Response>
- mit einem Antwortcode von 200 OK.
SpoilerFehler zu vertuschen ist eine sehr schlechte Praxis. Das Problem ist, dass alles so aussieht, als ob die Antwort keine Probleme enthält: Es gibt kein <Error>
-Tag, der http-Status besagt, dass alles in Ordnung ist. In diesem Fall muss eine zusätzliche Validierung der empfangenen Informationen durchgeführt werden, damit in unserem System keine unvorhergesehenen Konsequenzen auftreten.
Fazit
Trotz der umfangreichen Dokumentation zur Arbeit mit SOAP / XML-Technologien und zum API-Design sind viele Probleme immer noch relevant, und einige Lösungen widersprechen dem gesunden Menschenverstand. Ich hoffe, dass ich mit diesem Artikel die Aufmerksamkeit der Entwickler auf die nicht erfolgreichsten Ansätze lenken kann, um ihre Anzahl in Zukunft zu reduzieren.