Zum Inhalt springen
Blume
Esc
↑↓navigieren↵öffnen⌘Jvorschau
Auf dieser Seite

GraphQL

Binde ein GraphQL-Schema ein und erhalte eine native API-Referenz – eine echte Seite pro Operation und pro Typ, in deiner Sidebar und in der Suche.

Richte Blume auf ein GraphQL-Schema, und es generiert eine native API-Referenz: eine echte Seite pro Root-Feld – Queries, Mutations und Subscriptions – plus eine Seite pro benanntem Typ (Objekte, Input-Objekte, Enums, Interfaces, Unions und Custom Scalars). Jede Seite zeigt Argumente, Standardwerte, Deprecations und Verwendungs-Backlinks, dazu eine generierte Beispiel-Operation, Code-Beispiele und ein interaktives Try it-Panel. Da jede Seite eine echte Blume-Seite ist, bekommt sie ihre eigene URL, taucht in der Seitensuche und in llms.txt auf und erhält ein Open-Graph-Bild – genau wie jede von Hand geschriebene Doku-Seite.

Die Referenz ist der graphql()-Adapter aus blume/reference. Du trägst ihn unter reference ein, neben beliebigen OpenAPI- oder AsyncAPI-Adaptern:

import { defineConfig } from "blume";
import { graphql } from "blume/reference";

export default defineConfig({
  reference: [
    graphql({
      spec: "./schema.graphql",
      endpoint: "https://api.example.com/graphql",
    }),
  ],
});

Damit wird die Referenz unter /graphql eingebunden (eine Übersichtsseite). Root-Felder liegen unter /graphql/queries/<field>, /graphql/mutations/<field> und /graphql/subscriptions/<field>, Typen nach Art gruppiert unter /graphql/objects/<type>, /graphql/enums/<type> und so weiter.

Die spec ist entweder ein Pfad zu einer lokalen Datei in deinem Projekt oder eine http(s)-URL und akzeptiert zwei Formate:

  • SDL-Text – eine .graphql-Datei mit Typdefinitionen. Direktiven, die die Datei verwendet, aber nicht deklariert, etwa @key aus Apollo Federation oder @aws_* aus AppSync, werden ignoriert.
  • Ein Introspection-Ergebnis – das JSON, das die Standard-Introspection-Query liefert, entweder in der rohen Form { "__schema": … } oder als vollständiger Response-Envelope { "data": { "__schema": … } }.

Der endpoint ist die URL der Live-GraphQL-API. Anders als ein OpenAPI-Dokument nennt ein Schema keinen Server – deshalb ist der Endpoint das Ziel für das Try-it-Panel und die generierten Code-Beispiele. Lässt du ihn weg, werden die Beispiele mit einer Platzhalter-URL gerendert, die deine Leser selbst ersetzen.

Die Referenz fügt von sich aus keinen Header-Tab hinzu. Damit sie sichtbar wird, richte einen Navigations-Tab auf ihre Route – dadurch wird auch die Sidebar der Referenz auf diesen Tab beschränkt:

navigation: {
  tabs: [{ label: "GraphQL", path: "/graphql" }],
}

GraphQL-Doku aus deinem Schema generieren führt dich Schritt für Schritt vom Schema bis zur deployten Seite – inklusive eines Try-it-Panels, das eine Sandbox abfragt.

Generierte Beispiele

Jede Operationsseite enthält eine vollständige, gültige Beispiel-Operation – eine Variable pro Argument, typisiert anhand des Schemas, mit einem Selection Set begrenzter Tiefe über den Rückgabetyp. Dazu kommen passende Beispielvariablen und eine Beispielantwort, die dieselbe Selection widerspiegelt. Deklariert ein Argument einen Standardwert, beginnt die zugehörige Variable mit diesem Wert, und als deprecated markierte Felder lässt die Selection weg. Die Code-Beispiele zeigen den exakten HTTP-Request (ein JSON-POST von { query, variables }) in jeder konfigurierten Sprache. Dir stehen dieselben Sprachen wie bei openapi() zur Verfügung, und mit codeSamples: false werden keine angezeigt:

reference: [
  graphql({
    spec: "./schema.graphql",
    codeSamples: ["curl", "js"],   // any language openapi() offers
  }),
],

Eine ID, für die Blume kein Beispiel generiert, wird weggelassen. Du bekommst dann eine BLUME_GRAPHQL_UNKNOWN_CODE_SAMPLE-Warnung, die alle unterstützten IDs auflistet.

Typseiten

Benannte Typen bekommen eigene Seiten, auf die du direkt verlinken kannst, in der Sidebar nach Art gruppiert. Sie zeigen Felder und Input-Felder mit verlinkten Typen, Enum-Werte, Union-Mitglieder und Interface-Implementierungen. Dazu kommt ein Abschnitt Verwendet von mit den Operationen, die den Typ zurückgeben oder akzeptieren, und den anderen Typen, die auf ihn verweisen. In der Spezifikation definierte Scalars (String, Int, …) bekommen keine eigenen Seiten. Custom Scalars schon, inklusive ihrer specifiedBy-URL.

Mehrere Schemas

Jeder Eintrag in sources rendert ein Schema auf einer eigenen Route. Ein endpoint pro Quelle überschreibt den des Adapters:

reference: [
  graphql({
    endpoint: "https://api.example.com/graphql",
    sources: [
      { label: "Public API", spec: "./schema.graphql" },
      {
        label: "Admin API",
        route: "/graphql-admin",
        spec: "./admin.graphql",
        endpoint: "https://admin.example.com/graphql",
      },
    ],
  }),
],

spec ist die Kurzform für sources mit einem einzigen Eintrag. Schemas, die unterschiedliche Darstellungsoptionen brauchen, gehören in separate graphql()-Adapter, jeweils mit eigener route. Jede Quelle unterstützt dieselben Einstellungen pro Quelle wie openapi(): includeInSearch, includeInLlms, noindex und seoDescriptionSuffix. Hier nennt der generierte Satz die Query, die Mutation oder den Typ, zum Beispiel „Reference for the pets query in the GraphQL API.“

Try-it-Playground

Query- und Mutation-Seiten zeigen ein interaktives Panel. Dort bearbeitest du den Request-Body (die Query und die Variablen), richtest ihn auf deinen Endpoint oder eine eigene URL und schickst ihn ab. Die Code-Beispiele aktualisieren sich dabei live, sodass das, was du kopierst, Byte für Byte dem gesendeten Request entspricht. Mit playground: false schaltest du das Panel ab. Subscription-Seiten zeigen stattdessen die generierte Operation und ein Beispiel-Event. Subscriptions laufen nämlich über einen zustandsbehafteten Transport (WebSocket oder SSE), und den unterstützt der einzelne HTTP-POST des Playgrounds nicht.

Ein Schema verrät nicht, wie sich seine API authentifiziert. Deshalb sendet das Panel keine Zugangsdaten, bis du sie mit auth festlegst. Die Option hat dieselbe Form wie api.auth für von Hand geschriebene Endpoint-Seiten: method ist bearer, basic, key (ein API-Key in einem Header) oder none, und name ist der Header, in dem der API-Key mitgeschickt wird (standardmäßig x-api-key). Jede Operationsseite bekommt dann einen Abschnitt Autorisierung, das Panel ein Feld für Zugangsdaten, das genauso funktioniert wie das bei OpenAPI, und die Code-Beispiele Platzhalter-Zugangsdaten. Ein auth pro Quelle überschreibt das des Adapters:

reference: [
  graphql({
    spec: "./schema.graphql",
    endpoint: "https://api.example.com/graphql",
    auth: { method: "bearer" },
  }),
],

Wenn deine GraphQL-API keine Cross-Origin-Requests von der Doku-Seite erlaubt, leite die Requests über einen CORS-Proxy. Das kann eine eigene URL sein oder true für den integrierten /_api-proxy-Endpoint (unter deinem basePath, falls du einen gesetzt hast). Der integrierte Endpoint braucht Server-Output, also einen Host-Adapter wie deployment: vercel() aus blume/deploy. Der integrierte Proxy leitet nur an Origins weiter, die in deinen dokumentierten Specs stehen: jeden konfigurierten GraphQL-endpoint und jede absolute servers[].url aus einer dokumentierten OpenAPI-Spec. So kann niemand ein öffentliches Doku-Deployment auf andere Hosts richten. Deshalb braucht ein funktionierender Proxy einen endpoint. Ohne ihn hat der Proxy für diese Referenz keinen erlaubten Origin und lehnt jeden Request ab (der Build warnt dich davor). Es gelten dasselbe Body-Limit, dieselbe Header-Weiterleitung und dieselben Response-Header wie beim OpenAPI-Proxy.

reference: [
  graphql({
    spec: "./schema.graphql",
    endpoint: "https://api.example.com/graphql",
    playground: { proxy: true },
  }),
],

Für GraphQL gibt es kein Scalar-Pendant: Das scalar()-Embed liest nur OpenAPI- und AsyncAPI-Dokumente. Eine GraphQL-Referenz wird deshalb immer nativ gerendert.

Zuletzt aktualisiert am

War diese Seite hilfreich?