GraphQL Naming Conventions: die sich in Teams durchsetzen
AI generated
{ }
type
GraphQL · Schema Design · Governance · Style Guide
GraphQL Naming Conventions
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.

17 Min. Lesezeit PascalCase · camelCase · Input/Payload · Deprecation GraphQL · alle Server-Implementierungen

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.

11. FAQ: GraphQL Naming Conventions

1Was sind GraphQL Naming Conventions?
Verbindliche Regeln für die Benennung von Typen, Feldern, Queries, Mutations und Enum-Werten, damit ein Schema unabhängig vom Team konsistent bleibt.
2Warum PascalCase für Typen, camelCase für Felder?
Weil sich diese Kombination in praktisch allen produktiven Schemas durchgesetzt hat und sofortige Vertrautheit für neue Entwickler schafft.
3Brauchen Mutations immer ein Verb?
Ja, weil eine Mutation immer eine Aktion beschreibt. create, update oder delete am Anfang machen die Wirkung sofort erkennbar.
4Was ist das Input/Payload-Pattern?
Ein Input-Objekt als Mutation-Argument, ein Payload-Objekt als Rückgabe mit Daten und Fehlern. Erlaubt Erweiterungen ohne Breaking Change.
5Wie vermeide ich Namenskollisionen in großen Schemas?
Über Interfaces und dedizierte Root-Felder pro Domäne statt künstlicher Präfixe in jedem Typnamen.
6Wie benenne ich ein Feld um, ohne Clients zu brechen?
Neues Feld parallel einführen, altes mit @deprecated markieren, Nutzung beobachten, erst nach vollständiger Migration entfernen.
7Wo pflege ich einen GraphQL-Style-Guide?
Im selben Repository wie das Schema, am besten als kommentierte Beispiel-Datei, die bei Schema-Änderungen mit aktualisiert wird.
8Wie erzwinge ich Naming automatisiert?
Mit graphql-schema-linter als CI-Check, der Pull Requests bei Regelverstößen automatisch fehlschlagen lässt.
9Wie sollten Enum-Werte benannt werden?
In SCREAMING_SNAKE_CASE, zum Beispiel ORDER_STATUS_PENDING, klar unterscheidbar von Feld- und Typnamen.
10Gibt es eine offizielle Spezifikation dafür?
Nein, die GraphQL-Spezifikation schreibt nichts vor. Die Regeln sind De-facto-Standard aus den großen öffentlichen Schemas und graphql.org.