GraphQL-API, Customer-Token und der Vergleich zu Hyva SSR
Headless Commerce trennt das Magento-Backend über eine GraphQL-API von einem eigenständigen Frontend, egal ob PWA, native App oder IoT-Terminal. Der Artikel liefert einen konkreten Entscheidungsrahmen: wann sich die zusätzliche Komplexität durch Multi-Channel-Anforderungen und getrennte Teams auszahlt, und wann Hyva als serverseitig gerendertes Standard-Setup die schnellere und günstigere Wahl bleibt.
Inhaltsverzeichnis
- 1. Einordnung: Was Headless bei Magento konkret bedeutet
- 2. Architektur: GraphQL als API-Layer
- 3. Wann sich die Trennung lohnt
- 4. GraphQL-Schema erweitern: eigenes Modul und Resolver
- 5. Auth und Customer-Token im Headless-Setup
- 6. SEO-Herausforderungen bei SPA-Frontends
- 7. Infrastruktur und Deployment
- 8. Kosten-Nutzen: Wann sich das Investment nicht lohnt
- 9. Headless vs. Hyva SSR im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Einordnung: Was Headless bei Magento konkret bedeutet
Headless Commerce bedeutet, dass das Magento-Backend keine HTML-Seiten mehr ausliefert, sondern nur noch Daten über eine API bereitstellt, in der Regel über GraphQL, teilweise ergänzt durch REST-Endpunkte. Die eigentliche Darstellung, also HTML, CSS und die Interaktionslogik, übernimmt eine komplett getrennte Anwendung, etwa eine React- oder Vue-basierte PWA, eine native App oder ein Kassensystem. Backend und Frontend kommunizieren ausschließlich über die API, es gibt keine gemeinsame Codebasis und keinen gemeinsamen Deployment-Zyklus mehr.
Das Gegenmodell, das mironsoft als Standard einsetzt, ist Hyva mit serverseitigem Rendering. Hyva ersetzt das schwergewichtige Luma-Frontend durch schlanke PHTML-Templates, Tailwind CSS und Alpine.js für die clientseitige Interaktivität, bleibt aber im klassischen Magento-Request-Response-Zyklus. Der Server rendert vollständiges HTML aus, der Browser bekommt eine fertige Seite, zusätzliche Interaktivität kommt punktuell über Alpine-Komponenten dazu. Es gibt kein separates Frontend-Repository, keinen eigenen Build- und Deploy-Prozess für die Darstellungsschicht, und keine zweite Laufzeitumgebung, die betrieben werden muss.
Wichtig ist: Headless Magento ist kein Alles-oder-nichts-Entscheid. Es ist möglich, nur den Checkout oder nur eine mobile App headless zu betreiben, während der Hauptshop weiterhin serverseitig über Hyva gerendert wird. Die GraphQL-API existiert in Magento ohnehin, unabhängig davon, ob man sie aktiv für ein eigenständiges Frontend nutzt oder nicht, denn Hyva selbst nutzt für einzelne dynamische Bereiche wie den Warenkorb-Slider bereits GraphQL-Aufrufe im Hintergrund.
2. Architektur: GraphQL als API-Layer
Das Fundament jeder Headless-Commerce-Architektur mit Magento ist das GraphQL-Schema. Anders als bei REST, wo für jede Ressource ein eigener Endpunkt existiert, stellt GraphQL einen einzigen Endpunkt unter /graphql bereit, über den das Frontend exakt die Felder anfragt, die es tatsächlich benötigt. Das Schema wird modular aus mehreren schema.graphqls-Dateien zusammengesetzt, jedes Magento-Modul kann eigene Types, Queries und Mutations beisteuern, die zur Laufzeit zu einem einzigen Gesamtschema gemergt werden.
Für ein Frontend, das Produktlisten und Warenkorb abbilden muss, sind die Queries products und cart die zentralen Einstiegspunkte. Die products-Query erlaubt Filterung, Sortierung und Pagination über Argumente, während verschachtelte Felder wie price_range oder media_gallery nur dann geladen werden, wenn sie im Query-Body auch tatsächlich angefragt sind. Das eliminiert das klassische Over-Fetching-Problem von REST-APIs, bei dem immer der komplette Produktdatensatz übertragen wird, selbst wenn das Frontend nur Name und Preis braucht.
query ProductListWithCart($search: String!, $cartId: String!) {
products(search: $search, pageSize: 12, currentPage: 1) {
total_count
items {
sku
name
url_key
small_image { url label }
price_range {
minimum_price {
regular_price { value currency }
final_price { value currency }
}
}
}
page_info { current_page total_pages }
}
cart(cart_id: $cartId) {
id
total_quantity
prices {
grand_total { value currency }
}
items {
id
quantity
product { sku name }
}
}
}
Das Schema ist stark typisiert und per Introspection erkundbar, Tools wie GraphiQL oder Apollo Studio können das komplette Magento-Schema direkt aus dem laufenden System auslesen. Für Resolver-Entwickler bedeutet das: jede neue Query oder Mutation muss zuerst im Schema deklariert werden, bevor die PHP-Implementierung dahinter greift, das Schema ist also die verbindliche Vertragsgrundlage zwischen Backend-Team und jedem Frontend-Client, der gegen die API arbeitet.
3. Wann sich die Trennung lohnt
Das stärkste Argument für Headless Magento ist Multi-Channel. Sobald ein Shop nicht nur eine Webseite bedienen muss, sondern zusätzlich eine native iOS- und Android-App, ein Self-Service-Terminal im Ladengeschäft oder eine Sprachassistenten-Integration, wird eine zentrale GraphQL-API zum gemeinsamen Nenner. Jeder Kanal implementiert seine eigene Präsentationsschicht, aber alle greifen auf dieselbe Produktdaten-, Preis- und Warenkorblogik im Backend zu. Ohne diese Trennung müsste jede zusätzliche Plattform eigene Integrationen gegen REST-Endpunkte oder direkt gegen die Datenbank bauen, was schnell zu Inkonsistenzen führt.
Ein zweites Kriterium ist die Team-Struktur. Wenn ein Unternehmen bereits über ein etabliertes Frontend-Team mit React- oder Next.js-Expertise verfügt, das unabhängig vom Magento-Backend-Team release, testen und deployen will, erzwingt eine monolithische Hyva-Architektur künstliche Kopplung. Mit Headless Commerce kann das Frontend-Team eigene Sprints fahren, eigene Feature-Flags setzen und Deployments unabhängig von der Magento-Release-Planung durchführen, solange sich das GraphQL-Schema als Vertrag nicht bricht.
Drittens spielt Time-to-Market für neue Touchpoints eine Rolle. Ist die GraphQL-API einmal etabliert und ausreichend vollständig, kostet ein zusätzlicher Kanal, etwa eine neue Landingpage-Experience für eine Marketing-Kampagne oder eine Partner-Integration, deutlich weniger Backend-Aufwand, weil die Geschäftslogik bereits über die API verfügbar ist. Das Frontend-Team baut lediglich einen neuen Client gegen ein bestehendes, stabiles Schema, statt für jeden neuen Touchpoint erneut Backend-Anpassungen abzustimmen.
4. GraphQL-Schema erweitern: eigenes Modul und Resolver
Sobald Standard-Queries nicht ausreichen, etwa weil ein Frontend Kundenbindungspunkte oder ein individuelles Lagerbestandsfeld benötigt, wird das Schema per eigenem Modul erweitert. Die Deklaration erfolgt in einer schema.graphqls-Datei, die neue Felder an existierende Types anhängt oder komplett neue Queries definiert. Die eigentliche Logik dahinter liegt in einer Resolver-Klasse, die ResolverInterface implementiert und über Dependency Injection an das Schema gebunden wird.
<?php
declare(strict_types=1);
namespace Mironsoft\HeadlessApi\Model\Resolver;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
use Mironsoft\LoyaltyApi\Api\LoyaltyPointsRepositoryInterface;
/**
* Resolves the loyalty point balance for a customer in a headless frontend.
*/
final class CustomerLoyaltyPoints implements ResolverInterface
{
/**
* @param LoyaltyPointsRepositoryInterface $loyaltyPointsRepository Service contract for loyalty balances
*/
public function __construct(
private readonly LoyaltyPointsRepositoryInterface $loyaltyPointsRepository,
) {
}
/**
* Resolves the loyaltyPoints field for the currently authenticated customer.
*
* @param Field $field Resolved schema field
* @param mixed $context Resolver context with customer id
* @param ResolveInfo $info GraphQL resolve metadata
* @param array|null $value Parent field value
* @param array|null $args Query arguments
* @return array{points: int, expires_at: string|null}
* @throws GraphQlInputException
* @throws GraphQlNoSuchEntityException
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
?array $value = null,
?array $args = null,
): array {
$customerId = (int) ($context->getUserId() ?? 0);
if ($customerId === 0) {
throw new GraphQlInputException(__('Ein Kunde muss authentifiziert sein.'));
}
$balance = $this->loyaltyPointsRepository->getByCustomerId($customerId);
return [
'points' => $balance->getPoints(),
'expires_at' => $balance->getExpiresAt(),
];
}
}
Die passende schema.graphqls-Datei bleibt bewusst schlank und deklariert nur den Vertrag, nicht die Implementierung:
type Customer {
loyaltyPoints: LoyaltyPoints @resolver(class: "Mironsoft\\HeadlessApi\\Model\\Resolver\\CustomerLoyaltyPoints")
}
type LoyaltyPoints {
points: Int!
expires_at: String
}
Der Resolver nutzt konsequent Constructor Property Promotion aus PHP 8.4 und greift ausschließlich über das Service-Contract-Interface LoyaltyPointsRepositoryInterface auf die eigentliche Fachlogik zu, nie direkt auf ein Model oder eine Collection. Das hält den Resolver dünn und testbar, die eigentliche Geschäftslogik bleibt in der Repository-Implementierung gekapselt und lässt sich unabhängig vom GraphQL-Layer unit-testen.
5. Auth und Customer-Token im Headless-Setup
In einem klassischen Magento-Setup mit Hyva läuft die Kunden-Session über ein PHP-Session-Cookie, das der Browser bei jedem Request automatisch mitschickt. Sobald das Frontend eine eigenständige Anwendung auf einer anderen Domain oder in einer nativen App ist, funktioniert dieses Cookie-Modell nicht mehr zuverlässig, insbesondere wegen Cross-Origin-Beschränkungen und weil native Apps ohnehin keinen Browser-Cookie-Store teilen. Headless Commerce mit Magento setzt deshalb auf Bearer-Token-Authentifizierung über die Mutation generateCustomerToken.
Das Frontend sendet Login-Daten an diese Mutation und erhält im Gegenzug einen Token zurück, der bei jedem weiteren GraphQL-Request im Authorization-Header mitgeschickt wird. Magento validiert den Token serverseitig gegen die Integration-Token-Tabelle und ermittelt daraus die Customer-ID für den jeweiligen Resolver-Context, ganz ohne Session-Cookie. Für Warenkörbe vor dem Login wird zusätzlich eine cart_id für Gastkäufe erzeugt, die nach dem Login über die Mutation mergeCarts mit dem Kunden-Warenkorb zusammengeführt wird.
#!/usr/bin/env bash
# Step 1: authenticate and receive the bearer token
TOKEN=$(curl -s -X POST https://shop.mironsoft.de/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "mutation { generateCustomerToken(email: \"kunde@example.com\", password: \"secret\") { token } }"
}' | jq -r '.data.generateCustomerToken.token')
# Step 2: use the token for authenticated queries
curl -s -X POST https://shop.mironsoft.de/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${TOKEN}" \
-d '{
"query": "{ customer { firstname lastname email loyaltyPoints { points } } }"
}'
Ein wichtiger Punkt bei der Token-Verwaltung: Standard-Customer-Token in Magento laufen per Konfiguration ab, in der Regel nach wenigen Stunden, und müssen vom Frontend erneut angefordert werden. Für native Apps empfiehlt sich zusätzlich ein Refresh-Mechanismus über eine eigene Mutation, da ein erzwungener Re-Login bei jedem Token-Ablauf in einer App zu schlechter User Experience führt, während das im Browser-Kontext mit Hyva durch die serverseitige Session ohnehin transparent gelöst ist.
6. SEO-Herausforderungen bei SPA-Frontends
Der größte praktische Nachteil von Headless Commerce zeigt sich bei der Suchmaschinenoptimierung. Eine reine Single-Page-Application rendert Inhalte clientseitig per JavaScript, nachdem der initiale HTML-Response weitgehend leer war. Zwar können moderne Crawler JavaScript ausführen, aber das Crawl-Budget dafür ist begrenzt, und Rendering-Verzögerungen führen regelmäßig dazu, dass Produktdetails, Preise oder Verfügbarkeit erst mit Verzögerung oder gar nicht indexiert werden. Bei Hyva entfällt dieses Problem komplett, weil der Server bereits vollständiges, semantisches HTML samt Inhalt ausliefert.
Die gängige Antwort auf dieses Problem ist Server-Side-Rendering oder Prerendering auf Frontend-Seite, etwa über Next.js mit getServerSideProps oder eine dedizierte Prerender-Middleware, die Crawler-Requests erkennt und fertiges HTML ausliefert. Das bedeutet aber zusätzlichen Infrastruktur- und Wartungsaufwand: eine Node.js-Laufzeit muss betrieben, skaliert und überwacht werden, nur um dieselbe Grundfunktion nachzubauen, die Hyva serverseitig ohnehin liefert.
Zusätzlich müssen Meta-Tags und structured data, die bei Hyva direkt aus dem PHTML-Template und den Magento-Attributen kommen, im Headless-Frontend pro Route dynamisch aus den GraphQL-Antworten nachgebaut werden. Title, Description, Canonical-URL, Open-Graph-Daten und Product-Schema-JSON-LD müssen bei jedem Seitenwechsel neu gesetzt werden, meist über eine Head-Management-Bibliothek. Fehlt dieser Schritt, verliert die Seite strukturierte Daten und Social-Sharing-Vorschauen, ohne dass das im Frontend selbst sofort auffällt.
7. Infrastruktur und Deployment
Headless Commerce bedeutet zwangsläufig zwei getrennte Deployment-Pipelines. Das Magento-Backend durchläuft weiterhin den klassischen Composer-Build mit DI-Compile und Static-Content-Deploy, während das Frontend einen eigenen Node.js-basierten Build- und Deploy-Prozess bekommt, meist auf einer CDN-nahen Plattform wie Vercel, Netlify oder einem eigenen statischen Hosting hinter Cloudflare. Beide Pipelines müssen versioniert und aufeinander abgestimmt sein, damit ein Schema-Breaking-Change im Backend nicht unbemerkt ein bereits deployter Frontend-Build ausbremst.
Weil GraphQL-Requests standardmäßig als POST-Requests laufen, greifen klassische HTTP-Cache-Schichten wie Varnish nicht automatisch. Für Performance in einem Headless-Magento-Setup braucht es deshalb eine eigene Caching-Schicht vor dem GraphQL-Endpunkt, entweder über Persisted Queries mit GET-Requests und Cache-Keys, oder über einen dedizierten GraphQL-Edge-Cache, der Query-Hash und Store-View als Cache-Key nutzt und bei Produkt- oder Preisänderungen gezielt invalidiert wird.
#!/usr/bin/env bash
set -euo pipefail
# Backend pipeline: Magento build and deploy
echo "[backend] composer install and DI compile"
bin/composer install --no-dev --optimize-autoloader
bin/magento setup:di:compile
bin/magento setup:static-content:deploy de_DE en_US -f
bin/magento cache:flush
# Frontend pipeline: separate Node.js build and static deploy
echo "[frontend] build headless client"
npm --prefix frontend ci
npm --prefix frontend run build
npm --prefix frontend run deploy:production
# Purge the GraphQL edge cache after both pipelines finished
echo "[edge-cache] purge GraphQL cache for affected store views"
curl -s -X POST https://edge-cache.mironsoft.de/purge \
-H "Authorization: Bearer ${EDGE_CACHE_TOKEN}" \
-d '{"tags": ["graphql", "store-view:de_DE", "store-view:en_US"]}'
Ein Detail, das häufig unterschätzt wird: Cache-Invalidierung im GraphQL-Edge-Cache muss an dieselben Magento-Events gekoppelt werden, die auch die Varnish-Invalidierung bei einem klassischen Hyva-Setup auslösen, also Produkt-Speicherung, Preisänderung und Lagerbestand-Updates. Ohne diese Kopplung zeigt das Headless-Frontend veraltete Preise an, obwohl das Backend längst aktuelle Daten hätte.
8. Kosten-Nutzen: Wann sich das Investment nicht lohnt
Der Mehraufwand von Headless Commerce ist real und wird in frühen Planungsphasen regelmäßig unterschätzt. Zwei Systeme bedeuten zwei Technologie-Stacks, zwei Deployment-Pipelines, zwei Monitoring-Setups und in der Regel auch zwei Teams mit unterschiedlichem Skill-Profil. Ein Bug in der Preisberechnung kann sowohl im GraphQL-Resolver als auch in der Frontend-Formatierungslogik liegen, was Debugging und Fehlerzuordnung über die Systemgrenze hinweg erschwert.
Für kleinere Shops mit einem einzigen Vertriebskanal, also ausschließlich Desktop- und Mobile-Web ohne native App und ohne zusätzliche Touchpoints, lohnt sich diese Komplexität in den meisten Fällen nicht. Hyva liefert dieselbe moderne, schnelle Nutzererfahrung mit Tailwind und Alpine.js, ohne die SEO-Nacharbeit, ohne zweite Infrastruktur und ohne die Notwendigkeit, ein Frontend-Team parallel zum Backend-Team aufzubauen. Die Umsatzsteigerung durch bessere Core-Web-Vitals-Werte, die oft als Argument für Headless angeführt wird, lässt sich mit Hyva ebenfalls erreichen, weil das serverseitig gerenderte HTML von Haus aus schlank ist.
Die Entscheidung für Headless Magento sollte deshalb nie eine reine Technologie-Präferenz sein, sondern muss an einem konkreten Geschäftsbedarf hängen: mehrere aktive Kanäle, ein bereits vorhandenes und eingespieltes Frontend-Team, oder ein Produktkonzept, bei dem die Commerce-Logik explizit in verschiedene, unabhängig entwickelte Erlebniswelten eingebettet werden soll. Fehlt einer dieser Treiber, überwiegt der Mehraufwand den Nutzen fast immer.
9. Headless vs. Hyva SSR im direkten Vergleich
Die folgende Tabelle fasst die zentralen Entscheidungskriterien zusammen und ordnet sie einer konkreten Empfehlung zu, abhängig davon, welches Szenario im jeweiligen Projekt tatsächlich vorliegt.
| Kriterium | Hyva SSR | Headless / GraphQL | Empfehlung |
|---|---|---|---|
| Anzahl Vertriebskanäle | Ein Kanal, Web only | Web, native App, IoT, Kiosk | Ab 2+ echten Kanälen headless |
| SEO-Aufwand | Gering, HTML kommt vom Server | Hoch, SSR/Prerender nötig | Hyva bei SEO-Priorität |
| Team-Struktur | Ein Team, PHP und Tailwind | Getrennte Frontend/Backend-Teams | Headless nur mit echtem Frontend-Team |
| Infrastruktur-Aufwand | Eine Pipeline, ein Deployment | Zwei Pipelines, Edge-Cache nötig | Hyva bei kleinem Ops-Budget |
| Time-to-Market neuer Touchpoints | Neuer Kanal erfordert Theme-Arbeit | Neuer Client gegen bestehendes Schema | Headless bei häufigen neuen Kanälen |
Der rote Faden aus der Tabelle: Headless Commerce gewinnt genau dann, wenn Multi-Channel-Anforderungen, eine etablierte Frontend-Organisation und ein Bedarf an schneller Erweiterung um neue Touchpoints tatsächlich vorliegen. Fehlen diese Treiber, ist Hyva SSR in nahezu jedem Kriterium die pragmatischere und günstigere Lösung, ohne Abstriche bei Performance oder Nutzererfahrung.
10. Zusammenfassung
Headless Magento löst ein konkretes Problem: mehrere unabhängige Frontend-Kanäle, die alle auf dieselbe Commerce-Logik zugreifen sollen, ohne dass jeder Kanal eigene Backend-Integrationen bauen muss. Die GraphQL-API ist dafür die richtige Grundlage, mit eigenen Resolvern, Service Contracts und Customer-Token-Auth lässt sich das Schema sauber um projektspezifische Anforderungen erweitern. Wer diesen Weg geht, muss aber auch die Kosten einkalkulieren: getrennte Deployment-Pipelines, eine eigene Caching-Schicht vor GraphQL und deutlich mehr SEO-Aufwand, weil SPA-Frontends kein fertiges HTML mehr liefern.
Für die meisten Magento-Shops mit einem einzigen Kanal bleibt Hyva SSR die pragmatischere Wahl, schneller umzusetzen, günstiger im Betrieb und ohne die zusätzliche Systemgrenze zwischen Frontend und Backend. Die Entscheidung für Headless Commerce sollte daher immer aus einem echten Geschäftsbedarf abgeleitet werden, Multi-Channel, getrennte Teams oder hohe Anforderungen an Time-to-Market für neue Touchpoints, und nicht aus einer reinen Technologiepräferenz für moderne JavaScript-Frameworks.
Headless Magento: Das Wichtigste auf einen Blick
GraphQL als Vertrag
Das Schema aus mehreren schema.graphqls-Dateien ist die verbindliche Schnittstelle zwischen Backend und jedem Frontend-Client.
Customer-Token statt Cookie
Bearer-Token via generateCustomerToken ersetzt die PHP-Session, wenn Frontend und Backend auf getrennten Domains laufen.
SEO braucht Mehraufwand
SPA-Frontends brauchen SSR oder Prerendering plus dynamisches Meta- und JSON-LD-Management pro Route.
Entscheidung nach Bedarf
Headless lohnt sich bei Multi-Channel und getrennten Teams, Hyva SSR bleibt für einkanalige Shops die günstigere Wahl.
11. FAQ: Headless Magento und GraphQL
1Was bedeutet Headless Commerce bei Magento?
2Ist Headless immer besser als Hyva SSR?
3Kann man Headless und Hyva kombinieren?
4Wie erweitert man das GraphQL-Schema?
5Wie funktioniert Auth ohne Session-Cookie?
6Warum ist SEO bei SPA-Frontends schwieriger?
7Braucht Headless eine eigene Caching-Schicht?
8Welche Rolle spielt die Team-Struktur?
9Für welche Shops lohnt sich Headless nicht?
10Was passiert mit dem Warenkorb beim Login?
Mironsoft
Magento 2 Entwicklung, GraphQL-APIs und Hyva-Frontends
Headless Commerce oder Hyva SSR: welche Architektur passt zu eurem Shop?
Wir analysieren eure Kanaele, Team-Struktur und Wachstumsplaene und bauen entweder ein performantes Hyva-Frontend oder eine GraphQL-API mit eigenen Resolvern fuer ein echtes Headless-Setup, je nachdem, was sich fuer euch tatsaechlich rechnet.
Architektur-Beratung
Entscheidungsworkshop: Headless vs. Hyva SSR anhand eurer Kanaele und Teams
GraphQL-Module
Eigene Resolver, Schema-Erweiterungen und Customer-Token-Auth nach Service-Contract-Konvention
Hyva-Frontends
Schnelle, serverseitig gerenderte Shops ohne zusaetzliche Frontend-Infrastruktur