3 Punkte von GN⁺ 2024-04-27 | 1 Kommentare | Auf WhatsApp teilen
  • Entscheidungen zur Benennung und Modellierung von API-Ressourcen sind der schwierigste und wichtigste Teil des API-Designs. Ressourcen formen das mentale Modell der Nutzer davon, wie das Produkt funktioniert und welche Funktionen es bietet.
  • Das Increase-Team unterstützt das API-Design mit dem Prinzip „keine Abstraktionen“.

Stripes Ansatz für API-Design

  • Ein beträchtlicher Teil des Teams von Increase hat zuvor bei Stripe gearbeitet und orientiert sich an den Werten hinter Stripes erfolgreichem API-Design.
  • Stripe ist hervorragend darin, Kernfunktionen komplexer Domänen in Abstraktionen zu überführen, die Nutzer leicht verstehen und verwenden können. (Beispiel: PaymentIntent, das die Unterschiede zwischen Visa und Mastercard abstrahiert)
  • Die meisten Nutzer von Stripe sind junge Startups, die Produkte entwickeln, die nichts mit Zahlungsverkehr zu tun haben, und die keine Details über Kreditkarten kennen müssen. Sie möchten Stripe schnell integrieren und sich auf die Produktentwicklung konzentrieren.

Die Nutzer von Increase und die Prinzipien des API-Designs

  • Im Gegensatz dazu verfügen die Nutzer von Increase über tiefes Wissen über Zahlungsnetzwerke, und der Grund, warum sie sich für Increase entschieden haben, liegt in der direkten Netzwerkanbindung und der Tiefe der Integration.
  • Sie möchten genau wissen, wann das FedACH-Fenster schließt und wann eine Überweisung ausgeführt wird, und sie verstehen, dass unterschiedliche SEC-Codes bei ACH-Überweisungen den Zeitpunkt einer Rückgabe beeinflussen können.
  • Der Versuch, die grundlegende Komplexität dieser Netzwerke zu verbergen, vereinfacht ihr Leben nicht, sondern frustriert sie nur.
  • Aus Gesprächen mit frühen Nutzern leitete das Team das Prinzip „keine Abstraktionen“ ab und wendete es auf das API-Design an.

Wie sich das Prinzip „keine Abstraktionen“ auf das API-Design ausgewirkt hat

  • Verwendung tatsächlich gebräuchlicher Begriffe: Statt eigene Namen für API-Ressourcen und -Attribute zu erfinden, wird das Vokabular der zugrunde liegenden Netzwerke verwendet. (Beispiel: Die Parameter für ACH-Überweisungen verwenden die Feldnamen der Nacha-Spezifikation)
  • Unveränderlichkeit: Da reale Ereignisse als Modell dienen, sind mehr API-Ressourcen unveränderlich. Es ist wirkungsvoll, Cluster unveränderlicher Ressourcen als Zustandsmaschinen-„Lifecycle-Objekte“ zu gruppieren. (Beispiel: das Feld status des Objekts ach_transfer und einige unveränderliche Unterobjekte, die entsprechend dem Übertragungs-Lifecycle erzeugt werden)
  • Trennung von Ressourcen nach Anwendungsfall: Wenn sich die Menge der Aktionen, die Nutzer je nach Ressourceninstanz ausführen können, stark unterscheidet, werden sie in mehrere Ressourcen aufgeteilt. (Beispiel: ausgehende und eingehende ACH-Überweisungen werden als separate Ressourcen getrennt)

Konsequente Einhaltung dieses Ansatzes im Engineering-Team

  • Das Engineering-Team hat sich dazu verpflichtet, diesem Ansatz treu zu bleiben.
  • Beim Design komplexer APIs über mehrere Jahre hinweg müssen ständig kleine inkrementelle Entscheidungen getroffen werden. Wenn man sich im Vorfeld zur Einhaltung grundlegender Prinzipien verpflichtet, verringert das die kognitive Last dieser Entscheidungen.
  • Beim Feld Input Message Accountability Data, das bei Überweisungen an die Federal Reserve erforderlich ist, müsste man bei einer stark abstrahierenden API darüber nachdenken, wie man dieses Feld „nutzerfreundlich“ benennt. Bei Increase nennt ein Engineer das Feld einfach input_message_accountability_data und geht weiter.

Meinung von GN⁺

  • Der Abstraktionsgrad einer API kann je nach Erfahrungsniveau der Entwickler in der jeweiligen Produktdomäne und je nach Energie, die sie in die Integration investieren, unterschiedlich sein. Deshalb ist es beim API-Design wichtig, den passenden Abstraktionsgrad für die integrierenden Entwickler zu berücksichtigen.
  • Wenn man eine API mit hohem Abstraktionsgrad baut, sollte man sorgfältig nachdenken, bevor man neue Funktionen hinzufügt. Baut man dagegen eine API mit niedrigem Abstraktionsgrad, sollte man konsequent dabei bleiben und der Versuchung widerstehen, zusätzliche Abstraktionen einzuführen.
  • Die unveränderte Verwendung der Begriffe des zugrunde liegenden Netzwerks oder Protokolls kann Entwicklern helfen, das underlying system zu verstehen, kann für Entwickler, die erstmals damit arbeiten, aber auch eine Einstiegshürde sein. Daher scheint es wichtig, Kommentare und Dokumentation sorgfältig auszuarbeiten.
  • Der Einsatz unveränderlicher Objekte im API-Design kann wirksam sein, um Datenkonsistenz zu erhalten und side effects zu verhindern. Umgekehrt kann er aber unpraktisch sein, wenn Daten aktualisiert werden müssen; man sollte also die Trade-offs sorgfältig abwägen.
  • Die Trennung von Ressourcen nach Anwendungsfall kann die Komplexität einer API erhöhen, langfristig aber die Vorhersehbarkeit verbessern. Wird sie jedoch zu stark verfeinert, kann die Nutzbarkeit sinken, daher ist es wichtig, das richtige Maß zu finden.

1 Kommentare

 
GN⁺ 2024-04-27
Hacker-News-Kommentar
  • Es ist gut, sowohl APIs mit Low-Level-Abstraktion als auch APIs mit High-Level-Abstraktion bereitzustellen

    • Low-Level-APIs ermöglichen feingranulare Kontrolle, erfordern aber Fachwissen
    • High-Level-APIs bieten vereinfachte Abläufe für allgemeine Anwendungsfälle
    • Wenn man eine klare Trennung zwischen beiden APIs beibehält, verringert sich der Druck, einer der APIs zusätzliche Abstraktionen oder Sonderfälle hinzuzufügen
    • Es ist sinnvoll, Materialien bereitzustellen, damit Clients lernen können, wie sie von einer API zur anderen wechseln
  • Mir gefällt der Teil, in dem erklärt wird, warum Increase einen anderen Ansatz gewählt hat

    • Beim Entwurf von etwas Grundlegendem ist der Kontext sehr wichtig, aber Menschen erkennen das meist nicht ausreichend
  • Die wahre Stärke von Stripe liegt darin, seine Kunden zu kennen und ihnen die Einfachheit zu bieten, die sie wollen

    • Increase versteht ebenfalls gut, was seine Kunden brauchen, und zeigt einen ähnlichen Fokus bei der Formulierung von Designrichtlinien für den Bau eines großartigen Produkts
  • Das ähnelt dem Domain-Driven-Design-Muster der „Ubiquitous Language“, bei dem in der Implementierung dieselben Begriffe verwendet werden wie von Domain-Experten in der Praxis

  • Man sollte eine Sprache verwenden, die Domain-Experten verstehen können

    • Wenn Nutzer NACHA-Dateien kennen, müssen sie bei Verwendung anderer Begriffe im Kopf ständig Zuordnungen aufrechterhalten
    • Im Fall von Stripe sind die Nutzer keine Domain-Experten, daher ist es wertvoll, Abstraktionen zu schaffen, die verständlich sind und zugleich unnötige Details verbergen
  • Ohne Abstraktionen wie POSIX müssten Anwendungen Adapter für alle unterstützten Dateisysteme schreiben

  • Es heißt, dass Teile der API-Struktur 1:1 auf Grundlage extern kontrollierter Spezifikationen aufgebaut werden

    • Was passiert, wenn sich diese Spezifikationen weiterentwickeln oder ändern? Ist das dann eine neue API?
  • Etwas, das sich in einer Zahlungs-API nur schwer sauber modellieren lässt, ist, dass Zahlungssysteme bei Rückerstattungen die Rollen von Zahler und Empfänger unterschiedlich darstellen

    • Zum Beispiel können in manchen Systemen Zahler und Empfänger an derselben Position bleiben wie bei der ursprünglichen Zahlung
    • In anderen Systemen werden sie dagegen vertauscht