API geschrieben — XML (zwei) zerrissen

Die erste API von МоегоСклада erschien vor 10 Jahren. Seitdem arbeiten wir an den bestehenden API-Versionen und entwickeln neue. Und einige Versionen der API wurden schon eingestellt.

In diesem Artikel wird es viel geben: wie die API erstellt wurde, warum sie für den Cloud-Service benötigt wird, was sie den Benutzern bietet, auf welche Fallstricke wir gestoßen sind und was wir als Nächstes tun möchten.

Ich heiße Oleg Alexeev oalexeev, ich bin technischer Direktor und Mitbegründer von МоегоСклада.

Warum eine API für den Service erstellen

Unsere Kunden, das sind Zehntausende von Unternehmern, nutzen aktiv Cloud-Lösungen: Banking, Online-Shops, Warenwirtschaft, CRM. Man verbindet sich mit einem — und schon wird es schwierig, aufzuhören. Und jetzt bieten der fünfte, achte, zehnte Service den Unternehmern eine einfachere Arbeit, aber die Daten zwischen diesen Cloud-Services werden manuell übertragen. Die Arbeit wird zum Albtraum.

Eine offensichtliche Lösung besteht darin, den Benutzern die Möglichkeit zu geben, Daten zwischen Cloud-Services zu übertragen. Zum Beispiel Daten als Dateien zu importieren und zu exportieren, die dann in den gewünschten Service hochgeladen werden können. Die Dateien werden üblicherweise an das Format jedes Services angepasst. Das ist mehr oder weniger einfache Handarbeit, aber mit der steigenden Anzahl dieser Services wird es immer schwieriger, das zu erledigen.

Deshalb ist der nächste Schritt die API. Mit ihr gewinnt der Cloud-Service, indem er mehrere Services an einem Punkt verbindet. Das Entstehen eines solchen Ökosystems zieht neue Kunden aufgrund zusätzlicher Möglichkeiten an. Ein Produkt mit neuen Funktionen wird rentabler und nützlicher.

Wenn man eigene Schnittstellen erstellt, zieht das externe Verkäufer in Form von Programmierern an, die dank der API von Ihrem Produkt erfahren. Sie beginnen, Lösungen auf der Grundlage der bereitgestellten API zu erstellen und verdienen Geld mit der Automatisierung der Aufgaben ihrer Kunden.

Das Buchhaltungssystem von МоегоСклада basiert auf einfachen Prozessen. Das Wichtigste ist die Arbeit mit primären Dokumenten, die Möglichkeit, Warenannahme und -versand durchzuführen, und auf der Grundlage der Primärdaten Berichte für das Geschäft zu erhalten. Außerdem gibt es die Datenübertragung, zum Beispiel an die Cloud-Buchhaltung, und deren Abruf aus Bankensystemen oder Einzelhandelsflächen. Außerdem arbeiten wir mit Online-Shops: Wir erhalten Informationen über Produkte und senden Daten zu Beständen.

API geschrieben — XML (zwei) zerrissen

Die erste API von МоегоСклада

In den 10 Jahren, in denen МоегоСклада mit der API arbeitet, haben wir zahlreiche Integrationen entwickelt, die den Datenaustausch ermöglichen, mit Banken arbeiten, Zahlungen durchführen und externe Telefonie nutzen.

Im ersten Jahr ermöglichten wir den Export beliebiger Daten im XML-Format. Zu dieser Zeit war es für die Benutzer viel verständlicher und vertrauter, die Daten offline und nicht in einer Cloud zu speichern, und wir gaben ihnen das. Der Export wurde durch manuelles Exportieren aus der Benutzeroberfläche gestartet. Man konnte also noch nicht wirklich von einer API sprechen.

Damals begannen wir die Zusammenarbeit mit dem Unternehmen Русагро — sie nutzten bereits ein 'ausgereiftes' ERP zur Produktions- und Vertriebsplanung, während die Beladung von Waggons in den Werken im МоёмСкладе automatisiert wurde. So entstanden die ersten Ansätze einer echten API: Der Austausch zwischen unserem Dienst und dem ERP erfolgte durch das Versenden großer Dateien mit Daten zu allen Dokumentenarten.

Das ist eine gute Option für den Batch-Datenaustausch, aber zusammen mit den Dokumenten musste man auch deren Abhängigkeiten übermitteln: Informationen über Produkte, Geschäftspartner und Lager. Solch ein Datenmix lässt sich beim Export nicht so schwer generieren, beim Import jedoch ziemlich schwierig zu entwirren, da alle Informationen in einem Paket ankommen: sowohl über neue Dokumente als auch über bereits bestehende.

Die erste XML-API lebte nicht lange — nach zwei Jahren begannen wir mit ihrer Umstrukturierung. Schon zu Beginn ihrer Arbeit begingen wir einige Fehler beim Aufbau der Programmierschnittstelle.

API geschrieben — XML (zwei) zerrissen
So wurde die XML-API erstellt: eine Illustration von einem unserer Architekten. Übrigens, erwarten Sie seine Artikel.

Hier sind unsere Hauptfehler:

  1. Die JAXB-Deklaration wurde direkt an Entity Beans vorgenommen. Für die Kommunikation mit der Datenbank nutzen wir Hibernate, und für diese Beans wurde ebenfalls die JAXB-Deklaration erstellt. Dieser Fehler trat fast sofort auf: Jede Änderung der Datenstruktur erforderte eine sofortige Benachrichtigung aller, die die API nutzen, oder den Aufwand, Umgehungslösungen zu finden, die die Kompatibilität mit der vorhergehenden Datenstruktur gewährleisteten.
  2. API entwickelte sich als eine Art Ergänzung, und ursprünglich haben wir nicht definiert, welcher Teil des Produkts er ausmacht. Wir haben auch nicht darüber nachgedacht, ob die API etwas Wichtiges ist und ob wir rückwärtskompatibel für die ersten Kunden sein müssen. Für einen gewissen Zeitraum betrug die Anzahl der API-Nutzer etwa 5 % der insgesamt kleinen Nutzerbasis, und wir haben ihnen keine Beachtung geschenkt. Die damals durchgeführte universelle Filterung führte dazu, dass wir als Backend verwendet wurden. Diese Filterung war ganz und gar kein GraphQL, sondern etwas Ähnliches — sie funktionierte über eine Vielzahl von Abfrageparametern. Mit so einem leistungsstarken Werkzeug war es für die Nutzer schwierig, sich zurückzuhalten, und die Anfragen wurden so umgeleitet, dass sie direkt von der UI ihrer Online-Shops gesendet wurden. Die Situation wurde zu einer unangenehmen Überraschung, denn die Bereitstellung eines solchen Dienstes sollte andere Tarifierungen und ein ganz anderes Verständnis der API als Produkt erfordern.
  3. Da sich die API nicht als Hauptprodukt entwickelte, wurde die API-Dokumentation nach dem Prinzip des Restes erstellt und veröffentlicht — durch Reverse Engineering. Dieser Ansatz scheint ziemlich einfach und bequem zu sein, widerspricht jedoch der Vertragsarbeit. Dabei gibt es eine Komponente mit einem festgelegten Funktionsschema. Der Entwickler implementiert sie gemäß diesem Schema und den Anforderungen, die Komponente wird getestet, und der Kunde erhält ein Produkt, das den Vorstellungen des Analytikers entspricht. Reverse Engineering hingegen wirft ein Produkt auf den Markt, das einfach existiert: mit Stützen, seltsamen Lösungen und improvisierten Ansätzen anstelle der benötigten Funktionalität.
  4. Der gesamte Anfragenfluss, der über die API kam, konnte nicht mehr als ein Nginx- oder Application Server-Log analysiert werden. Dies erlaubte es nicht, Fachgebiete zu identifizieren, außer sie nach Nutzern und Abonnenten zu unterteilen. Wenn keine Möglichkeit besteht, die Registrierung von Anwendungen oder Kunden zu regulieren, wird die Analyse der Situation unmöglich. Dieses Problem hatte in geringem Maße Auswirkungen auf die Entwicklung der API, es betrifft mehr das Verständnis ihres Bedarfs und ihrer Funktionalität.

Versuch Nummer zwei: REST API

Im Jahr 2010 versuchten wir, ein System für den Austausch mit der Online-Buchhaltungssoftware BuchSoft zu entwickeln. Es kam nicht zustande. Doch im Verlauf der Integration entstand eine vollwertige API: ein REST-Service für den Austausch, bei dem keine Freiheiten wie RPC-Aufrufe vorhanden waren. Alle Kommunikation mit der API wurde auf den für REST typischen Modus umgestellt: In der Anfragezeile befindet sich der Name der Entität, und die durchzuführende Operation wird über die HTTP-Methode festgelegt. Wir fügten eine Filterung nach dem Aktualisierungszeitpunkt der Entitäten hinzu, wodurch die Benutzer die Möglichkeit hatten, Replikationen mit ihren Systemen zu erstellen.

Im gleichen Jahr wurde eine API für den Export von Lagerbeständen und Warenbeständen eingeführt. Über die API wurden den Benutzern die wertvollsten Teile des Systems zugänglich gemacht – der Austausch von Primärdokumenten sowie die Berechnung von Beständen und Selbstkosten der Waren.

Im Dezember 2015 veröffentlichte RetailCRM die erste Drittanbieter-Bibliothek für den Zugriff auf unsere API. Diese wurde ziemlich aktiv genutzt, während gleichzeitig die Beliebtheit des Dienstes insgesamt wuchs, und die Last auf der API wuchs schneller als die auf der Weboberfläche. Eines Tages verwandelte sich das Wachstum in einen Anstieg der Last.

API geschrieben — XML (zwei) zerrissen

API geschrieben — XML (zwei) zerrissen

Und dieser Anstieg, auf den der Pfeil links hinweist, versetzte den Server, der unsere API bedient, in völliges Erstaunen. Eine Woche lang versuchten wir herauszufinden, was genau diese Last verursachte. Es stellte sich heraus, dass es die Anfragen waren, die von den Frontends der Kunden an unsere API weitergeleitet wurden. Rund 50 Kunden verursachten den gesamten Anstieg. Hier wurde uns einer unserer Fehler bewusst – die völlige Abwesenheit von Limits.

Letztendlich führten wir ein Limit für die Anzahl gleichzeitiger Anfragen ein. Mit einem Benutzerkonto konnten nicht mehr als zwei Anfragen gleichzeitig geöffnet werden. Das ist ausreichend für den Betrieb im Replikationsmodus für den Austausch von Daten im Batch-Modus. Diejenigen, die uns als Backend nutzen wollten, mussten sich von diesem Zeitpunkt an stärker an die Tarife anpassen, da sie in ihren Programmen Arbeiten mit mehreren Konten implementierten.

Wir bringen Ordnung hinein

Schon seit 2014 wurde die Nachfrage nach der bestehenden API zu einem wichtigen Teil des Geschäfts, und die API generierte das größte Datenvolumen im Austausch von Daten mit den Kunden. Im Jahr 2015 starteten wir ein Projekt zur Ordnung der API. Wir wählten als Format JSON anstelle von XML und begannen, sie basierend auf den Besonderheiten zu entwickeln, die wir bei der Implementierung der vorherigen Version festgestellt hatten:

  1. Die Möglichkeit, Versionen zu verwalten. Die Versionierung ermöglicht die Entwicklung einer neuen Version, ohne die bestehende Anwendung zu beeinträchtigen oder den Betrieb der Nutzer zu stören.
  2. Die Möglichkeit für den Benutzer, Metadaten in der Antwort zu sehen, die er erhält.
  3. Die Möglichkeit, große Dokumente auszutauschen. Wenn wir ein Dokument mit mehr als 4-5 Tausend Positionen verarbeiten, wird dies für den Server zu einem Problem: lange Transaktionen, lange HTTP-Anfragen. Wir haben einen speziellen Mechanismus entwickelt, der es ermöglicht, das Dokument in Teilen zu aktualisieren und einzelne Positionen dieses Dokuments zu verwalten, indem wir sie an den Server senden.
  4. Replikationswerkzeuge – waren auch in der vorherigen Version vorhanden.
  5. Lastgrenzen – als Erbe der Stolpersteine, auf die wir in der vorherigen Version gestoßen sind. Wir haben Limits für die Anzahl der Anfragen in einem bestimmten Zeitraum, die Anzahl paralleler Anfragen und Anfragen von einer IP-Adresse eingeführt.

Seitdem haben wir zwei kleinere Versionen der API veröffentlicht und mehrere spezialisierte APIs gestartet, aber der grundlegende Ansatz blieb unverändert. Das aktualisierte Austauschformat und die neue Architektur ermöglichen es, Mängel in der API viel schneller zu beheben.

API von МойСклад heute

Heute löst die API von МойСклад viele Aufgaben:

  • Datenaustausch mit Online-Shops, Buchhaltungssystemen, Banken;
  • Abruf von Berechnungsdaten, Berichten;
  • Nutzung als Backend für Client-Anwendungen – unsere mobilen Anwendungen und die Desktop-Kasse arbeiten über die API
  • Versand von Benachrichtigungen über Änderungen der Daten in МойСклад – Webhooks;
  • Telefonie;
  • Treueprogramme.

Auf Basis der API hat unser Generaldirektor Askar Rakhimberdiev rhino in vier Stunden einen Telegram-Bot geschrieben, der über die API die Bestände abruft: github.com/arahimberdiev/com-lognex-telegram-moysklad-stock

Jetzt die nackten Zahlen.

Hier sind unsere Statistiken zur alten REST API:

  • 400 Unternehmen;
  • 600 Benutzer;
  • 2 Millionen Anfragen pro Tag;
  • 200 GB/Tag ausgehender Verkehr.

Und hier ist das Ergebnis für alle APIs von МойСклад:

  • über 70 Integrationen (ein Teil davon kann hier angesehen werden www.moysklad.ru/integratsii);
  • 8500 Unternehmen;
  • 12.000 Benutzer;
  • 46 Millionen Anfragen pro Tag;
  • 2 TB/Tag ausgehender Verkehr.

Was kommt als nächstes

Die Pläne zur Entwicklung der API befinden sich in aktiver Diskussion. Wir versuchen, die Erfahrungen aus dem Betrieb, die uns die Nutzer zur Verfügung stellen, zu berücksichtigen. Es gelingt nicht immer, alles sofort umzusetzen, aber eine neue Version der API mit benutzerfreundlicheren Metadaten und einer weniger umfangreichen Struktur ist nicht mehr weit entfernt, einschließlich OAuth für die Authentifizierung und einer API für in die Benutzeroberfläche integrierte Anwendungen.

Neuigkeiten können auf der speziellen Website für Entwickler von Integrationen mit meinem Lager verfolgt werden: dev.moysklad.ru.

Quelle: habr.com

60GB SSD 8Gb DDR4