die sich in Teams tatsächlich durchsetzen
Ein Schema mit drei verschiedenen Stilen für dieselbe Sache kostet jedes Team Zeit, Nerven und Vertrauen in die API. Klare GraphQL Naming Conventions für Typen, Felder, Mutations und Enums machen ein Schema selbsterklärend und lassen sich mit Style Guide und Linting dauerhaft im Team verankern.
Inhaltsverzeichnis
- 1. Warum Naming Conventions in GraphQL-Teams überhaupt entscheiden
- 2. Typen, Felder und Enums: die drei Grundregeln
- 3. Queries, Mutations und Subscriptions richtig benennen
- 4. Input Types und Payload Types konsistent strukturieren
- 5. Pluralisierung, Präfixe und Namespacing in großen Schemas
- 6. Naming und Deprecation: Felder umbenennen ohne Breaking Change
- 7. Naming Conventions dokumentieren: Style Guide statt Tribal Knowledge
- 8. Naming automatisiert prüfen statt im Review diskutieren
- 9. GraphQL Naming Conventions im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum Naming Conventions in GraphQL-Teams überhaupt entscheiden
In GraphQL-Projekten mit mehreren Teams wird schnell sichtbar, wie stark uneinheitliche Benennung die Produktivität bremst. Wenn ein Team getUser, ein anderes fetchCustomer und ein drittes userById als Query-Namen verwendet, verlieren Entwickler Zeit beim Suchen der richtigen Query in der Autocomplete-Liste des GraphiQL-Explorers. GraphQL Naming Conventions lösen genau dieses Problem, indem sie für jede Kategorie von Schema-Element, also Typ, Feld, Mutation und Enum, eine verbindliche Regel festlegen, die im gesamten Schema gilt, unabhängig davon, welches Team den jeweiligen Resolver implementiert hat.
Der Effekt reicht über reine Ästhetik hinaus. Ein Schema mit klaren GraphQL Naming Conventions ist selbsterklärend, reduziert den Dokumentationsaufwand und macht automatisch generierte Client-Typen, etwa über GraphQL Code Generator, lesbarer, weil Typnamen und Methodennamen im generierten Code denselben konsistenten Regeln folgen wie im Schema selbst. Wer früh in einem Projekt Naming Conventions festlegt, spart sich später aufwendige Refactorings, bei denen Feldnamen wegen Uneinheitlichkeit als deprecated markiert und durch neue Varianten ersetzt werden müssen.
2. Typen, Felder und Enums: die drei Grundregeln
Die GraphQL-Spezifikation selbst schreibt keine Namenskonvention vor, aber die überwiegende Mehrheit produktiver Schemas folgt derselben Konvention: Typnamen in PascalCase (Product, CustomerAddress), Feld- und Argumentnamen in camelCase (firstName, isActive) und Enum-Werte in SCREAMING_SNAKE_CASE (ORDER_STATUS_PENDING). Diese drei Regeln bilden das Fundament jeder GraphQL Naming Convention und sollten als Erstes in jedem Style Guide stehen, weil sie sich auch in den offiziellen graphql.org-Beispielen und in praktisch allen großen öffentlichen Schemas wiederfinden.
Abweichungen von diesen Grundregeln entstehen meistens, wenn ein Team ein bestehendes REST-API eins zu eins in ein GraphQL-Schema übersetzt und dabei Snake-Case-Feldnamen aus der Datenbank unverändert übernimmt. first_name statt firstName mag im Resolver bequemer wirken, bricht aber mit der Erwartungshaltung jedes GraphQL-Clients und wirkt in einer gemischten Codebasis wie ein Fremdkörper. Die Übersetzung zwischen Datenbank-Snake-Case und GraphQL-camelCase gehört konsequent in den Resolver, niemals ins Schema selbst.
# WRONG: inconsistent casing mixed with raw database naming
type product {
id: ID
product_name: String
IN_STOCK: Boolean
}
# RIGHT: PascalCase type, camelCase fields, no db leakage
type Product {
id: ID!
name: String!
inStock: Boolean!
}
enum OrderStatus {
PENDING
SHIPPED
DELIVERED
CANCELLED
}
3. Queries, Mutations und Subscriptions richtig benennen
Bei Query-Namen hat sich in der Praxis ein nomenbasiertes Muster durchgesetzt: product(id: ID!): Product für ein einzelnes Objekt, products(filter: ProductFilter): ProductConnection für eine Liste. Verben wie getProduct oder fetchProducts sind redundant, weil eine Query per Definition immer ein Lesezugriff ist. Diese GraphQL Naming Convention hält Query-Namen kurz und lässt sie wie eine natürliche Objektbeschreibung lesen, was besonders bei generiertem Client-Code, etwa React-Hooks über GraphQL Code Generator, zu sprechenden Funktionsnamen wie useProductQuery führt.
Bei Mutations gilt die entgegengesetzte Regel: Ein Verb ist Pflicht, weil eine Mutation immer eine Aktion beschreibt. createProduct, updateProductPrice, deleteProduct statt product oder productUpdate. Die Reihenfolge Verb-Objekt-Detail verbessert außerdem die Sortierung in der Autocomplete-Liste, weil verwandte Mutations zum selben Objekt alphabetisch beieinander bleiben, sobald man konsequent mit dem Verb beginnt. Subscriptions folgen demselben Verb-Prinzip, meist als Past-Participle-Suffix: productPriceUpdated, orderStatusChanged.
type Query {
product(id: ID!): Product
products(filter: ProductFilter, first: Int): ProductConnection!
}
type Mutation {
createProduct(input: CreateProductInput!): CreateProductPayload!
updateProductPrice(input: UpdateProductPriceInput!): UpdateProductPricePayload!
deleteProduct(id: ID!): DeleteProductPayload!
}
type Subscription {
productPriceUpdated(productId: ID!): Product!
}
4. Input Types und Payload Types konsistent strukturieren
Für Mutation-Argumente hat sich das Input-Type-Pattern etabliert: Statt einzelner Skalar-Argumente nimmt eine Mutation ein einziges Input-Objekt entgegen, dessen Typname sich aus dem Mutation-Namen plus dem Suffix Input ableitet. createProduct(input: CreateProductInput!): CreateProductPayload macht sofort sichtbar, welches Input zu welcher Mutation gehört, und erlaubt es, neue optionale Felder ohne Änderung der Mutation-Signatur zu ergänzen. Diese Naming Convention für Input Types reduziert außerdem die Anzahl der Breaking Changes, weil neue Pflichtfelder im Input Type isoliert bleiben.
Für Rückgabewerte von Mutations gilt spiegelbildlich das Payload-Pattern: Statt direkt den geänderten Product-Typ zurückzugeben, liefert die Mutation einen CreateProductPayload-Typ, der das eigentliche Objekt, mögliche Validierungsfehler und Metadaten bündelt. Das Payload-Pattern macht Schemas erweiterbar, ohne bestehende Clients zu brechen, weil neue Felder im Payload einfach ergänzt werden, statt den Rückgabetyp der Mutation komplett zu ändern.
input CreateProductInput {
name: String!
price: Float!
categoryId: ID
}
type CreateProductPayload {
product: Product
errors: [UserError!]!
}
type UserError {
field: String!
message: String!
}
5. Pluralisierung, Präfixe und Namespacing in großen Schemas
Sobald ein Schema mehrere Domänen abbildet, etwa Katalog, Checkout und Kundenkonto, wird Namespacing zum Problem: Soll die Query für Bestellungen orders heißen oder checkoutOrders, um Kollisionen mit einem künftigen orders-Feld aus einem anderen Kontext zu vermeiden? Die gängige GraphQL Naming Convention rät davon ab, künstliche Präfixe wie ecom_orders in jeden Typnamen zu packen. Stattdessen übernehmen Interfaces und dedizierte Root-Felder pro Domäne die Trennung, während die Typnamen selbst so generisch wie möglich bleiben.
Pluralisierung folgt einer einfachen Regel: Felder, die eine Liste zurückgeben, tragen den pluralisierten Namen (products, orders), Felder, die ein einzelnes Objekt liefern, den Singular (product(id: ID!)). Unregelmäßige Pluralformen wie category/categories werden in größeren Teams am besten in einer zentralen Namensliste dokumentiert, weil automatisierte Codegenerierung sonst falsche Pluralformen für neue Typen vorschlägt und Inkonsistenzen entstehen, sobald mehrere Entwickler unabhängig voneinander neue Felder ergänzen.
6. Naming und Deprecation: Felder umbenennen ohne Breaking Change
Ein Feld einfach umzubenennen ist in GraphQL ein Breaking Change, weil bestehende Clients weiterhin den alten Feldnamen anfragen. Die etablierte GraphQL Naming Convention für Umbenennungen läuft über das @deprecated-Directive: Das neue Feld wird parallel zum alten eingeführt, das alte erhält @deprecated(reason: "..."), und erst nachdem alle Clients migriert sind und die Nutzung über Monitoring auf null gefallen ist, wird das alte Feld entfernt. Dieser Prozess kann je nach Anzahl der Client-Teams Wochen bis Monate dauern.
Wer von Anfang an konsistente Naming Conventions durchsetzt, reduziert die Häufigkeit solcher Migrationen drastisch, weil die häufigste Ursache für nachträgliche Umbenennungen genau die anfängliche Inkonsistenz ist. Ein Feld, das beim ersten Entwurf isActive statt active heißt, weil ein anderes Teammitglied is-Präfixe für Booleans bevorzugt, erzeugt später genau die Art von Deprecation-Zyklus, die durch einen im Vorfeld abgestimmten Style Guide vermeidbar gewesen wäre.
type Product {
active: Boolean! @deprecated(reason: "Use isActive instead. Removed in v3.")
isActive: Boolean!
}
7. Naming Conventions dokumentieren: Style Guide statt Tribal Knowledge
Naming Conventions, die nur im Kopf eines einzelnen Senior-Entwicklers existieren, verwässern mit jedem neuen Teammitglied. Ein schriftlicher GraphQL-Style-Guide, der die Regeln aus den vorherigen Abschnitten mit konkreten Beispielen aus dem eigenen Schema dokumentiert, ist die Grundlage für konsistente GraphQL Naming Conventions über die Lebensdauer eines Projekts hinweg. Der Style Guide sollte im selben Repository wie das Schema liegen, damit er bei Schema-Änderungen im selben Pull Request mitgepflegt werden kann.
Effektiver als reiner Fließtext ist eine kommentierte Beispiel-Schema-Datei, die als lebendes Beispiel dient: ein minimales Schema mit Typ, Query, Mutation, Input und Enum, jeweils mit Kommentar, warum genau dieser Name gewählt wurde. Neue Teammitglieder lesen diese Datei in wenigen Minuten und übernehmen die Naming Convention intuitiv, statt sie aus verstreuten Slack-Nachrichten oder alten Pull-Request-Kommentaren rekonstruieren zu müssen.
8. Naming automatisiert prüfen statt im Review diskutieren
Manuelle Code Reviews sind der langsamste und unzuverlässigste Weg, Naming Conventions durchzusetzen, weil Reviewer Abweichungen übersehen oder aus Zeitdruck durchwinken. Tools wie graphql-schema-linter erlauben es, Naming-Regeln als CI-Check zu formulieren: Enum-Werte müssen SCREAMING_SNAKE_CASE folgen, Typnamen dürfen keine Unterstriche enthalten, Felder mit Boolean-Rückgabe müssen mit is, has oder can beginnen. Ein Pull Request, der gegen eine dieser Regeln verstößt, schlägt automatisch fehl, bevor ein menschlicher Reviewer überhaupt involviert werden muss.
Die Kombination aus dokumentiertem Style Guide und automatisierter Prüfung ist der zuverlässigste Weg, GraphQL Naming Conventions in wachsenden Teams durchzusetzen: Der Style Guide erklärt das Warum, der Linter erzwingt das Was. Details zur konkreten Linter-Konfiguration, inklusive eslint-plugin-graphql für Client-seitige Queries, behandelt der separate Artikel zu GraphQL-Linting in dieser Serie.
{
"schemaPaths": ["./schema.graphql"],
"rules": [
"enum-values-sorted-alphabetically",
"enum-values-all-caps",
"types-are-capitalized",
"fields-are-camel-cased",
"fields-have-descriptions"
],
"customRules": ["./rules/boolean-field-prefix.js"]
}
9. GraphQL Naming Conventions im Vergleich
Die folgende Übersicht fasst die wichtigsten Entscheidungen zusammen, die in fast jedem Schema-Review wieder auftauchen und mit einer klaren GraphQL Naming Convention in Sekunden statt in einer langen Diskussion entschieden werden können.
| Element | Unsicher / inkonsistent | Empfohlene Naming Convention | Begründung |
|---|---|---|---|
| Typname | product |
Product |
PascalCase ist Schema-Standard |
| Feldname | first_name |
firstName |
camelCase, keine DB-Leakage |
| Query | getProduct(id) |
product(id) |
Verb ist bei Queries redundant |
| Mutation | product(input) |
createProduct(input) |
Verb ist bei Mutations Pflicht |
| Enum-Wert | pending |
PENDING |
SCREAMING_SNAKE_CASE Standard |
Alle fünf Regeln lassen sich in graphql-schema-linter als CI-Check hinterlegen, sodass die Tabelle nicht nur als Dokumentation dient, sondern direkt in eine automatisierte Prüfung überführt werden kann, die jeden Pull Request gegen dieselben Kriterien bewertet.
Mironsoft
GraphQL-Schema-Design, API-Governance und Magento-GraphQL-Beratung
Ein Schema, das jedes Team auf Anhieb versteht?
Wir richten GraphQL-Style-Guides ein, konfigurieren Naming-Linting in eurer CI-Pipeline und begleiten Migrationen bestehender Schemas auf konsistente Naming Conventions, ohne bestehende Clients zu brechen.
Style-Guide-Workshop
Gemeinsam mit eurem Team Naming-Regeln erarbeiten und dokumentieren
Linting-Setup
graphql-schema-linter und eslint-plugin-graphql in CI integrieren
Schema-Migration
Bestehende Felder deprecaten und schrittweise auf saubere Namen umstellen
10. Zusammenfassung
Konsistente GraphQL Naming Conventions lösen ein Problem, das sich in wachsenden Teams sonst immer wieder neu stellt: Typen in PascalCase, Felder in camelCase, Enum-Werte in SCREAMING_SNAKE_CASE, Queries als Nomen und Mutations als Verb bilden das Grundgerüst. Das Input/Payload-Pattern macht Mutations erweiterbar, ohne bestehende Clients zu brechen, und das @deprecated-Directive erlaubt kontrollierte Umbenennungen statt harter Breaking Changes.
Der entscheidende Hebel liegt nicht in der einzelnen Regel, sondern in der Durchsetzung: Ein dokumentierter Style Guide erklärt das Warum, automatisiertes Linting mit graphql-schema-linter erzwingt das Was in jedem Pull Request. Teams, die beides kombinieren, verbringen in Reviews spürbar weniger Zeit mit Namensdiskussionen und mehr Zeit mit tatsächlicher Schema-Architektur.
GraphQL Naming Conventions — Das Wichtigste auf einen Blick
Grundregeln
PascalCase für Typen, camelCase für Felder, SCREAMING_SNAKE_CASE für Enum-Werte. Die Basis jeder GraphQL Naming Convention.
Operationen
Queries als Nomen ohne Verb, Mutations mit Pflicht-Verb, Input/Payload-Pattern für erweiterbare Mutations.
Deprecation
Felder nie direkt umbenennen. Neues Feld parallel einführen, altes mit @deprecated markieren, erst nach Migration entfernen.
Governance
Style Guide im Schema-Repository pflegen, Regeln mit graphql-schema-linter automatisiert in der CI-Pipeline erzwingen.