GraphQL Linting mit eslint-plugin-graphql und graphql-schema-linter
AI generated
{ }
type
GraphQL · Linting · ESLint · CI/CD
GraphQL Linting mit eslint-plugin-graphql
und graphql-schema-linter richtig kombinieren

Ungültige Felder, vertippte Argumente und veraltete Felder, die trotzdem weiterverwendet werden: All das lässt sich mit GraphQL Linting bereits im Editor abfangen, statt erst zur Laufzeit über einen kryptischen Serverfehler zu stolpern.

18 Min. Lesezeit eslint-plugin-graphql · graphql-schema-linter · Custom Rules Node.js · CI/CD · ESLint

1. Warum GraphQL-Linting mehr ist als Style-Checking

GraphQL Linting wird oft mit reinem Style-Checking verwechselt, dabei deckt gutes GraphQL Linting Fehlerklassen ab, die ohne Werkzeug erst zur Laufzeit auffallen: eine Query, die ein Feld anfragt, das im Schema gar nicht existiert, eine Mutation, die ein Pflicht-Argument vergisst, oder ein Client, der ein bereits mit @deprecated markiertes Feld weiter verwendet. Ohne GraphQL Linting bemerken Entwickler solche Fehler erst, wenn der GraphQL-Server zur Laufzeit einen Validierungsfehler zurückgibt, im schlechtesten Fall erst in Production.

Der Wert von GraphQL Linting entsteht durch Integration in den Entwicklungsworkflow: als IDE-Warnung während des Tippens, als Pre-Commit-Hook vor jedem Commit und als CI-Check vor jedem Merge. Jede dieser drei Ebenen fängt Fehler zu einem anderen Zeitpunkt ab, und je früher ein Fehler gefunden wird, desto günstiger ist die Korrektur. Die zwei etablierten Werkzeuge im GraphQL-Ökosystem, eslint-plugin-graphql für Client-Queries und graphql-schema-linter für die Schema-Definition selbst, decken zusammen beide Seiten ab.

2. Zwei Ebenen des GraphQL-Lintings: Schema vs. Operationen

GraphQL Linting lässt sich in zwei unabhängige Ebenen aufteilen, die häufig verwechselt werden. Die erste Ebene ist das Schema-Linting: Es prüft die SDL-Datei (Schema Definition Language) selbst auf Konsistenz, Naming Conventions, fehlende Beschreibungen und strukturelle Probleme wie zirkuläre Eingabetypen. graphql-schema-linter ist hier das Referenz-Tool und arbeitet unabhängig von einem laufenden Server direkt auf der .graphql- oder .graphqls-Datei.

Die zweite Ebene ist das Operations-Linting, also die Prüfung von Client-seitigen Queries, Mutations und Fragments gegen ein konkretes Schema. eslint-plugin-graphql übernimmt diese Aufgabe als ESLint-Plugin, das jede Query in .js-, .ts- oder .graphql-Dateien gegen die tatsächliche Schema-Definition validiert. Beide Ebenen ergänzen sich: Ein sauberes Schema allein verhindert keine fehlerhaften Client-Queries, und valide Client-Queries allein sagen nichts über die Qualität des Schemas aus.


# Install both layers of GraphQL linting
npm install --save-dev eslint eslint-plugin-graphql graphql
npm install --save-dev graphql-schema-linter

3. eslint-plugin-graphql einrichten und gegen ein Live-Schema validieren

eslint-plugin-graphql benötigt Zugriff auf ein Schema, entweder als Introspection-JSON-Export oder als SDL-Datei. In der ESLint-Konfiguration wird das Plugin aktiviert und der Schema-Pfad hinterlegt; anschließend prüft ESLint jede mit gql oder graphql markierte Template-Literal-Query gegen das Schema. Ein Aufruf wie products(fitler: {...}) mit vertipptem Argumentnamen wird sofort als Lint-Fehler markiert, lange bevor der Code überhaupt ausgeführt wird.

Wichtig ist, das Schema regelmäßig zu aktualisieren, sonst validiert eslint-plugin-graphql gegen einen veralteten Stand und übersieht neue Breaking Changes oder meldet False Positives für neu hinzugefügte Felder. Ein npm-Script, das die Introspection-Query gegen die Entwicklungsumgebung ausführt und das Ergebnis als schema.json im Repository ablegt, sollte Teil jedes Build- oder Pre-Commit-Schritts sein.


// .eslintrc.js
module.exports = {
  plugins: ['graphql'],
  rules: {
    'graphql/template-strings': ['error', {
      env: 'apollo',
      // Regenerate this file via a graphql-codegen introspection task
      schemaJson: require('./schema.json'),
      tagName: 'gql',
    }],
  },
};

4. Typische Fehler, die eslint-plugin-graphql zur Entwicklungszeit fängt

Die häufigste Fehlerklasse ist die Verwendung nicht existierender Felder, meist durch Tippfehler oder durch eine Query, die gegen ein älteres Schema geschrieben wurde. eslint-plugin-graphql markiert solche Felder mit einer präzisen Fehlermeldung, die den erwarteten Typ und die verfügbaren Felder auflistet, statt den generischen "Cannot query field"-Fehler, den der Server zur Laufzeit zurückgeben würde.

Eine zweite wichtige Fehlerklasse ist die Nutzung deprecated markierter Felder. Ohne GraphQL Linting bleibt eine solche Nutzung unsichtbar, bis das Feld tatsächlich entfernt wird und die Query bricht. Mit aktiviertem Deprecation-Check erscheint bereits im Editor eine Warnung, sobald ein Entwickler ein veraltetes Feld in eine neue Query übernimmt, häufig durch Copy-Paste aus einer bestehenden, aber ebenfalls veralteten Query.

5. graphql-schema-linter: eingebaute Regeln im Überblick

graphql-schema-linter liefert von Haus aus mehr als 30 Regeln, die sich grob in drei Kategorien einteilen lassen: Naming-Regeln (types-are-capitalized, fields-are-camel-cased, enum-values-all-caps), Dokumentations-Regeln (types-have-descriptions, fields-have-descriptions) und strukturelle Regeln (relay-connection-types-spec, input-object-values-are-camel-cased). Jede Regel lässt sich einzeln aktivieren oder deaktivieren, was bei der schrittweisen Einführung von GraphQL Linting in ein bestehendes Schema entscheidend ist.

Bei einem bereits produktiven Schema mit hunderten Feldern führt ein sofortiges Aktivieren aller Regeln zu einer Flut von Fehlermeldungen, die niemand mehr sinnvoll bearbeitet. Der pragmatische Weg ist, zunächst nur die kritischsten Regeln zu aktivieren, etwa types-are-capitalized und enum-values-all-caps, bestehende Verstöße gezielt zu ignorieren, und danach schrittweise weitere Regeln zu ergänzen.


{
  "schemaPaths": ["./schema.graphql"],
  "rules": [
    "types-are-capitalized",
    "fields-are-camel-cased",
    "enum-values-all-caps",
    "fields-have-descriptions",
    "types-have-descriptions"
  ],
  "ignoreExceptions": ["Product.legacy_sku"]
}

6. Eigene Lint-Regeln schreiben

Sowohl eslint-plugin-graphql als auch graphql-schema-linter erlauben eigene Regeln für projektspezifische Konventionen, die die eingebauten Regelsets nicht abdecken. Ein häufiger Fall: Boolean-Felder müssen mit is, has oder can beginnen. graphql-schema-linter bietet dafür eine Custom-Rule-API, die auf dem AST des Schemas operiert und über einen Visitor Knoten wie FieldDefinition prüft.

Eigene Regeln lohnen sich vor allem für Konventionen, die im eigenen Style Guide dokumentiert, aber ohne automatisierte Prüfung regelmäßig übersehen werden. Der Aufwand für eine einfache Custom-Rule liegt bei wenigen Dutzend Zeilen Code und zahlt sich schnell aus, sobald mehr als ein oder zwei Entwickler gleichzeitig am Schema arbeiten.


// rules/boolean-field-prefix.js
module.exports = function booleanFieldPrefix(context) {
  return {
    FieldDefinition(node) {
      const isBoolean = node.type.name && node.type.name.value === 'Boolean';
      const name = node.name.value;
      const hasPrefix = /^(is|has|can)[A-Z]/.test(name);
      if (isBoolean && !hasPrefix) {
        context.reportError(
          context.createError(
            `Boolean field "${name}" should start with is, has or can.`,
            [node]
          )
        );
      }
    },
  };
};

7. Linting in CI/CD integrieren

GraphQL Linting entfaltet den größten Nutzen erst, wenn es verbindlich in der CI-Pipeline läuft, statt optional in der lokalen Entwicklungsumgebung zu bleiben. Ein GitHub-Actions-Workflow, der bei jedem Pull Request sowohl ESLint mit dem graphql-Plugin als auch graphql-schema-linter ausführt, verhindert, dass fehlerhafte Queries oder Konventionsverstöße überhaupt in den main-Branch gelangen.

Für schnelles Feedback lohnt sich zusätzlich ein Pre-Commit-Hook über husky und lint-staged, der nur die geänderten Dateien prüft, statt bei jedem Commit das komplette Schema zu validieren. Das hält die Feedback-Schleife kurz, während die vollständige Prüfung in der CI-Pipeline weiterhin als Sicherheitsnetz für das gesamte Repository dient.


# .github/workflows/graphql-lint.yml
name: GraphQL Lint
on: [pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx eslint . --ext .js,.ts,.graphql
      - run: npx graphql-schema-linter schema.graphql

8. Monorepo und mehrere Schemas: Konfiguration skalieren

In Monorepos mit mehreren GraphQL-Services oder einem föderierten Schema wird eine einzelne globale Lint-Konfiguration schnell zum Nadelöhr. Sinnvoller ist eine Basis-Konfiguration im Root, die projektspezifische .graphql-schema-linterrc-Dateien in jedem Service-Verzeichnis erweitert, sodass gemeinsame Regeln zentral gepflegt werden, während einzelne Services zusätzliche, domänenspezifische Regeln ergänzen können.

Für eslint-plugin-graphql bedeutet das analog, pro Frontend-Paket ein eigenes Schema, oder den relevanten Ausschnitt eines föderierten Schemas, zu hinterlegen, damit Linting-Fehler auf das tatsächlich verwendete Sub-Schema referenzieren und nicht auf das gesamte föderierte Gateway-Schema, das für ein einzelnes Frontend-Team ohnehin nur teilweise relevant ist.

9. GraphQL-Linting-Tools im Vergleich

Die folgende Übersicht ordnet die gängigen Werkzeuge nach ihrer eigentlichen Aufgabe ein, damit die Wahl zwischen ihnen nicht zur Bauchentscheidung wird.

Tool Prüft Stärke Einschränkung
eslint-plugin-graphql Client-Queries gegen Schema Direkte IDE-Integration über ESLint Für Schema-SDL selbst ungeeignet
graphql-schema-linter Schema-SDL selbst Große Regelbibliothek, Custom Rules Keine Client-Query-Validierung
@graphql-eslint/eslint-plugin Schema UND Operationen Ein Werkzeug für beide Ebenen Größere Konfiguration, jüngeres Ökosystem
GraphQL Inspector Schema-Diffs zwischen Versionen Erkennt Breaking Changes zwischen Commits Kein klassisches Style-Linting

Für neue Projekte ist @graphql-eslint/eslint-plugin oft die pragmatischste Wahl, weil eine einzige Konfiguration beide Linting-Ebenen abdeckt. Für gewachsene Codebasen, die bereits mit eslint-plugin-graphql und graphql-schema-linter arbeiten, lohnt sich die Migration meist erst, wenn ohnehin ein größeres Tooling-Update ansteht.

Mironsoft

GraphQL-Tooling, CI-Pipelines und Schema-Qualitätssicherung

Fehlerhafte Queries schon im Editor abfangen?

Wir richten GraphQL Linting für Schema und Client-Queries ein, integrieren es in eure CI-Pipeline und schreiben projektspezifische Custom Rules für eure Naming Conventions.

Linting-Setup

eslint-plugin-graphql und graphql-schema-linter produktionsreif konfigurieren

Custom Rules

Projektspezifische Regeln für eure Naming Conventions entwickeln

CI-Integration

Pre-Commit-Hooks und GitHub Actions für schnelles, verlässliches Feedback

10. Zusammenfassung

GraphQL Linting lohnt sich, weil es Fehlerklassen früh abfängt, die sonst erst zur Laufzeit sichtbar werden: falsche Feldnamen, vergessene Pflicht-Argumente und weiterverwendete deprecated Felder. eslint-plugin-graphql übernimmt die Prüfung von Client-Queries gegen ein konkretes Schema, graphql-schema-linter prüft die Schema-Definition selbst auf Naming Conventions, Dokumentation und Struktur. Beide Werkzeuge ergänzen sich, weil sie unterschiedliche Ebenen des GraphQL-Stacks abdecken.

Der größte Effekt entsteht durch Integration in den Workflow: IDE-Warnung während des Tippens, Pre-Commit-Hook für schnelles lokales Feedback, CI-Check als verbindliches Sicherheitsnetz vor jedem Merge. Eigene Regeln über die Custom-Rule-APIs beider Tools schließen die Lücke zwischen dokumentiertem Style Guide und tatsächlich durchgesetzter Konvention.

GraphQL Linting — Das Wichtigste auf einen Blick

Zwei Ebenen

eslint-plugin-graphql für Client-Queries, graphql-schema-linter für die Schema-SDL. Beide ergänzen sich.

Custom Rules

Beide Tools bieten APIs für eigene, projektspezifische Regeln jenseits der eingebauten Regelsets.

CI-Integration

GitHub Actions bei jedem Pull Request, Pre-Commit-Hooks mit husky und lint-staged für schnelles Feedback.

Schrittweise Einführung

Bei bestehenden Schemas zunächst kritische Regeln aktivieren, Verstöße ignorieren oder beheben, dann erweitern.

11. FAQ: GraphQL Linting

1Was ist GraphQL Linting?
Automatisierte Prüfung von Schemas und Queries auf strukturelle Fehler und Konventionen, bereits während der Entwicklung.
2Unterschied eslint-plugin-graphql vs. graphql-schema-linter?
Ersteres prüft Client-Queries gegen ein Schema, letzteres prüft das Schema selbst. Beide ergänzen sich.
3Welches Schema-Format braucht eslint-plugin-graphql?
Introspection-JSON oder SDL-Datei, regelmäßig aktualisiert, damit Ergebnisse nicht veraltet sind.
4Wie werden deprecated Felder erkannt?
Über die @deprecated-Direktive im Schema, markiert im Editor als Warnung bei Nutzung in einer Query.
5Wie viele Regeln hat graphql-schema-linter?
Mehr als 30, unterteilt in Naming-, Dokumentations- und strukturelle Regeln, einzeln aktivierbar.
6Wie führe ich Linting in ein großes Schema ein?
Schrittweise mit den kritischsten Regeln beginnen, Verstöße gezielt beheben oder ignorieren, dann erweitern.
7Kann ich eigene Regeln schreiben?
Ja, beide Tools bieten Custom-Rule-APIs für projektspezifische Konventionen jenseits der eingebauten Regeln.
8Wie integriere ich Linting in CI?
Über einen Workflow bei jedem Pull Request plus Pre-Commit-Hooks für schnelles lokales Feedback.
9Wie skaliert Linting in einem Monorepo?
Über eine Basis-Konfiguration, die projektspezifische Konfigurationen pro Service erweitern, statt einer globalen Konfiguration.
10Lohnt sich @graphql-eslint/eslint-plugin?
Für neue Projekte oft ja. Für gewachsene Setups lohnt sich die Migration meist erst bei einem größeren Tooling-Update.