Headless und API first Solidus: die Voraussetzung für eine mobile App
Kurz gesagt
Niveau: Profi
Headless heißt, das Storefront ist ein Client des Shops und nicht der Shop selbst. Für die meisten Shops ist ein Hybrid richtig: eine Rails Anwendung mit serverseitig gerendertem Storefront und einer vollwertigen JSON API, die dieselben Regeln aufruft. Solidus liefert seine API mit dem Kern aus, mit Checkout, Zahlungen, Bestand, Bildgrößen, Token Authentifizierung und einem Eventbus. Kundenanmeldung, Versionierung, Rate Limits, Caching, Suche und Idempotenzschlüssel entwirfst du selbst. App Stores nehmen auf physische Waren keine Provision, aber Apple lehnt Apps ab, die nur eine umverpackte Website sind. Die App braucht also die API darunter.
Früher oder später fällt in einem wachsenden Onlineshop das Wort App, Marktplatz oder zweites Storefront, und wie schwer das wird, wurde entschieden, bevor der Shop gebaut war. In diesem Artikel erkläre ich, was Headless wirklich heißt, wann es sich lohnt und wann nicht, welchen Hybrid aus einer Anwendung ich auf Solidus baue, was die aktuelle Solidus API tatsächlich mitbringt, was du selbst entwerfen musst und was Apple und Google einem Shop berechnen, der physische Waren in einer App verkauft.
Ein Shop, der nur mit Browsern reden kann, ist teuer zu erweitern
Früher oder später fällt in einem wachsenden Onlineshop das Wort App. Oder Marktplatz. Oder ein Tablet für den Showroom, oder eine zweite Marke, die denselben Bestand über eine anders aussehende Seite verkauft. Dann fragt die Inhaberin, wie schwer das wäre, und die ehrliche Antwort hängt fast vollständig an einer Entscheidung, die vor dem Bau des Shops gefallen ist: Wurde er als Website gebaut, die nebenbei verkauft, oder als Verkaufssystem, vor dem zufällig eine Website steht?
Genau diese Unterscheidung meinen Leute mit Headless, wenn sie überhaupt etwas damit meinen. In diesem Artikel erkläre ich, was das wirklich heißt, wann es sich lohnt und wann nicht, was dir Solidus heute mitgibt (geprüft am aktuellen Quellcode, Version 4.8.11), was du trotzdem selbst entwerfen musst und was die App Stores verlangen und was nicht. Die grundsätzliche Abwägung der Plattform steht in meinem Vergleich der Shopsysteme. Dieser Text ist enger gefasst und technischer.
Was Headless heißt, in einem Satz
Das Storefront ist ein Client des Shops. Es ist nicht der Shop.
In einem klassischen Shop ist der Code, der die Produktseite rendert, derselbe Code, der weiß, was das Produkt kostet, ob es lagernd ist, welche Aktion gilt und was beim Klick auf In den Warenkorb passiert. Regeln und Pixel wohnen zusammen. Das geht gut, bis du eine zweite Oberfläche willst. Dann merkst du, dass die Regeln in der ersten verheddert sind, und du musst sie entweder doppelt bauen oder auseinanderziehen.
In einem Headless Shop wohnen die Regeln an einer Stelle und sind über eine Schnittstelle erreichbar, fast immer eine JSON API über HTTP. Die Website fragt diese Schnittstelle. Die App auch, der Marktplatzfeed, das Tablet im Showroom und das Lagertool. Keiner davon weiß etwas über Preise, Bestand oder Aktionen. Sie fragen, und sie bekommen eine Antwort.
Wenn die Website und die App deiner Bank immer denselben Kontostand zeigen, hast du so ein System schon benutzt. Der Kontostand liegt nicht in der App. Die App fragt.
Das Marketingwort und der Vertrag
Fast jede Plattform nennt sich heute headless, weil fast jede Plattform irgendeine API hat. Im Marketingsinn bedeutet das Wort nichts mehr. Entscheidend ist, ob die API der Vertrag ist, über den jeder Client geht, oder eine Seitentür neben der eigentlichen Logik. Drei Fragen trennen das.
Erstens: Bedient dieselbe Logik Website und API? Nimmt die Website einen privilegierten Weg und ist die API nur eine Übersetzung davon, hinkt die API immer hinterher. Eine im Admin angelegte Aktion funktioniert im Web und schweigt in der App.
Zweitens: Kannst du über die API tun, was dein Geschäft tatsächlich braucht? Nicht "das meiste", sondern genau die Vorgänge, die deine App, dein Feed oder dein Lagertool brauchen werden. Solidus zeigt gut, warum du prüfen statt annehmen solltest: Die API deckt Produkte, Bestellungen, Checkout, Zahlungen, Sendungen und Bestand ab, aber Aktionen sind nur lesbar, abgesehen vom Einlösen und Entfernen von Gutscheincodes an einer Bestellung, und es gibt keinen eigenen Endpunkt für Rückerstattungen (Zahlungen haben stattdessen eine Credit Aktion)2.
Drittens: Wem gehört die API? Gehört sie einem Anbieter, entscheidet der über Limits, Versionen, Abkündigungen und Preis. Liegt sie in deinem Code auf deinem Server, ändert sie sich, wenn du sie änderst. Bei Solidus ist die dritte Antwort eindeutig: Es ist ein Open Source Rails Framework, die API Engine gehört dazu und läuft in deiner eigenen Anwendung.
Wann sich ein getrenntes Frontend lohnt
"Flexibilität" ist kein Business Case. Hier sind die konkreten.
Du willst eine mobile App. Eine App ist ein zweites Storefront, das auf dem Handy läuft. Sie braucht Katalog, Warenkorb, Checkout, Kundenkonto und Bestellhistorie, und alles muss sich genau so verhalten wie auf der Website, weil dieselbe Kundin beides benutzt. Ohne API baust du das alles zweimal, und die Kopien laufen auseinander.
Du verkaufst über Marktplätze oder Partner. Amazon, Kaufland, ein Branchenportal, ein Händler, der dein Sortiment listet. Jeder will Produkte und Bestand heraus und Bestellungen hinein. Das ist eine API in beide Richtungen, kein nächtlicher Tabellenexport, der die meiste Zeit des Tages falsch ist.
Du betreibst eine zweite Marke auf demselben Katalog. Eine Händlerseite und eine Endkundenseite, oder ein österreichischer und ein deutscher Shop mit anderen Preisen, Steuersätzen und Rechtstexten. Liegen die Regeln an einer Stelle, ist das zweite Storefront ein Designauftrag. Liegen sie in den Templates, ist es ein zweiter Shop.
Du verkaufst auch vor Ort. Ein Tablet am Marktstand oder im Showroom, das aus demselben Bestand zu denselben Preisen verkauft und die Bestellung in dieselbe Warteschlange fürs Lager legt.
Deine Systeme müssen miteinander reden. ERP, Lagerverwaltung, Buchhaltung, CRM, ein Newslettertool, das von abgebrochenen Warenkörben wissen will. Jede Anbindung wird leichter mit einem dokumentierten Weg hinein und hinaus.
Stehen zwei oder mehr davon wirklich auf der Roadmap, und nicht nur einmal in einem Meeting erwähnt, ist die API keine Option, sondern Pflicht.
Wann es sich nicht lohnt
Ein Storefront und keine Pläne. Eine Website, keine App, keine Marktplätze, Anbindungen nur an einen Zahlungsanbieter und ein Mailtool. Ein komplett entkoppelter Bau heißt hier zwei Anwendungen, die du ausrollst, überwachst und debuggst, und zwei Hostingrechnungen, für Flexibilität, die du nicht nutzt.
Ein kleines Team. Ein JavaScript Frontend, das mit einem Ruby Backend redet, braucht zwei Skillsets, zwei Buildpipelines und hat zwei Orte, an denen sich ein Fehler verstecken kann. Ein Team aus ein oder zwei Leuten fährt mit einer Anwendung besser.
Ein großer Katalog, der von Suchtraffic lebt. Hängt dein Umsatz davon ab, dass Google Tausende Produktseiten findet, müssen diese Seiten als schnelles, vollständiges HTML mit korrekten strukturierten Daten ankommen. Ein JavaScript Frontend schafft das mit einem Framework für serverseitiges Rendern, aber dann hast du eine Renderschicht ergänzt, um ein Problem zu lösen, das eine Rails Anwendung nie hatte, und jede Umstellung von URLs und Templates gefährdet Rankings, die du dir schon verdient hast.
Die Antwort ist also selten "ganz headless oder gar nicht". Sie ist die Variante, die dir den Vertrag gibt, ohne zwei Anwendungen betreiben zu müssen.
Der Hybrid, den ich baue: eine Anwendung, zwei Eingänge
Jeder Solidus Shop, den ich baue, hat dieselbe Form. Es gibt eine Rails Anwendung. Sie enthält den Solidus Kern, dem Produkte, Varianten, Preise, Bestand, Aktionen, Bestellungen, Zahlungen, Sendungen und Steuern gehören. Sie enthält ein serverseitig gerendertes Storefront: ganz normale Rails Controller und Views, die HTML erzeugen, das deine Kundschaft sieht und Google indexiert. Und sie enthält die JSON API, eine zweite Reihe Controller, die dieselben Modelle für alles bereitstellen, was kein Browser ist.
Wichtig ist, was diese beiden Reihen gemeinsam haben, nämlich alles darunter.
Legt jemand auf der Website etwas in den Warenkorb, ruft der Storefront Controller denselben Code auf wie der API Controller, wenn eine App das tut. In Solidus ist dieser gemeinsame Weg das Contents Objekt der Bestellung: Der Line Item Endpunkt der API ruft @order.contents.add mit Variante, Menge und Optionen auf3, und der Warenkorb Controller des offiziellen Starter Storefronts macht dasselbe4. Dieselben Aktionsregeln laufen, dieselbe Bestandsprüfung passiert, und derselbe Vergleich entscheidet, ob das eine neue Zeile ist oder mehr von einer bestehenden.
Ich nenne das API first, obwohl das Storefront nicht über HTTP mit der API spricht. Die API wird von Anfang an als vollwertiger Teil entworfen, die Regeln bleiben aus den Views heraus, und nichts, was das Storefront kann, ist über die API unmöglich. Das Ergebnis ist eine Anwendung zum Ausrollen, Überwachen, Absichern und Testen, serverseitig gerenderte Seiten für Suche und Tempo, und eine Antwort auf "Können wir eine App haben?", die mit "Die API ist schon da" beginnt.
Was Solidus heute mitbringt
Solidus wird als Gruppe von Gems ausgeliefert, und das Gem solidus, das du installierst, hängt neben Kern und Admin von solidus_api ab5. Die API ist keine optionale Erweiterung. Das bekommst du, geprüft am Quellcode.
Katalog und Bestand. Produkte, Varianten, Optionstypen, Taxonomien und Taxons, Produkteigenschaften, Bilder, Lagerorte, Lagerposten und Lagerbewegungen2. Listen sind mit dem Parameter per_page seitenweise abrufbar und nehmen Suchfilter an.
Warenkorb und Checkout. Bestellungen, Positionen, Adressen, Sendungen mit Wahl der Versandart, Zahlungen mit den Aktionen authorize, capture, purchase, void und credit, Gutscheincodes, Retouren und Kundenretouren2. Die Checkout Endpunkte treiben dieselbe Zustandsmaschine wie der Webcheckout. Ein eigener Checkoutschritt an der Bestellung existiert also auch in der API.
Authentifizierung. Anfragen tragen den API Key einer Nutzerin als Authorization: Bearer <key>, Gäste schicken das Gasttoken der Bestellung im Header X-Spree-Order-Token6. Zwei Voreinstellungen sind für eine App wichtig. API Keys werden standardmäßig nur für Admins erzeugt, und die Anmeldung, die einer Kunden App einen Key übergibt, musst du selbst bauen6. Außerdem verlangt jeder Endpunkt eine Authentifizierung, solange du die Einstellung requires_authentication nicht für die öffentlichen Endpunkte abschaltest, etwa die Produktliste7.
Bilder in mehreren Größen. Jedes Bild in der API Antwort kommt mit einer URL pro konfiguriertem Stil, standardmäßig mini (48 Pixel), small (400), product (680) und large (1200), gespeichert über Active Storage8. Das ist ein besserer Ausgangspunkt, als viele erwarten. Selbst entscheidest du das CDN davor und ob die Formate zu einer App passen.
Ein Eventbus. Solidus veröffentlicht Ereignisse über Spree::Bus, gebaut auf der Publish und Subscribe Bibliothek Omnes9. Der Kern registriert Ereignisse wie order_finalized, order_canceled, order_emptied, order_recalculated, order_short_shipped, carton_shipped, reimbursement_reimbursed und reimbursement_errored10. Ein Kernereignis für eine fehlgeschlagene Zahlung gibt es nicht, und auch keine eingebaute Verwaltung für ausgehende Webhooks. Ein Subscriber, der bei order_finalized JSON an ein anderes System schickt, ist eine kleine Klasse, die du in einem Initializer registrierst, und eigene Ereignisse kannst du auf demselben Bus veröffentlichen.
Zwei Dinge bekommst du nicht. Es gibt eine offizielle GraphQL Erweiterung, aber ihr README nennt Unterstützung für Solidus 2.11 und 3.x, und im Repository gab es seit Oktober 2023 keinen Commit mehr11. Auf Solidus 4 würde ich keine App darauf bauen. Plane mit REST. Und das Storefront ist kein Gem mehr: Das offizielle solidus_starter_frontend wird mit bin/rails generate solidus:install --frontend=starter in deine Anwendung generiert4. Der Storefront Code gehört also dir und ist frei änderbar, genau das, was der Hybrid braucht.
Ein Checkout über die API, Schritt für Schritt
Die API Dokumentation von Solidus beschreibt den kompletten Checkout als Folge von Aufrufen12. Durch diese Reihenfolge geht eine App, und es ist dieselbe wie im Webcheckout.
Eine Position als Gast hinzufügen sieht so aus. Bestellnummer, Token und Varianten ID sind Platzhalter.
curl -X POST https://shop.example/api/checkouts/R123456789/line_items \
-H "Content-Type: application/json" \
-H "X-Spree-Order-Token: GUEST_TOKEN" \
-d '{"line_item": {"variant_id": 42, "quantity": 1}}'
Und abschließen, mit der Summe, die die Kundin auf dem Bestätigungsbildschirm gesehen hat:
curl -X PUT "https://shop.example/api/checkouts/R123456789/complete?expected_total=70.00" \
-H "X-Spree-Order-Token: GUEST_TOKEN"
Der Parameter expected_total ist Gold wert. Hat sich die Summe seit dem Ansehen geändert, weil sich zwischendurch ein Preis oder eine Aktion geändert hat, lehnt der Endpunkt mit einem 400 ab, statt einen anderen Betrag abzubuchen13.
Was du selbst entwerfen musst
Versionierung. Ist eine App erst in den Stores, kannst du keine API Antwort mehr ändern, ohne Handys kaputtzumachen, die du nicht kontrollierst, weil irgendwer noch die Version von vor acht Monaten nutzt. Solidus versioniert seine API nicht für dich. Entscheide vor dem ersten Release: Version in der URL, ein Header, oder die Regel, dass Antworten nur Felder dazubekommen und nie welche verlieren. Ich nehme die letzte, mit einem bewussten Versionssprung für die seltene Änderung, die nicht additiv geht.
Rate Limits. Eine öffentliche API wird von Dingen getroffen, die nicht deine App sind: Scraper, die Anbindung eines Partners in einer Wiederholungsschleife. Rack::Attack, eine gepflegte Rack Middleware, drosselt pro Key oder pro Adresse und antwortet mit einem sauberen 429, statt umzufallen14.
Caching. Produktdaten werden ständig gelesen und selten geändert. HTTP Cache Header, bedingte Anfragen und ein Cache vor den leselastigen Endpunkten verhindern, dass eine App deinen Server härter arbeiten lässt als die Website.
Eine Kundenanmeldung für die App. Wie oben: Solidus gibt Admins API Keys und überlässt dir die Anmeldung der Kundschaft. Eine mobile App will meistens kurzlebige Tokens mit Refresh, die du obendrauf baust.
Suche. Die Listen filtern nach Name, Taxon und Preis. Das reicht für einen Kategoriebildschirm, nicht für ein Suchfeld mit Tippfehlertoleranz und Ergebnissen in unter einer Zehntelsekunde. Dafür brauchst du einen Index, der mit dem Katalog synchron bleibt.
Dokumentation. Die Kern API hat eine OpenAPI Beschreibung im Repository12. Deine eigenen Endpunkte brauchen dasselbe, am besten aus den Tests erzeugt, damit sie nicht veralten kann. Wie das geht, steht in meinem Artikel über das Testen von APIs.
Idempotenz. Die bekommt einen eigenen Abschnitt.
Wiederholungen, Idempotenz und die doppelte Abbuchung
Auf einer Website passiert eine Zahlung einmal, weil der Browser ein Formular einmal abschickt. Auf dem Handy reißt die Verbindung im Tunnel oder im Aufzug ab, und eine App, die "schließ diese Bestellung ab" schickt und keine Antwort hört, schickt es, naiv programmiert, noch einmal.
Solidus schützt den gefährlichsten Aufruf schon besser als viele Plattformen. Die Checkout und Line Item Aktionen sperren die Bestellung, solange sie laufen, und die Zustandsmaschine schließt keine Bestellung ab, die schon abgeschlossen ist13. Ein wiederholter Complete Aufruf schließt die Bestellung also nicht zweimal ab. Er erzeugt aber einen Fehler für einen Kauf, der in Wahrheit geklappt hat, und eine App, die "Zahlung fehlgeschlagen" zu jemandem sagt, der gerade bezahlt hat. Das größere Risiko sind die Aufrufe, die etwas anlegen: Ein wiederholtes POST /api/orders legt eine zweite Bestellung an, und eine wiederholte Zahlungsanlage hängt eine zweite Zahlung an die Bestellung.
Die übliche Lösung ist ein Idempotenzschlüssel. Die App erzeugt pro Versuch einen eindeutigen Schlüssel und schickt ihn mit, der Server speichert die erste Antwort unter diesem Schlüssel und liefert sie bei jeder Wiederholung erneut. Stripe arbeitet genau so: Es speichert Status und Inhalt der ersten Anfrage mit einem Schlüssel, liefert sie bei Wiederholungen zurück und kann Schlüssel nach 24 Stunden löschen15. Bei der IETF gibt es einen aktiven Entwurf, der dafür einen eigenen HTTP Header Idempotency-Key standardisiert16. Solidus setzt das nicht um, also ergänze ich eine kleine Tabelle bereits gesehener Schlüssel und eine Prüfung vor jedem Endpunkt mit Nebenwirkung: Bestellanlage, Zahlungen, Abschluss, alles, was eine Nachricht verschickt oder Bestand bewegt. Das ist ein Nachmittag Arbeit und die günstigste Versicherung, die ein Shop mit App abschließen kann.
The Gift Bow: was heute existiert und was eine App bräuchte
The Gift Bow ist ein Demoshop für Geschenke und Geschenkkörbe, den ich gerade auf Solidus baue. Er ist noch in Arbeit und nicht öffentlich zugänglich, zeigt die Disziplin aber schon in der Praxis. Das kann er heute. Er ist zweisprachig, Englisch und Deutsch. Er verkauft aus fünf eigenen Preislisten, in Pfund, Euro sowie US, australischen und neuseeländischen Dollar, mit eigenen Preisen je Währung statt umgerechneter Zahlen. Er hat einen Korb Konfigurator: In der Euro Preisliste kostet The Sweet Spot fix 70 € für genau sechs Leckereien, The Showstopper fix 115 € für genau acht, davon höchstens zwei aus Wein und Spirituosen, und Free Range wird nach Inhalt berechnet. Tee und Kaffee gibt es im Abo mit 10 % Rabatt, geliefert alle zwei, vier oder acht Wochen. Die Karten auf der Startseite sind Datensätze im Admin mit Start und Enddatum. So lässt sich eine Weihnachtskollektion für den 1. November einplanen, ohne dass jemand die Seite anfasst.
Jede dieser Funktionen ist als Regel an Bestellung, Position oder Produkt gebaut, nicht als View. Der gewählte Inhalt eines Korbs reist als strukturierte Daten an der Position mit, und eine Vergleichsregel im Modell sagt dem Warenkorb, dass zwei Körbe mit unterschiedlichem Inhalt zwei Zeilen sind und nicht Menge zwei. Das Abointervall ist ein Attribut der Position mit eigener Vergleichsregel. Die Währung ist eine Preisoption an der Bestellung.
Was eine App bräuchte, lässt sich ehrlich sagen. Die Standardendpunkte funktionieren heute mit einem API Key, wie in jedem Solidus Shop. Der Korb Konfigurator hat noch keinen eigenen JSON Endpunkt, weil ihn bisher nichts braucht: Heute ist er ein Storefront Formular vor dem Korb Service. Eine App bräuchte diesen Endpunkt, der einen Behälter und eine Liste ausgewählter Produkte annimmt und denselben Service aufruft wie das Formular, dazu Kundenanmeldung, Versionierung und Idempotenz aus den Abschnitten oben. Sie bräuchte nicht, dass jemand die Geschäftsregeln aus Templates herausgräbt, weil sie nie in den Templates lagen. Genau diese fehlende Phase ist der Punkt.
Was es kostet, es später zu machen, als Rechnung
"Mach es gleich richtig" sagt jeder, und keiner rechnet es aus. Ein einfacher Erwartungswertvergleich tut es. Die Regeln von Anfang an aus den Views herauszuhalten kostet jetzt einen bekannten Betrag. Eine API nachträglich auf einen Shop zu setzen, in dem die Regeln in die Views gewachsen sind, kostet mehr, aber nur, falls der zweite Client je kommt. Es jetzt zu tun lohnt sich, wenn
wobei die Wahrscheinlichkeit ist, dass während der Lebensdauer des Shops eine App, ein Marktplatzfeed oder ein zweites Storefront kommt, die Kosten der Nachrüstung, wenn es so weit ist, und die Mehrkosten, die Disziplin von Anfang an einzubauen. Warum man Kosten mit ihrer Wahrscheinlichkeit multipliziert, um fair zu vergleichen, steht im Abschnitt zum Erwartungswert in den Grundlagen.
Ein Beispiel mit einem erfundenen Shop, donaukorb.example in Linz, und Annahmen, die als Annahmen benannt sind. Der Bau kostet 60.000 €. Die Disziplin (Service Objekte statt Logik in Controllern, ein API Test neben jedem Webtest, Entscheidungen zu Bildern und Versionen früh getroffen) kostet 4.000 € mehr. Eine Nachrüstung, also jede Regel in den Views finden und verschieben, während der Shop live bleibt, ist mit 20.000 € angesetzt, bevor eine Zeile App geschrieben ist. Die Schwelle liegt bei
wobei die Wahrscheinlichkeit ist, ab der der Einbau von Anfang an die bessere Wette ist, die 4.000 € jetzt und die 20.000 € später. Besteht eine bessere Chance als eins zu fünf, dass der Shop in seinem Leben eine App, einen Marktplatzfeed oder ein zweites Storefront will, zahlt sich die Disziplin allein über den Erwartungswert aus, noch bevor du die Monate Verzögerung und das Risiko zählst, bei einer Nachrüstung einen laufenden Shop zu beschädigen. Setz deine eigenen Angebote ein, die Methode bleibt dieselbe.
Was die App Stores einem Shop berechnen
Zwei Fakten verändern den Business Case einer Shop App stärker als jede Architekturentscheidung, und beide sind besser, als viele befürchten.
Erstens die Provision. Apples App Store Review Guidelines sagen, dass eine App, die physische Waren oder außerhalb der App genutzte Dienstleistungen verkauft, andere Zahlungswege als In App Käufe nutzen muss, etwa Apple Pay oder die Eingabe einer Karte17. Google Play führt Käufe physischer Waren unter denen, die sein Abrechnungssystem nicht abdeckt18. Eine Shop App, die Geschenkkörbe über deinen eigenen Zahlungsanbieter abrechnet, zahlt auf diese Bestellungen also keine Store Provision. Kosten entstehen für die Entwicklerkonten: Das Apple Developer Program kostet 99 US Dollar im Jahr19, ein Google Play Entwicklerkonto einmalig 25 US Dollar20.
Zweitens die Prüfung. Apples Richtlinie 4.2 verlangt, dass eine App Funktionen, Inhalte und eine Oberfläche bietet, die über eine umverpackte Website hinausgehen17. Ein in eine App Hülle gesteckter Webshop riskiert die Ablehnung. Eine native App, die mit einer ordentlichen API spricht, mit gespeichertem Warenkorb, Sendungsverfolgung und Benachrichtigungen für Stammkundschaft, ist genau das, was die Richtlinie will, und sie braucht die API darunter.
Ob ein Shop überhaupt eine App braucht, ist eine eigene Frage. Wiederkauf und Abo Geschäfte, bei denen die Kundschaft monatlich wiederkommt und Benachrichtigungen und einen gespeicherten Warenkorb schätzt, sind die naheliegenden Kandidaten. Ein Shop, der jemandem alle sieben Jahre ein Sofa verkauft, meistens nicht. Passt eine App, baue ich sie in React Native, eine Codebasis für iOS und Android, gegen dieselbe API wie alles andere.
API bereit ab dem ersten Tag, als Checkliste
Das bedeutet der Ausdruck in einem Projekt, in der Reihenfolge, in der ich es mache.
- Geschäftsregeln leben in Services und Modellen, nie in Views oder Controllern. Ein Controller nimmt Eingaben an, ruft etwas auf und rendert.
- Jede Funktion des Webstorefronts bekommt neben dem Webtest einen API Test, der zeigt, dass der Endpunkt dasselbe tut. Das verhindert das Auseinanderdriften.
- Antworten bekommen nur Felder dazu. Ein Feld umbenennen oder entfernen ist ein bewusster Versionssprung.
- Jeder Endpunkt mit Nebenwirkung nimmt einen Idempotenzschlüssel an, und die App schickt beim Abschluss
expected_totalmit. - Bilder werden in benannten Größen über ein CDN ausgeliefert.
- Es gibt ein Rate Limit und eine Möglichkeit zu sehen, wer was aufruft.
- Die Kundenanmeldung für API Clients ist entworfen, nicht improvisiert.
- Der Vertrag ist aufgeschrieben und wird aus den Tests erzeugt.
Nichts davon ist exotisch, und es kostet wenig, wenn du so anfängst.
Wo dich das hinführt
Baust du einen neuen Shop, verlange den Hybrid: eine Anwendung, ein serverseitig gerendertes Storefront, eine vollwertige API, Regeln an einer Stelle. Lass dir die API Tests neben den Webtests zeigen und frag, was passiert, wenn die App eine Zahlung wiederholt.
Hast du schon einen Shop und die App Frage ist da, lass jemanden nachsehen, wo die Regeln wohnen, bevor irgendwer die App anbietet. Das App Angebot ist nur die Hälfte der Zahl.
Bei den Shops, die ich baue, gehört der individuelle Solidus Code nach vollständiger Bezahlung dir. Die API, die Services dahinter und die Tests sind also dein Vermögenswert, keine Lizenz. Willst du sehen, wie das mit echten Funktionen aussieht? Ich gehe den Ansatz gern mit dir durch, in einem kostenlosen Workshop, und die ersten zwei Wochen Arbeit gehen auf mich.