Zwei populäre Node.js-Server, zwei unterschiedliche Philosophien
GraphQL Yoga setzt auf einen schlanken Kern, Standards-Konformität und ein Plugin-System namens envelop. Apollo Server bringt ein gewachsenes Ökosystem mit Studio-Integration, Federation-Support und jahrelanger Produktionserfahrung mit. Welcher Server sich lohnt, hängt von Teamgröße, Bestandssystem und gewünschtem Funktionsumfang ab.
Inhaltsverzeichnis
- 1. Die Node.js-GraphQL-Server-Landschaft und warum die Wahl Folgen hat
- 2. GraphQL Yoga: envelop-Plugin-System und Standards-Konformität
- 3. Apollo Server: Ökosystem, Plugins und Studio-Integration
- 4. Performance und Bundle-Größe im Vergleich
- 5. Federation-Support: Apollo Server und Yoga im Supergraph-Kontext
- 6. Plugin-Ökosystem: envelop-Plugins vs. Apollo-Server-Plugins
- 7. Developer Experience: GraphiQL, Fehlerbehandlung und Landing Page
- 8. Migrationsaufwand zwischen GraphQL Yoga und Apollo Server
- 9. Entscheidungshilfe: welcher Server passt zu welchem Projekttyp
- 10. Zusammenfassung
- 11. FAQ
1. Die Node.js-GraphQL-Server-Landschaft und warum die Wahl Folgen hat
Wer heute einen GraphQL-Server in Node.js aufsetzt, wählt damit nicht nur eine Bibliothek, sondern eine ganze Betriebsphilosophie: Wie Plugins eingebunden werden, wie Fehler behandelt werden, wie eng die Anbindung an einen bestimmten Anbieter ausfällt, und wie leicht sich der Server später gegen ein anderes Framework wie Fastify oder Next.js austauschen lässt. GraphQL Yoga und Apollo Server sind die beiden mit Abstand am weitesten verbreiteten Optionen im Node.js-Ökosystem, verfolgen dabei aber unterschiedliche Prioritäten.
GraphQL Yoga, entwickelt vom The Guild-Team, das auch hinter GraphQL Mesh und envelop steht, versteht sich als schlanker, spezifikationstreuer Kern, der bewusst auf ein minimales Grundgerüst setzt und Funktionalität ausschließlich über Plugins nachrüstet. Apollo Server verfolgt den entgegengesetzten Weg: ein integriertes Gesamtpaket mit eingebauter Federation-Unterstützung, Tracing und einer engen, aber optionalen Anbindung an die kommerzielle Apollo-Studio-Plattform.
2. GraphQL Yoga: envelop-Plugin-System und Standards-Konformität
Der Kern von GraphQL Yoga ist bewusst klein gehalten und implementiert strikt die GraphQL-over-HTTP-Spezifikation, inklusive korrekter Content-Negotiation, Server-Sent Events für Subscriptions und WHATWG-Fetch-kompatibler Request- und Response-Objekte. Dadurch läuft derselbe Yoga-Server nahezu unverändert auf Node.js, Deno, Bun, Cloudflare Workers oder Vercel Edge Functions, weil er keine Node-spezifischen APIs voraussetzt.
Zusätzliche Funktionalität wie Caching, Rate-Limiting, Persisted Queries oder Response-Validierung wird nicht im Kern eingebaut, sondern über das envelop-Plugin-System nachgerüstet, das jeden Schritt der Ausführung, vom Parsing über die Validierung bis zur Execution, als austauschbaren Hook offenlegt. Das hält den Kern testbar und klein, verlangt aber, dass Teams die passenden envelop-Plugins bewusst zusammenstellen, statt sie vorkonfiguriert zu bekommen.
import { createYoga, createSchema } from 'graphql-yoga'
import { useResponseCache } from '@envelop/response-cache'
import { createServer } from 'node:http'
const yoga = createYoga({
schema: createSchema({
typeDefs: /* GraphQL */ `
type Query {
products: [Product!]!
}
type Product {
id: ID!
name: String!
}
`,
resolvers: {
Query: {
products: () => productRepository.findAll(),
},
},
}),
plugins: [
useResponseCache({ session: () => null, ttl: 5_000 }),
],
})
createServer(yoga).listen(4000)
3. Apollo Server: Ökosystem, Plugins und Studio-Integration
Apollo Server bringt von Haus aus ein Plugin-System mit, das an den Lebenszyklus einer Anfrage andockt, requestDidStart, willSendResponse und ähnliche Hooks, und darüber unter anderem Tracing-Daten direkt an Apollo Studio senden kann, ohne zusätzliche Konfiguration. Dieses eingebaute Observability-Angebot ist einer der Hauptgründe, warum viele Teams bei Apollo Server bleiben, sobald sie einmal mit Apollo Studio für Schema-Checks und Performance-Metriken arbeiten.
Das Framework selbst ist stark auf das Apollo-Ökosystem ausgerichtet: Apollo Client, Apollo Router für Federation und Apollo GraphOS als verwaltete Plattform greifen nahtlos ineinander, was Reibungsverluste reduziert, wenn ein Team ohnehin den gesamten Apollo-Stack einsetzen will. Wer dagegen bewusst herstellerunabhängig bleiben möchte, empfindet diese enge Verzahnung eher als zusätzliche Kopplung.
import { ApolloServer } from '@apollo/server'
import { startStandaloneServer } from '@apollo/server/standalone'
const typeDefs = `#graphql
type Query {
products: [Product!]!
}
type Product {
id: ID!
name: String!
}
`
const resolvers = {
Query: {
products: () => productRepository.findAll(),
},
}
const server = new ApolloServer({ typeDefs, resolvers })
const { url } = await startStandaloneServer(server, {
context: async ({ req }) => ({ token: req.headers.authorization }),
listen: { port: 4000 },
})
console.log(`Server ready at ${url}`)
4. Performance und Bundle-Größe im Vergleich
In eigenen und unabhängigen Benchmarks liegt GraphQL Yoga bei einfachen Anfragen meist knapp vorn, was vor allem am schlankeren Kern und dem Verzicht auf standardmäßig aktivierte Tracing-Instrumentierung liegt. Apollo Server aktiviert je nach Version standardmäßig mehr eingebaute Middleware, etwa für Landing-Page-Rendering oder Usage-Reporting, was sich unter sehr hoher Last leicht in der Latenz bemerkbar macht, sofern diese Funktionen nicht bewusst deaktiviert werden.
Für die allermeisten Projekte ist der Unterschied im einstelligen Millisekundenbereich pro Anfrage praktisch irrelevant, verglichen mit der Latenz, die Datenbankzugriffe oder externe Services ohnehin verursachen. Relevanter als reine Rohperformance ist meist die Bundle-Größe beim Deployment auf Edge-Plattformen, wo Yogas kleinerer Kern echte Vorteile bei Cold-Start-Zeiten bringt.
5. Federation-Support: Apollo Server und Yoga im Supergraph-Kontext
Apollo Server unterstützt Federation nativ über @apollo/subgraph und lässt sich ohne Umwege als Subgraph hinter einem Apollo Router betreiben, inklusive automatischer Entity-Resolution und Schema-Validierung gegen die Federation-Spezifikation. Das macht Apollo Server zur naheliegenden Wahl, sobald ein Team ohnehin eine verteilte, föderierte Architektur mit Apollo-Werkzeugen aufbaut.
GraphQL Yoga kann ebenfalls als Federation-Subgraph arbeiten, benötigt dafür aber das zusätzliche Paket @graphql-tools/federation oder die Kombination mit GraphQL Mesh, was einen zusätzlichen Konfigurationsschritt bedeutet, aber keine Einschränkung in der eigentlichen Funktionalität. In gemischten Umgebungen lassen sich Yoga- und Apollo-Subgraphs sogar problemlos hinter demselben Federation-Router kombinieren, weil die Spezifikation serverunabhängig ist.
import { createYoga } from 'graphql-yoga'
import { buildSubgraphSchema } from '@graphql-tools/federation'
import { parse } from 'graphql'
const typeDefs = parse(/* GraphQL */ `
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.3",
import: ["@key"])
type Product @key(fields: "id") {
id: ID!
name: String!
}
`)
const schema = buildSubgraphSchema({ typeDefs, resolvers: {
Product: {
__resolveReference: (ref) => productRepository.findById(ref.id),
},
}})
const yoga = createYoga({ schema })
6. Plugin-Ökosystem: envelop-Plugins vs. Apollo-Server-Plugins
Das envelop-Ökosystem rund um GraphQL Yoga bietet inzwischen weit über fünfzig fertige Plugins für Themen wie Rate-Limiting, Persisted Operations, Response-Caching, Sentry-Integration oder OpenTelemetry, die sich frei kombinieren lassen und unabhängig vom verwendeten Server auch mit anderen envelop-kompatiblen Setups funktionieren. Diese Modularität erlaubt es, exakt die Funktionen zu aktivieren, die ein Projekt braucht, ohne ungenutzten Code mitzuschleppen.
Apollo-Server-Plugins sind enger an das Apollo-Server-Lebenszyklusmodell gebunden und decken vor allem Observability, Caching und Validierung ab, dafür aber mit tiefer, offiziell gepflegter Integration in Apollo Studio. Wer stark auf offizielle Unterstützung und Versionsgarantien eines einzelnen Anbieters setzt, findet bei Apollo Server tendenziell konsistenter gepflegte Plugins, wer maximale Modularität will, profitiert eher vom offeneren envelop-Ökosystem.
import { envelop, useSchema } from '@envelop/core'
import { useRateLimiter } from '@envelop/rate-limiter'
import { usePersistedOperations } from '@envelop/persisted-operations'
import { useOpenTelemetry } from '@envelop/opentelemetry'
const getEnveloped = envelop({
plugins: [
useSchema(schema),
useRateLimiter({ identifyFn: (ctx) => ctx.request.ip }),
usePersistedOperations({ getPersistedOperation: (hash) => store.get(hash) }),
useOpenTelemetry({ resolvers: true, variables: false }),
],
})
7. Developer Experience: GraphiQL, Fehlerbehandlung und Landing Page
GraphQL Yoga liefert standardmäßig eine eingebaute GraphiQL-Oberfläche mit Explorer, die ohne zusätzliche Konfiguration unter dem Server-Endpunkt erreichbar ist, inklusive automatisch generierter Schema-Dokumentation. Fehler werden nach der offiziellen GraphQL-over-HTTP-Spezifikation formatiert, was die Fehlerbehandlung im Client vorhersehbarer macht als bei Servern mit eigenem, undokumentiertem Fehlerformat.
Apollo Server bietet mit dem Apollo Sandbox eine ähnlich komfortable Entwicklungsoberfläche, die zusätzlich Verlaufshistorie und Variablen-Presets speichert, wenn ein Apollo-Studio-Konto verbunden ist. Für Teams ohne Apollo-Studio-Zugang bleibt die Sandbox trotzdem lokal nutzbar, verliert aber einen Teil ihres Mehrwerts gegenüber der einfacheren, aber vollständig lokalen GraphiQL-Oberfläche von Yoga.
8. Migrationsaufwand zwischen GraphQL Yoga und Apollo Server
Da beide Server dasselbe GraphQL-Schema und dieselben Resolver-Signaturen verwenden, bleibt der eigentliche Geschäftslogik-Code bei einer Migration fast unverändert. Der Aufwand konzentriert sich auf drei Stellen: den Context-Aufbau, der bei Apollo Server über eine context-Funktion mit Zugriff auf req läuft und bei Yoga sehr ähnlich, aber mit WHATWG-Request-Objekten funktioniert, das Plugin-Setup, das komplett neu zusammengestellt werden muss, und die Deployment-Konfiguration.
In der Praxis dauert eine Migration eines mittelgroßen Servers meist ein bis drei Tage, wobei der größte Zeitaufwand nicht im Code liegt, sondern im Nachbau der Observability-Kette, wenn ein Team bislang auf Apollo Studio angewiesen war und nun eine gleichwertige Lösung über OpenTelemetry und ein envelop-Plugin aufbauen muss.
// Apollo Server context function
const server = new ApolloServer({ typeDefs, resolvers })
await startStandaloneServer(server, {
context: async ({ req }) => ({
userId: verifyToken(req.headers.authorization),
}),
})
// GraphQL Yoga equivalent, using a WHATWG Request object
const yoga = createYoga({
schema,
context: async ({ request }) => ({
userId: verifyToken(request.headers.get('authorization')),
}),
})
9. Entscheidungshilfe: welcher Server passt zu welchem Projekttyp
Für Teams, die bereits im Apollo-Ökosystem stecken, eine föderierte Architektur mit Apollo Router betreiben oder Wert auf eine verwaltete Studio-Plattform mit Schema-Checks legen, ist Apollo Server meist die reibungsärmere Wahl. Für Teams, die einen möglichst schlanken, Standards-treuen Server ohne Herstellerbindung suchen, insbesondere für Deployments auf Edge-Plattformen, ist GraphQL Yoga oft die passendere Grundlage.
Die folgende Tabelle stellt die wichtigsten Entscheidungskriterien gegenüber.
| Kriterium | GraphQL Yoga | Apollo Server | Empfehlung |
|---|---|---|---|
| Kernphilosophie | Minimal, Standards-basiert | Integriertes Ökosystem | Je nach gewünschter Kopplung |
| Plugin-System | envelop, herstellerunabhängig | Apollo-Lifecycle-Plugins | Yoga bei maximaler Modularität |
| Edge-Kompatibilität | Nativ, WHATWG-Fetch-basiert | Eingeschränkt, primär Node.js | Yoga für Edge-Deployments |
| Observability | Über envelop/OpenTelemetry | Eingebaut über Apollo Studio | Apollo bei Managed-Studio-Wunsch |
Mironsoft
GraphQL-Schema-Design, Resolver-Performance und API-Sicherheit
GraphQL-APIs, die unter echter Last stabil bleiben?
Wir prüfen bestehende GraphQL-Schemas und Resolver, decken N+1-Probleme und fehlende Query-Limits auf und bauen daraus eine API, die Performance, Sicherheit und Wartbarkeit gleichzeitig hält.
Schema-Review
Typen, Resolver und Berechtigungen auf Konsistenz und Sicherheitslücken prüfen.
Performance-Optimierung
DataLoader, Caching und Query-Complexity-Limits gegen N+1 und Overfetching einsetzen.
Produktions-Absicherung
Rate-Limiting, Introspection-Schutz und Monitoring für den produktiven Betrieb einrichten.
10. Zusammenfassung
GraphQL Yoga und Apollo Server: Das Wichtigste auf einen Blick
Kernphilosophie
GraphQL Yoga setzt auf einen minimalen, Standards-basierten Kern mit envelop-Plugins, Apollo Server auf ein integriertes Ökosystem samt Studio-Anbindung.
Federation
Beide unterstützen Federation, Apollo Server nativ über @apollo/subgraph, Yoga über @graphql-tools/federation oder GraphQL Mesh.
Edge-Deployments
Yogas WHATWG-Fetch-basierter Kern läuft ohne Anpassung auf Cloudflare Workers und Vercel Edge, Apollo Server bleibt primär Node.js-zentriert.
Migration
Resolver und Schema bleiben unverändert, Aufwand entsteht vor allem beim Context-Aufbau, Plugin-Setup und Nachbau der Observability-Kette.