Magento-GraphQL-Architektur im Überblick: schema.graphqls, Resolver, DataProvider
Magento-GraphQL-Architektur im Überblick: schema.graphqls, Resolver, DataProvider
~7 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026
Bevor es an eigenen Code geht, lohnt sich der Blick auf die drei Bausteine, aus denen jede Magento-GraphQL-Funktionalität besteht: die Schema-Deklaration in schema.graphqls, der Resolver und - optional, aber üblich - eine separate DataProvider-Klasse. Wer diese drei Bausteine und ihr Zusammenspiel verstanden hat, kann jede Magento-GraphQL-Funktionalität lesen und erweitern, egal wie tief sie im Core verschachtelt ist.
schema.graphqls: die Deklaration
Jedes GraphQL-fähige Modul kann eine Datei etc/schema.graphqls mitbringen. Sie ist in der GraphQL Schema Definition Language (SDL) geschrieben - kein PHP, kein XML, sondern die von der GraphQL-Spezifikation selbst vorgegebene Syntax. Magento sammelt beim Start alle schema.graphqls-Dateien aller aktiven Module ein und fügt sie zu einem einzigen, globalen Schema zusammen - deshalb kann ein Modul mit extend type Felder an Typen anhängen, die in einem ganz anderen Modul definiert wurden (Block 3).
type Query {
products(
search: String
filter: ProductAttributeFilterInput
pageSize: Int = 20
currentPage: Int = 1
sort: ProductAttributeSortInput
): Products
@resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products")
@doc(description: "The products query searches for products")
}Die entscheidende Zeile ist @resolver(class: "...") - eine Direktive, die ein Query- oder Mutation-Feld mit einer PHP-Klasse verknüpft. Ohne diese Direktive kennt Magento zwar den Typ des Feldes, weiß aber nicht, welcher Code die Daten dafür liefert.
Der Resolver: das Bindeglied zu PHP
Ein Resolver ist eine einfache PHP-Klasse, die \Magento\Framework\GraphQl\Query\ResolverInterface implementiert. Für jedes Feld mit einer @resolver-Direktive ruft Magento zur Laufzeit dessen resolve()-Methode auf:
interface ResolverInterface
{
public function resolve(
Field $field,
$context,
ResolveInfo $info,
?array $value = null,
?array $args = null
);
}$args enthält die vom Client übergebenen Argumente (z. B. search, pageSize), $context trägt Informationen zum aufrufenden Kunden/Store/Website, und der Rückgabewert wird direkt in die JSON-Antwort serialisiert. Kapitel 10 geht auf jeden dieser Parameter im Detail ein.
Der DataProvider: saubere Trennung von Auflösung und Datenzugriff
Magento selbst hält Resolver bewusst dünn und lagert die eigentliche Datenbeschaffung in eine separate DataProvider-Klasse aus - kein vom Framework erzwungenes Interface, sondern eine Konvention, die sich in praktisch jedem Core-GraphQl-Modul wiederfindet. Der Resolver bleibt schlank (Argumente entgegennehmen, DataProvider aufrufen, Ergebnis formen), während der DataProvider die eigentliche Fachlogik übernimmt - typischerweise unter Wiederverwendung eines bestehenden Repositories, statt Collections direkt anzufassen.
Typische Aufteilung in einem Core-GraphQl-Modul
Magento/CatalogGraphQl/
├── etc/
│ └── schema.graphqls
└── Model/
└── Resolver/
├── Products.php (implementiert ResolverInterface)
└── Products/
└── DataProvider/
└── Product.php (baut SearchCriteria, ruft Repository)Der vollständige Ablauf einer Anfrage
- Der Client schickt eine GraphQL-Query per
POSTan/graphql. - Magentos GraphQL-Controller (
Magento\GraphQl\Controller\GraphQl) parst die Query gegen das zusammengeführte globale Schema. - Für jedes angefragte Feld mit
@resolver-Direktive wird die passende Resolver-Klasse instanziiert undresolve()aufgerufen. - Der Resolver delegiert an einen DataProvider, der - meist über ein Repository oder eine Collection - die Daten aus der Datenbank lädt.
- Der Rückgabewert des Resolvers (ein assoziatives Array) wird gegen den im Schema deklarierten Typ geprüft und zu JSON serialisiert.
Tipp: Felder ohne eigene @resolver-Direktive sind kein Fehler: Magento löst sie automatisch über einen Default-Resolver auf, der einfach den gleichnamigen Schlüssel aus dem von der übergeordneten Query gelieferten Array liest. Ein eigener Resolver lohnt sich erst, wenn ein Feld eigene Logik braucht - mehr dazu in Kapitel 5.
Kapitel 3 nutzt genau diesen bereits vorhandenen Ablauf: die eingebaute GraphQL-Schnittstelle mit einem echten Client abfragen, ohne selbst eine Zeile PHP zu schreiben.