tRPC vs GraphQL Vergleich

Null Codegen, durchgängige TypeScript-Typsicherheit

VS
GraphQL

Schema-first, universelle Abfragesprache für mehrere Clients

16 Min. LesezeitBackend

Schnelles Fazit

Entscheide je nach Situation – 'Typsicherheit' allein ist kein Argument für GraphQL. Wenn du ein einziges TypeScript-Monorepo mit einem einzigen Web-Client nutzt, verursacht tRPC fast immer weniger Aufwand – kein Codegen, eine Serveränderung erzeugt sofort einen TS-Fehler im Client. Hast du eine mobile App, eine öffentliche API für externe Entwickler oder benötigst du eine teamübergreifende Föderation, verschafft GraphQLs sprachunabhängiger Schema-Vertrag und das Apollo-Federation-Ökosystem einen strukturellen Vorteil.

tRPCGraphQL
Vollständiges Fazit lesen

Punktevergleich

Diagramm wird geladen...

Detaillierte Bewertung

Detaillierte Bewertung: tRPC und GraphQL — Bewertungen pro Kategorie auf einer Skala von 1 bis 10
KategorietRPCGraphQL
Performance
7/10
6/10
Erlernbarkeit
8/10
5/10
Ökosystem
6/10
9/10
Community
7/10
8/10
Arbeitsmarkt
5/10
8/10
Zukunftssicherheit
7/10
8/10

Vor- und Nachteile

tRPC

Vorteile

  • Keine Codegenerierung oder Build-Schritt — Server-Typen fließen direkt zum Client
  • Bei einer Änderung am Server sieht der Client den TypeScript-Fehler, noch bevor die Datei gespeichert wird
  • Es gibt offizielle Adapter für React, Next.js, Express, Fastify, AWS Lambda, Solid und Svelte
  • Native Integration mit TanStack Query — queryKey/queryOptions-Factorys sind vorgefertigt
  • Laut offizieller FAQ setzen Unternehmen wie Netflix und Pleo es in Produktion ein
  • Selbst die Abhängigkeit von TanStack Query ist optional — ein einfacher Vanilla-Client genügt
  • Subscriptions werden über WebSocket oder SSE unterstützt; die SSE-Einrichtung wird als einfacher empfohlen
  • MIT-lizenziert, vollständig Open Source — keine kostenpflichtige Enterprise-Ebene

Nachteile

  • Die Typweitergabe ist an dasselbe TypeScript-Monorepo gebunden — ein nativer mobiler Client verliert diesen Vorteil
  • Es gibt keine offizielle öffentliche/REST-API-Oberfläche; dafür ist ein Drittanbieter-Paket wie `trpc-to-openapi` nötig
  • Es gibt keine Schema-Introspection — dem externen Entwickler wird kein selbstdokumentierender Vertrag geboten
  • Es gibt keine feldbasierte Auswahl (Field Selection) — jede Prozedur hat einen festen Rückgabetyp
  • In Szenarien, in denen das Backend nicht in JavaScript/TypeScript geschrieben ist, kann es nicht verwendet werden
  • Es gibt keinen offiziellen Standard für Föderation/Schema-Komposition über mehrere Services

Am besten geeignet für

Produkte mit einem einzigen TypeScript-Monorepo und einem einzigen Web-ClientFull-Stack-TS-Projekte auf Basis von Next.js, Express oder FastifyKleine bis mittelgroße Teams, die schnell iterieren wollenInterne Tools und Admin-Panels ohne externe KonsumentenProjekte, die bereits TanStack Query verwenden

GraphQL

Vorteile

  • Der Client wählt nur die benötigten Felder aus — Over-/Under-Fetching wird strukturell gelöst
  • Sprachunabhängiger Schema-Vertrag — bedient iOS, Android, Web und jeden Drittanbieter-Client nativ
  • Dokumentiert sich durch Introspection selbst; mit Tools wie GraphiQL erkundbar
  • Ermöglicht Schema-Weiterentwicklung über den Deprecation-Mechanismus, ohne breaking Changes zu erfordern
  • Das offizielle `graphql/dataloader`-Paket löst das N+1-Problem mit Batching und Caching
  • Mit Apollo Federation gibt es offizielle Unterstützung für Schema-Komposition in Multi-Team-/Multi-Service-Architekturen
  • Wird seit 2018 von der GraphQL Foundation unter dem Dach der Linux Foundation verwaltet
  • Offizielle Clients wie Relay verhindern mit einem normalisierten Cache unnötige Re-Renders

Nachteile

  • Es gibt keine HTTP-cache-freundliche URL-Struktur — erfordert globale IDs plus einen normalisierten Client-Cache
  • Zusätzliche Konzepte wie Schema-Design, Resolver-Architektur und Dataloader erhöhen die Lernkurve
  • Die Föderation befindet sich noch im Standardisierungsprozess — die Composite Schema Working Group arbeitet aktiv daran
  • Auf Unternehmensebene sind Ebenen wie Apollo GraphOS kostenpflichtig (Developer-Plan: 5 $/Million Anfragen)
  • Das N+1-Risiko ohne Dataloader zu belassen ist eine häufig anzutreffende Fehlerklasse
  • Bei einfachen CRUD-Szenarien erfordert es mehr Boilerplate (Schema + Resolver) als tRPC oder REST

Am besten geeignet für

APIs mit mobilen (iOS/Android) oder Drittanbieter-KonsumentenArchitekturen mit Föderationsbedarf in Multi-Team-/Multi-Service-OrganisationenÖffentliche APIs, die für externe Entwickler geöffnet werdenAnwendungen, in denen komplexe, verschachtelte Datengraphen abgefragt werdenGroß angelegte Systeme mit Bedarf an Enterprise-SLA und Schema-Governance

Code-Vergleich

tRPC
// tRPC — Router-Definition (Server)
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
// db = Prisma/ORM-Client (aus einer separaten Datei importiert)

const t = initTRPC.create();

export const appRouter = t.router({
  getUser: t.procedure
    .input(z.object({ id: z.string() }))
    .query(async ({ input }) => {
      return db.user.findUnique({ where: { id: input.id } });
    }),
});

export type AppRouter = typeof appRouter;

// Client — Server-Typ wird automatisch abgeleitet, kein Codegen
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from './server';

const client = createTRPCClient<AppRouter>({
  links: [httpBatchLink({ url: 'http://localhost:3000/trpc' })],
});

const user = await client.getUser.query({ id: '1' });
// user: { id: string; name: string; ... } — vollständige Typsicherheit zur Kompilierzeit
GraphQL
// graphql-js + @apollo/server — Schema, Resolver und Server in einer Datei
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
// db = Prisma/ORM-Client (aus einer separaten Datei importiert)

const typeDefs = `#graphql
  type Post {
    id: ID!
    title: String!
  }

  type User {
    id: ID!
    name: String!
    posts: [Post!]!
  }

  type Query {
    user(id: ID!): User
  }
`;

const resolvers = {
  Query: {
    user: (_parent, { id }, { db }) => db.user.findUnique({ where: { id } }),
  },
  User: {
    posts: (user, _args, { db }) =>
      db.post.findMany({ where: { authorId: user.id } }),
  },
};

const server = new ApolloServer({ typeDefs, resolvers });

const { url } = await startStandaloneServer(server, {
  context: async () => ({ db }),
  listen: { port: 4000 },
});
console.log(`Server bereit: ${url}`);

// Client-Abfrage — es werden nur die benötigten Felder ausgewählt:
// query { user(id: "1") { name posts { title } } }

Fazit

Entscheide je nach Situation – 'Typsicherheit' allein ist kein Argument für GraphQL. Wenn du ein einziges TypeScript-Monorepo mit einem einzigen Web-Client nutzt, verursacht tRPC fast immer weniger Aufwand – kein Codegen, eine Serveränderung erzeugt sofort einen TS-Fehler im Client. Hast du eine mobile App, eine öffentliche API für externe Entwickler oder benötigst du eine teamübergreifende Föderation, verschafft GraphQLs sprachunabhängiger Schema-Vertrag und das Apollo-Federation-Ökosystem einen strukturellen Vorteil.

Kostenlose Beratung erhalten
FAQ

Häufig gestellte Fragen

Arbeitest du in einem einzigen TypeScript-Monorepo mit einem einzigen Web-Client, benötigt tRPC weniger Code und Konfiguration (kein Codegen, durchgängige TS-Inferenz — trpc.io). Hast du eine mobile App, eine öffentliche API für externe Entwickler oder mehrere unabhängige Services, bietet GraphQLs Schema-Vertrag und das Föderations-Ökosystem (Apollo Federation) eine passendere Abstraktion.

Verwandte Blogartikel

Alle Artikel ansehen
Alle Vergleiche