REST-APIs können Sie einschränken und Sie dazu zwingen, für die gewünschten Daten große Umwege zu machen. GraphQL kehrt das um. Sie fragen nach dem, was Sie brauchen, und das ist alles, was Sie bekommen, ohne unnötige Datenmengen oder Füllmaterial.
Wenn Sie schon einmal versucht haben, eine App mit vielen verbundenen Daten zu verknüpfen, haben Sie wahrscheinlich die Grenzen von REST gespürt. Manchmal müssen Sie sich durch einen Haufen Daten wühlen, die Sie gar nicht angefordert haben. In anderen Fällen ist genau das, was Sie brauchen, nicht vorhanden. So oder so spüren Ihre Nutzer die Verzögerung.
Stellen Sie sich Ihre Storefront-App vor. Sie möchten lediglich die Namen Ihrer Kunden und deren letzte Bestellungen sehen. Wenn Sie REST verwenden, müssen Sie eine Reihe separater Anfragen stellen, um alle Informationen zusammenzufügen. Mit GraphQL senden Sie eine einzige Abfrage an einen einzigen Endpunkt und erhalten alles, was Sie benötigen, auf einmal.
REST-Beispiel:
Die REST-Aufrufe könnten wie folgt aussehen:
GET /customer/1
{
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"age": 30
}
GET /orders?customerId=1
[
{ "id": 1, "title": "Laptop" },
{ "id": 2, "title": "Mouse" }
]
Dieser REST-Ansatz sendet übermäßige Datenmengen, deren Filterung zusätzlichen Aufwand erfordert.
GraphQL-Beispiel:
GraphQL handhabt dies effizienter mit einer einzigen fokussierten Abfrage:
query {
customer(id: 1) {
name
orders {
title
}
}
}
Ergebnis:
{
"customer": {
"name": "Alice",
"orders": [
{ "title": "Laptop" },
{ "title": "Mouse" }
]
}
}
Die einzelne Anfrage liefert genau das, was das Frontend benötigt. Keine zusätzlichen Roundtrips, keine redundanten Daten, einfach direkt und effizient.
Facebook hat GraphQL 2015 entwickelt, um Daten schnell in den News Feed zu übertragen. Nachdem es als Open Source veröffentlicht wurde, begannen andere Unternehmen, es zu nutzen, da es ihnen ermöglichte, Datenanfragen über einen einzigen Endpunkt präziser zu bearbeiten.
Das zeichnet GraphQL aus:
Wenn Sie mit verbundenen Datenstrukturen arbeiten, vereinfacht das Abfragesystem von GraphQL die Entwicklung.
GraphQL ist nicht nur eine weitere API, es ist eine Abfragesprache, mit der Sie über einen einzigen Endpunkt genau die Daten abrufen können, die Sie benötigen. Dies vereinfacht zwar die Client-Server-Kommunikation, aber Sie sollten sich darüber im Klaren sein, welche Vorteile dies mit sich bringt.
Im Gegensatz zu REST-APIs, bei denen Sie mehrere Aufrufe für unterschiedliche Daten benötigen, fasst GraphQL alles in einer einzigen Abfrage zusammen. Denken Sie jedoch daran, dass Sie beim Erstellen der Anwendung Caching und Leistung berücksichtigen müssen.
Schauen wir uns an, wie GraphQL reale Anwendungen prägt und warum Entwickler es für die moderne API-Entwicklung wählen.
GraphQL verarbeitet Daten auf eine für Entwickler wichtige Weise.
GraphQL bietet Ihnen eine flexible und präzise API-Schicht. Durch eine durchdachte Implementierung von Caching, Leistung und Schema-Design kann es Ihren Entwicklungsprozess effizienter gestalten.
Sehen wir uns nun an, wie GraphQL Schemata und Typen verwendet, um Flexibilität und Leistung in Einklang zu bringen.
Ein GraphQL-Schema definiert, mit welchen Daten Ihre API arbeiten kann, betrachten Sie es als eine Art Vertrag zwischen Ihrem Client und Ihrem Server. Mit einer einfachen Sprache namens SDL (Schema Definition Language) setzt es klare Grenzen für den Datenaustausch.
Sehen wir uns dies anhand eines einfachen „User”-Typs in der Praxis an:
type User {
id: ID!
name: String!
email: String!
}
type Query {
getUser(id: ID!): User
}
Das Schema fungiert als klarer Regelkatalog für Datenanfragen. Sie teilen GraphQL mit, welche Felder Sie benötigen, und das Schema überprüft, ob diese Felder vorhanden sind. Wie bei einem Menü, aus dem Sie genau das auswählen können, was Sie brauchen.
Schemas helfen dabei, Datenverbindungen so zu organisieren, dass Ihre Abfragen effizienter werden und Sie genau die Informationen erhalten, die Sie suchen.
Ihr Schema zeigt auch, wie verschiedene Teile Ihrer Daten miteinander verknüpft sind. Mit GraphQL können Sie diese Verbindungen über einen einzigen Endpunkt abfragen, was einfacher ist als die Verwendung mehrerer REST-Endpunkte.
type Post {
id: ID!
title: String!
content: String!
author: User
}
Jeder Beitrag kann mit seinem Autor verknüpft werden. Im Gegensatz zu REST-APIs, die mehrere API-Aufrufe erfordern, können GraphQL-Abfragen sowohl Beitrags- als auch Autorendaten über einen einzigen Endpunkt gleichzeitig abrufen, es handelt sich um eine optimierte Abfragesprache für APIs.
Ihr Schema muss sowohl flexibel als auch wartbar sein, wenn es mit Ihrer App mitwachsen soll. Folgendes hat sich bewährt:
enum Role {
ADMIN
USER
}
input UpdateUserInput {
id: ID!
name: String
email: String
}
Ein gut strukturiertes Schema erleichtert die klare Kommunikation zwischen Clients und Servern über einen einzigen Endpunkt.
Sehen wir uns an, wie diese Schema-Konzepte in der Praxis mit GraphQL funktionieren.
GraphQL bietet Ihnen zwei einfache Tools zum Umgang mit Daten: Abfragen und Mutationen. Diese erleichtern die Arbeit mit Ihrer API.
query {
getUser(id: "1") {
id
name
email
}
}
mutation {
updateUser(input: { id: "1", name: "John Doe" }) {
name
email
}
}
GraphQL hält die Dinge einfach, indem es zwei Hauptmethoden für die Arbeit mit Daten bietet: Abfragen zum Abrufen von Informationen und Mutationen zum Ändern dieser Informationen. Alles geschieht über einen einzigen Verbindungspunkt, wodurch Ihr Code übersichtlich und leicht verständlich bleibt.
GraphQL arbeitet mit Echtzeit-Updates über Abonnements, die WebSocket-Verbindungen und eine Serverkonfiguration erfordern. Sobald es läuft, erhält Ihre App Updates sofort, sobald sie erfolgen.
So sehen Abonnements in einer Chat-App aus:
subscription {
onNewMessage(roomId: "123") {
content
timestamp
}
}
Wenn etwas Neues passiert (z. B. eine neue Chat-Nachricht), senden Abonnements die Aktualisierungen über WebSocket-Verbindungen an die verbundenen Clients. Sie müssen nicht ständig nach Aktualisierungen suchen, benötigen jedoch eine bestimmte Serverkonfiguration und WebSocket-Unterstützung.
GraphQL und REST verfolgen unterschiedliche Ansätze, wenn es um Fehler geht. Bei REST erhalten Sie einen HTTP-Statuscode und eine Fehlermeldung im Antworttext, sodass Sie wissen, was fehlgeschlagen ist. GraphQL hält es einfach. Sofern kein Netzwerkproblem vorliegt, erhalten Sie immer einen 200 OK-Status, und alle Fehler werden in einem speziellen Fehlerfeld in der Antwort angezeigt.
Sehen Sie selbst:
{
"errors": [
{
"message": "User not found",
"path": ["getUser"]
}
]
}
GraphQL liefert klare Fehlermeldungen, wenn etwas schiefgeht. Die Schema-Validierung hilft Entwicklern, Probleme während der Entwicklung und nicht erst in der Produktion zu erkennen und zu beheben.
Wie ein hilfreicher Übersetzer vereinfacht GraphQL die Kommunikation zwischen Ihrer App und den Daten. Es fasst alles, was Sie benötigen, in einer einzigen Anfrage zusammen und sorgt für einen reibungslosen Informationsfluss.
Sehen wir uns an, wie Sie GraphQL mit Apollo Server, einem soliden Tool zum Erstellen von GraphQL-APIs, dem viele Entwickler vertrauen, in der Produktion zum Laufen bringen.
Mit dem Apollo-Server können Sie eine GraphQL-API erstellen, die alle Ihre Daten über einen einzigen Endpunkt verarbeitet. Der Einstieg ist ganz einfach.
npm install apollo-server graphql
Erstellen Sie einen einfachen Server:
Hier ist ein Beispiel für die Erstellung eines Apollo-Servers mit einem Beispielschema und einem Resolver.
const { ApolloServer, gql } = require('apollo-server');
// Definieren Sie das GraphQL-Schema mit `gql`.
const typeDefs = gql`
type Query {
hello: String
}
`;
// Definieren Sie die Resolver für das Schema.
const resolvers = {
Query: {
hello: () => 'Hello, world!',
},
};
// Erstellen einer neuen Apollo-Server-Instanz
const server = new ApolloServer({ typeDefs, resolvers });
// Starten des Servers und Protokollieren der URL
server.listen().then(({ url }) => {
console.log(`Server bereit unter ${url}`);
});
Um Ihre GraphQL-API zu sichern, fügen Sie Ihrer Middleware-Schicht einen JWT-Validierungsschritt hinzu. So geht's:
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req }) => {
const token = req.headers.authorization || '';
const user = validateJWT(token); // Benutzerdefinierte Funktion zum Dekodieren/Validieren von JWT
return { user };
},
});
Diese Sicherheitseinstellung bedeutet, dass nur angemeldete Benutzer Ihre GraphQL-API verwenden können. Sie müssen außerdem Berechtigungen auf Feld- und Typebene einrichten. Dadurch können Benutzer nur auf die Daten zugreifen und diese ändern, die sie sehen sollen, während Ihr einzelner Endpunkt effizient bleibt.
Als Nächstes sehen wir uns an, wie Sie GraphQL mit modernen Client-Apps mithilfe von Apollo Client verbinden können – einem Tool, das die Frontend-Datenverwaltung vereinfacht.
Richten wir Apollo Client ein, einen GraphQL-Client, der Ihre API-Verbindungen vereinfacht. Mit ihm können Sie Ihr Frontend über einen einzigen Endpunkt mit einer GraphQL-API verbinden, sodass Sie nur die Daten erhalten, die Sie benötigen.
npm install @apollo/client graphql
Apollo Client initialisieren:
Einrichten von Apollo Client mit einem GraphQL-Endpunkt und In-Memory-Caching:
import { ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: 'https://example.com/graphql',
cache: new InMemoryCache(),
});
Durch Umschließen Ihrer React-App mit ApolloProvider werden Datenabfragen in Ihrer gesamten Anwendung vereinfacht:
import { ApolloProvider } from '@apollo/client';
import App from './App';
const Root = () => (
<ApolloProvider client={client}>
<App />
</ApolloProvider>
);
Nachdem Apollo Client bereit ist, sorgen wir für die Sicherheit unserer API und stellen sicher, dass Benutzer nur auf die Daten zugreifen können, die sie sehen sollen.
So funktioniert die rollenbasierte Zugriffskontrolle mit JWT-Tokens in Resolvern. Hier ist ein praktisches Beispiel, das zeigt, wie API-Aufrufe autorisiert werden:
const resolvers = {
Query: {
getUser: async (_, { id }, { user }) => {
if (!user || user.role !== 'ADMIN') {
throw new Error('Unauthorized');
}
return await User.findById(id);
},
},
};
Apollo Server ruft Ihre API-Daten aus dem JWT-Token ab und stellt sie in Ihren GraphQL-Resolvern zur Verfügung. Auf diese Weise können Sie anhand dieser Daten überprüfen, ob jemand die Berechtigung hat, die Datenquelle abzufragen oder zu ändern.
Tests helfen Ihnen sicherzustellen, dass Ihre API korrekt funktioniert. Wir verwenden Jest für unsere Tests, da es einfach und effektiv ist.
Schreiben Sie einen Test für eine Abfrage:
describe('GraphQL Queries', () => {
it('fetches user data', async () => {
const query = `
query {
getUser(id: "1") {
id
name
}
}
`;
const response = await executeGraphQL(query); // Replace with test setup logic
expect(response.data.getUser.name).toBe('John Doe');
});
});
Erkennen Sie Probleme frühzeitig durch häufiges Testen. So bleibt Ihr Schema zuverlässig und Sie vermeiden Debugging-Probleme. Nachdem wir uns nun mit dem Testen befasst haben, wollen wir uns mit der Optimierung der Leistung Ihrer GraphQL-API beschäftigen.
GraphQL-APIs stoßen häufig auf das n+1-Abfrageproblem. Dies tritt auf, wenn eine API-Anfrage einen Datenblock abruft und anschließend weitere zugehörige Daten benötigt, wodurch mehrere Datenbankaufrufe entstehen, die den Vorgang verlangsamen.
DataLoader macht GraphQL schneller, indem es Datenbankaufrufe kombiniert und Ergebnisse speichert. So optimiert GraphQL API-Aufrufe, um genau die Daten zu erhalten, die Sie benötigen:
const userLoader = new DataLoader(keys =>
User.findMany({ where: { id: keys } })
);
// Resolver example
const resolvers = {
Post: {
author: (post) => userLoader.load(post.authorId),
},
};
DataLoader kombiniert Datenbankabfragen, reduziert die Serverlast und beschleunigt API-Antworten. Damit wird die Verwaltung von APIs zum Kinderspiel.
Als Nächstes sehen wir uns an, wie Caching Ihre GraphQL-API noch schneller machen kann.
GraphQL verfügt nicht über integriertes Caching, aber die Tools in seinem Ökosystem bieten Ihnen solide Caching-Optionen. So können Sie Caching zu Ihren GraphQL-Apps hinzufügen:
Schauen wir uns an, wie Sie Caching mit Apollo Client einrichten:
import { createPersistedQueryLink } from '@apollo/client/link/persisted-queries';
import { ApolloClient, InMemoryCache } from '@apollo/client';
// Apollo Client mit persistenten Abfragen konfigurieren
const client = new ApolloClient({
link: createPersistedQueryLink().concat(httpLink),
cache: new InMemoryCache(),
});
Überwachen Sie Ihre GraphQL-API, um sicherzustellen, dass sie schnell und zuverlässig bleibt. Die Tools von Apollo zeigen Ihnen, welche Abfragen beliebt sind und wo es zu Verzögerungen kommt.
Wenn Abfragen langsam werden, wissen Sie sofort, wo Sie Caching hinzufügen oder DataLoader verwenden müssen, um die Geschwindigkeit zu erhöhen. Durch regelmäßige Überwachung können Probleme frühzeitig erkannt und behoben werden.
Die Bereitstellung mit Upsun ist einfach und schnell. Wir verfügen über integrierte Caching- und Bereitstellungstools, mit denen Sie Ihre API sofort in der Produktion ausführen können. Test- und Produktionsumgebungen sind schnell eingerichtet, sodass Sie sofort mit der Arbeit beginnen können.
Wenn Sie APIs haben, die in verschiedenen Regionen funktionieren müssen, sorgt unser globales Caching für schnelle und stabile Abläufe. Das bedeutet, dass Ihre Benutzer nicht warten müssen, sie erhalten schnelle Antworten, egal wo sie sich befinden, und Ihr GraphQL-Dienst bleibt auch bei Wachstum reaktionsschnell.
Mit GraphQL können mobile Apps Daten mit einem einzigen API-Aufruf abrufen. Sie fordern genau das an, was Ihre App benötigt, also nur Benutzernamen statt vollständiger Profile.
Stellen Sie sich eine mobile App vor, die Profile, Aktivitäten und Benachrichtigungen anzeigt. Während REST-APIs möglicherweise mehrere Aufrufe erfordern, kann GraphQL diese in einer einzigen Anfrage zusammenfassen, was je nach Ihrer spezifischen Implementierung und Caching-Strategie die Akkulaufzeit und die Antwortzeiten verbessern kann.
GraphQL eignet sich hervorragend für die Verarbeitung verknüpfter Daten, sodass Sie alle zugehörigen Informationen in einer einzigen Abfrage abrufen können.
Stellen Sie sich vor, Sie suchen die Bestellhistorie eines Kunden und möchten Details darüber erfahren, was er gekauft hat, wer es verkauft hat und wo sich jedes Paket gerade befindet. Mit GraphQL fragen Sie einfach alles auf einmal ab. Wenn Sie mit REST arbeiten, müssten Sie zwischen mehreren Endpunkten hin- und herspringen und die Informationen selbst zusammenstellen.
Wenn Sie Microservices betreiben, kann GraphQL als zentrales API-Gateway fungieren. Mit Tools wie Schema Stitching oder Apollo Federation können Sie alle Ihre Dienste unter einem Dach zusammenführen.
Stellen Sie sich Folgendes vor: Benutzer, Bestellungen und Produkte sind auf ihre Microservices aufgeteilt. GraphQL verbindet sie mit einem einzigen Schema. Das Gateway findet heraus, wo sich die einzelnen Dienste befinden, bearbeitet die Anfragen und führt die Daten für Sie zusammen.
Wenn Sie diesen Ansatz in der Praxis sehen, können Sie leichter vergleichen, wie GraphQL und REST jeweils mit verteilten Systemen umgehen.
REST-APIs bieten Ihnen feste Endpunkte für jede Ressource, aber das ist nicht immer die beste Lösung. Ohne gute Planung erhalten Sie entweder mehr Daten als Sie benötigen (z. B. vollständige Benutzerprofile, obwohl Sie nur Namen wollen) oder Sie müssen mehrere Aufrufe tätigen, um die gewünschten Daten zu erhalten. Moderne REST-APIs können dies besser handhaben, indem sie Ihnen die Auswahl bestimmter Felder ermöglichen und andere Methoden verwenden, um die Effizienz zu gewährleisten.
Mit GraphQL können Sie präzise vorgehen. Ein Endpunkt, exakte Daten. Sie möchten den Namen eines Benutzers und seine letzten Beiträge? Genau das erhalten Sie.
Beispiel für eine REST-Antwort (Overfetching):
{
"id": "1",
"name": "John Doe",
"birthdate": "1990-01-01",
"address": { "street": "123 Main St", "city": "Example City" }
}
Beispiel für eine GraphQL-Abfrage (spezifisches Abrufen von Daten):
query {
getUser(id: "1") {
name
posts {
title
}
}
}
Sehen wir uns nun an, wie REST und GraphQL Daten in realen Situationen verarbeiten.
REST eignet sich gut für einfache Daten, die Endpunkten zugeordnet sind. Wenn Sie jedoch verschachtelte Daten benötigen (z. B. Benutzer und deren Beiträge), sind mehrere Aufrufe erforderlich oder Sie erhalten zusätzliche Daten, die Sie nicht benötigen.
GraphQL glänzt mit verknüpften Daten, wenn Sie es richtig einrichten. Sie schreiben eine einzige Abfrage, um genau das zu erhalten, was Sie benötigen, wodurch Ihre App bei richtiger Einrichtung schneller laufen kann. Denken Sie jedoch daran, dass die Geschwindigkeit von Ihrer Caching-Konfiguration und Ihrer Implementierung abhängt. Vergessen Sie nicht, DataLoader auf Ihrem Server einzurichten, um Verzögerungen durch N+1-Abfragen zu vermeiden.
REST und GraphQL behandeln Aktualisierungen nicht auf die gleiche Weise. Bei REST ist es üblich, Ihre API direkt in der URL zu versionieren, z. B. /v1/users. Modernes REST kann auch Content Negotiation und Hypermedia verwenden, um ohne Versionsnummern zu aktualisieren.
Mit GraphQL können Sie schrittweise aktualisieren, indem Sie Felder als veraltet markieren. Ihr Code funktioniert weiterhin, während Entwickler Zeit haben, ihren Code anzupassen.
So markieren Sie Felder in Ihrem Schema als veraltet:
type User {
id: ID!
name: String!
email: String @deprecated(reason: "Verwenden Sie stattdessen 'contactEmail'.")
contactEmail: String
}
Mit GraphQL können Sie Ihre API schrittweise aktualisieren. Sie müssen nicht alle gleichzeitig zur Aktualisierung zwingen, Entwickler können ihren Code ändern, wenn es ihnen passt.
GraphQL verfügt über integrierte Tools, mit denen Sie APIs während der Entwicklung einfach erkunden können. Während Sie Tools wie GraphiQL und GraphQL Playground aus Sicherheitsgründen in der Produktion deaktivieren sollten, können Sie mit dem Typsystem Fehler frühzeitig erkennen. Diese Typprüfung arbeitet mit der Schema-Validierung zusammen, um Probleme schnell zu erkennen und die Zusammenarbeit zwischen Frontend- und Backend-Teams zu vereinfachen.
REST-APIs liefern oft zu viele Daten (Overfetching) oder erfordern mehrere Endpunkt-Aufrufe (Underfetching). Beides ist nicht ideal.
Mit GraphQL können Sie in einer einzigen Abfrage genau das anfordern, was Sie benötigen. Möchten Sie den Namen eines Benutzers und dessen neueste Beiträge abrufen? Dazu ist nur eine einzige Abfrage statt mehrerer REST-Endpunkte erforderlich. Bei korrekter Implementierung erhalten Sie kleinere Payloads und reduzieren den Netzwerkverkehr. Die Entwicklungsabläufe können für bestimmte Arten von Anwendungen vereinfacht werden, insbesondere für solche mit komplexen Datenbeziehungen.
Schauen wir uns an, wie Caching diese schnellen Abfragen noch schneller machen kann.
Hier erfahren Sie, was Sie wissen müssen, um Ihre GraphQL-Apps mit Caching schneller laufen zu lassen.
Caching ist keine Einheitslösung. REST-APIs funktionieren von Haus aus gut mit HTTP-Caching und CDNs, aber mit GraphQL müssen Sie etwas mehr Arbeit investieren, um die gleichen Ergebnisse zu erzielen. Es lohnt sich, einen Schritt zurückzutreten und zu überlegen, was Ihre App wirklich braucht, bevor Sie sich für einen Caching-Ansatz entscheiden.
Lassen Sie uns von Anfang an Sicherheit in Ihre GraphQL-API einbauen. Mit dem richtigen Schutz werden Sie keine Probleme mit komplexen verschachtelten Abfragen haben, die Ihren Server verlangsamen. Hier ist, was Sie brauchen:
Verwenden Sie graphql-shield auf Ihrem Server für Autorisierungsregeln. Mit dieser Middleware legen Sie Regeln fest, wer bestimmte Daten in Ihrem GraphQL-Schema sehen oder ändern darf. Auf diese Weise erhalten Benutzer nur Zugriff auf das, was sie sehen sollen.
GraphQL bietet Ihnen eine flexible Abfragesprache für APIs. Sowohl GraphQL als auch REST können Daten effizient abrufen, aber das schemabasierte Design und das integrierte Typsystem von GraphQL eignen sich besonders gut für bestimmte Aufgaben. Es verfügt über solide Tools für die Typprüfung und Echtzeit-Updates, was es ideal für moderne Apps macht, die viele Daten benötigen.
Sie sind neu bei GraphQL? Beginnen Sie damit, es nur für eine Funktion in Ihrer App zu verwenden. So können Sie die Grundlagen erlernen, während Ihre aktuellen Systeme weiterlaufen.
Probieren Sie GraphQL zunächst mit kleinen Implementierungen aus. So können Sie sehen, wie es zu den Anforderungen Ihres Teams passt.
Möchten Sie mit GraphQL entwickeln? Sehen wir uns an, wie Sie beginnen können.
Wenn Sie für die Produktion bereit sind, verwenden Sie Infrastruktur-Tools wie Upsun, die Mechanismen zum Klonen von Umgebungen und zum Caching bieten, um eine reibungslose Bereitstellung zu gewährleisten.
Fangen Sie klein an, wählen Sie eine Funktion aus, die Sie mit GraphQL ausprobieren möchten, testen Sie sie gründlich und bauen Sie darauf auf. Das ist der direkte Weg zur Erstellung sauberer, effizienter APIs.