Zusammenfassung: Spickzettel aller wichtigsten GraphQL-Patterns aus dieser Serie
Zusammenfassung: Spickzettel aller wichtigsten GraphQL-Patterns aus dieser Serie
~7 Min. Lesezeit Zuletzt aktualisiert am 9. August 2026
26 Kapitel, ein durchgehendes Projekt, eine vollständige Veranstaltungen-GraphQL-API von der ersten Schema-Deklaration bis zu ACL und Batch-Resolvern. Dieses letzte Kapitel bündelt die wichtigsten Muster als Nachschlagewerk für die eigene Praxis - ohne neue Inhalte, nur Verdichtung.
Schema-Grundgerüst
type Query {
myField(arg: String): MyType
@resolver(class: "Vendor\\Module\\Model\\Resolver\\MyField")
@doc(description: "...")
}
type Mutation {
myMutation(input: MyMutationInput!): MyMutationOutput
@resolver(class: "Vendor\\Module\\Model\\Resolver\\MyMutation")
}
extend type ExistingCoreType {
my_extra_field: String @resolver(class: "...")
}Resolver-Skelett
final class MyField implements ResolverInterface
{
public function __construct(
private readonly MyDataProvider $dataProvider,
) {
}
public function resolve(
Field $field,
$context,
ResolveInfo $info,
?array $value = null,
?array $args = null
): array {
return $this->dataProvider->getData($args);
}
}Die vier GraphQL-Exceptions
GraphQlInputException- fachlich ungültige Eingabe.GraphQlAuthorizationException- fehlende Berechtigung.GraphQlNoSuchEntityException- Entität existiert nicht.GraphQlAlreadyExistsException- eindeutiger Wert bereits vergeben.- Immer mit
__('...')statt rohem String (übersetzbar).
Authentifizierungs-Check im Resolver
if ($context->getUserType() !== UserContextInterface::USER_TYPE_CUSTOMER
|| !$context->getExtensionAttributes()->getIsCustomer()
) {
throw new GraphQlAuthorizationException(__('...'));
}
$customerId = (int) $context->getUserId();Batch-Resolver gegen N+1
final class MyBatchField implements BatchResolverInterface
{
public function resolve(array $requests): BatchResponse
{
$response = new BatchResponse();
// alle IDs aus $requests sammeln, EINE Abfrage, Ergebnisse zuordnen
foreach ($requests as $request) {
$response->addResponse($request, /* ... */ null);
}
return $response;
}
}Die zehn goldenen Regeln dieser Serie
- Nach jeder
schema.graphqls-Änderung sofortbin/cache-clean config- keinsetup:di:compilenötig, aber immer ein Cache-Clean. - Resolver bleiben dünn, DataProvider tragen die eigentliche Logik - aber nur, wenn die Logik das rechtfertigt (Kapitel 15).
- Bestehende Core-Typen mit
extend typeerweitern statt neue, isolierte Typen zu duplizieren. - Bestehende Core-Input-Typen (
FilterTypeInput,SortEnum) wiederverwenden statt eigene neu zu erfinden. - Non-Null (
!) nur für Felder, die fachlich wirklich nie fehlen können - Null-Bubbling reißt sonst ganze Antwortzweige mit. - DataProvider nutzen Repositories, nicht nackte Collections -
addFieldToFilter()immer in Array-Form['eq' => $value]. - Für Fehlerfälle immer eine der vier GraphQL-Exceptions werfen, nie eine generische Exception, die im Produktivmodus maskiert wird.
getExtensionAttributes()->getIsCustomer()statt einer reinengetUserId() > 0-Prüfung für echte Kundenerkennung.- Bei absehbar großen Listen mit eigenen Feld-Resolvern von Anfang an
BatchResolverInterfacestattResolverInterfacein Betracht ziehen. - Bei jedem Problem zuerst Cache-Clean, dann Introspection, dann Developer-Mode und
exception.logprüfen - erst danach den eigenen Code verdächtigen.
Tipp: Das komplette, in dieser Serie entwickelte Mironsoft\Event-Modul deckt jedes dieser Muster an einer einzigen, konsistenten API ab - bei Unklarheit zu einem einzelnen Muster lohnt sich der Rücksprung in das jeweilige Kapitel dieser Serie, statt das Muster isoliert neu nachzuschlagen.
Damit endet diese Serie. Von der ersten Frage "Was ist GraphQL überhaupt?" bis zu einer vollständigen, performanten, getesteten und abgesicherten Veranstaltungen-API - die hier gezeigten Muster tragen genauso für jedes andere eigene GraphQL-Projekt in Magento 2.