Wie erstellt man eine GraphQL API?
In den letzten Jahren hat sich GraphQL zu einer beliebten Wahl für die Erstellung komplexer APIs entwickelt. Dies liegt daran, dass es einige der Einschränkungen herkömmlicher REST-APIs beseitigt und Ihre API flexibler und effizienter macht.
In diesem Artikel besprechen wir GraphQL, seine Vor- und Nachteile, wichtige GraphQL-Terminologie und vergleichen GraphQL-APIs mit REST-APIs. Darüber hinaus zeigen wir Ihnen, wie Sie Ihre eigene GraphQL-API auf Back4app erstellen und sich von einem Next.js-Frontend aus mit ihr verbinden können.
Contents
- 1 GraphQL-Einführung
- 2 GraphQL vs. REST
- 3 Gemeinsame GraphQL-Begriffe
- 4 Wie funktioniert GraphQL?
- 5 Was sind die Vorteile von GraphQL?
- 6 Was sind die Nachteile von GraphQL?
- 7 Wie erstellt man eine GraphQL API?
- 8 Schlussfolgerung
- 9 FAQ
- 10 Was ist GraphQL?
- 11 Was sind die Hauptunterschiede zwischen REST und GraphQL?
- 12 Welche Begriffe werden häufig in GraphQL verwendet?
- 13 Wie erstellt man eine GraphQL-API?
GraphQL-Einführung
GraphQL ist eine Abfragesprache und eine serverseitige Laufzeitumgebung für die Entwicklung von Anwendungsprogrammierschnittstellen (APIs). Mit GraphQL können Kunden genau angeben, welche Daten sie von der API benötigen, anstatt sich darauf zu verlassen, dass das Backend einen festen Satz von Daten bereitstellt.
GraphQL ist ein moderner und effizienter Ansatz für die Erstellung schneller und flexibler APIs. Es verfügt über ein integriertes Typensystem und basiert auf einem stark typisierten Schema, das die über die API verfügbaren Daten definiert. Es unterstützt Echtzeit-Updates und Abonnements und ermöglicht es Entwicklern, Daten aus mehreren Datenquellen abzurufen. Darüber hinaus erleichtert es die Weiterentwicklung von APIs, da es Entwicklern die Möglichkeit gibt, Felder zu verwerfen, ohne dass sich dies auf bestehende Abfragen oder Mutationen auswirkt.
GraphQL kann von Beginn eines Projekts an verwendet oder in eine bestehende API integriert werden. Einige Unternehmen kombinieren es auch mit REST und migrieren dann Schritt für Schritt.
Es wurde 2012 intern von Facebook entwickelt und später im Jahr 2015 als Open Source zur Verfügung gestellt. GraphQL hat mit dem Aufkommen von Single-Page-Anwendungen (SPAs) und mobilen Apps an Popularität gewonnen. Seit seiner Veröffentlichung wurde es von vielen Tech-Giganten wie GitHub, Airbnb, Pinterest und Shopify übernommen.
GraphQL vs. REST
GraphQL und REST sind zwei beliebte Ansätze für die Erstellung von Web-APIs.
REST (Representational State Transfer) ist ein Software-Architekturstil, der die Struktur des Webs beschreibt. Er wurde im Jahr 2000 eingeführt und ist seit über einem Jahrzehnt der De-facto-Standard für die Erstellung von Web-APIs. Es verwendet HTTP-Methoden wie GET
, POST
, PUT
, PATCH
und DELETE
, um die Ressourcen zu manipulieren. Jede Ressource wird an ihrem Endpunkt gehostet (siehe Abbildung unten) und jedes Mal, wenn wir eine Ressource anfordern, wird der gesamte “Datensatz” zurückgegeben.
Diese Architektur führte zu zwei Problemen. Das erste ist die Unterabrufbarkeit (zu wenig Daten) und die Überabrufbarkeit (zu viele Daten). Außerdem können wir mit REST-APIs keine Datenänderungen abonnieren.
Hier kommt GraphQL ins Spiel. GraphQL hat einen einzigen Endpunkt und ermöglicht es uns, Daten aus mehreren Datenquellen in einer einzigen Anfrage abzufragen. So können wir genau definieren, welche Daten wir benötigen. Außerdem können wir mit GraphQL Datenänderungen abonnieren, ohne den Server abzufragen. Dadurch wird unsere API berechenbarer und selbstdokumentierend.
Letztendlich hängt die Wahl zwischen GraphQL und REST von den spezifischen Anforderungen Ihres Projekts ab. Auch wenn GraphQL großartig ist, könnte es für einfache Projekte zu viel Komplexität mit sich bringen.
Gemeinsame GraphQL-Begriffe
Sehen wir uns einige der gebräuchlichen Begriffe an, die Ihnen bei der Arbeit mit GraphQL begegnen können.
Typ
GraphQL hat ein Typsystem und ist stark typisiert. Es verfügt über einige integrierte skalare Typen wie Int
, Float
, String
und Boolean
, ermöglicht aber auch die Definition eigener Typen.
Ein benutzerdefinierter Typ kann wie folgt definiert werden:
type User {
username: String!
password: String!
friends: [User!]
}
Schema
Ein Schema ist eine Beschreibung der über eine GraphQL-API verfügbaren Daten. Es umfasst die Objekttypen, ihre Felder und zugehörigen Datentypen, Beziehungen, Abfragen, Mutationen und mehr. Ein Schema wird normalerweise mit der Schema Definition Language (SDL) definiert.
Auflöser
Ein Resolver ist eine Funktion, die die Daten für ein bestimmtes Feld in einer GraphQL-Abfrage abruft. Resolver-Funktionen sind dafür verantwortlich, die Daten aus einer Datenquelle zu holen und sie im erwarteten Format zurückzugeben.
Abfrage
Eine Abfrage ist eine Nur-Lese-Anfrage nach Daten aus einer GraphQL-API. Sie können sich Abfragen wie GET-Anfragen
in der REST-API vorstellen.
Beispiel:
query GetUser {
user(id: "Wfx8o2AZrE") {
id
username
fullName
}
}
Diese Abfrage gibt die Liste aller Benutzer zurück.
Mutation
Eine Mutation ist eine Anfrage zur Manipulation der Daten in einer GraphQL-API. Sie können sich Mutationen wie POST/PUT/PATCH/DELETE-Anfragen
in der REST-API vorstellen. Mutationen können auch definieren, welche Daten zurückgegeben werden.
Beispiel:
mutation CreateAuthor {
createAuthor(input: {fields: {firstName: "William", lastName: "Shakespeare"}}) {
author {
id
createdAt
}
}
}
Diese Mutation erstellt einen neuen Autor und gibt dessen ID
und createdAt
zurück.
Abonnement
Ein Abonnement ist eine Anfrage für Echtzeit-Updates von einer GraphQL-API. Abonnements ermöglichen es Clients, Aktualisierungen zu erhalten, sobald sie verfügbar sind, ohne den Server abzufragen.
Beispiel:
subscription OnPostCreate($postID: ID!) {
userAdded(postID: $postID) {
id
user
content
}
}
Dieses Abonnement wird aufgerufen, wenn ein neuer Beitrag erstellt wird.
Wie funktioniert GraphQL?
Um eine GraphQL-API zu implementieren, müssen Sie die folgenden Schritte durchführen:
- Beschreiben Sie Ihre Daten mithilfe eines Schemas
- Verbindung von Resolvern mit Datenquellen
- Abfragen und Mutationen schreiben
- Vorhersehbare Ergebnisse erzielen
Durch den Einsatz von Back4app oder einem ähnlichen Dienst wird ein Großteil dieser Arbeit abstrahiert. Während Sie die Datenbankmodelle erstellen, generiert Back4app automatisch das GraphQL-Schema und die Dokumentation. Mehr dazu im praktischen Teil des Tutorials.
Was sind die Vorteile von GraphQL?
GraphQL ist leicht zu erlernen, Benutzer können Daten aus verschiedenen Quellen zusammenfassen und es ist eine moderne Sprache für Ihre API.
Schema
Die GraphQL-API basiert auf einem stark typisierten Schema. Dadurch lassen sich Typfehler und Bugs bereits bei der Kompilierung und nicht erst während der Laufzeit erkennen. Darüber hinaus sind GraphQL-APIs introspektiv, d. h. sie können Informationen über sich selbst bereitstellen, ohne auf eine externe Dokumentation angewiesen zu sein.
Flexibler und effizienter Datenabruf
GraphQL-APIs sind äußerst flexibel, da sie es den Kunden ermöglichen, genau anzugeben, was sie benötigen. Dies löst das Problem der Unter- und Überabrufe und reduziert die Anzahl der API-Anfragen. Weniger API-Anfragen führen zu einer besseren Leistung.
API-Aktualisierungen
Mit GraphQL können Sie neue Felder und Typen nahtlos integrieren, ohne dass dies Auswirkungen auf aktuelle Abfragen hat. Veraltete und veraltete Felder können auch vor Tools verborgen werden. GraphQL-APIs bieten Anwendungen ständigen Zugang zu neuen Funktionen und fördern die Entwicklung von sauberem, nachhaltigem Servercode.
Eine einzige Quelle der Wahrheit
Ein GraphQL-Schema stellt eine einzige Quelle der Wahrheit in einer GraphQL-Anwendung dar. Es bietet einer Organisation eine einfache Möglichkeit, ihre gesamte API zu verwalten.
GraphQL-Erweiterungen
GraphQL wird von einer großen Gemeinschaft von GraphQL-Entwicklern unterstützt und wird mit vielen Open-Source-Erweiterungen geliefert. Die Erweiterungen vereinfachen einige der üblichen API-Aufgaben wie Paginierung, Caching, Leistungsüberwachung und so weiter.
Was sind die Nachteile von GraphQL?
Komplexität
GraphQL verlagert einen Großteil der Arbeit einer Datenabfrage auf die Serverseite, wodurch die Backends komplexer werden. Hinzu kommt, dass die Abfragesprache und die Schemadefinitionen im Vorfeld mehr Planung und Wartung erfordern können.
Lernkurve
GraphQL hat eine steilere Lernkurve als REST. Außerdem sind GraphQL-Entwickler in der Regel teurer und schwieriger zu finden als REST-Entwickler.
Fehlende Standardisierung
Einer der Hauptkritikpunkte an GraphQL ist der Mangel an Standardisierung bei der Implementierung. Für REST-APIs gibt es eine Reihe etablierter Grundsätze und bewährter Verfahren, während die GraphQL-Dokumentation nur einige allgemeine Tipps für die Implementierung enthält. Dies kann zu Inkonsistenzen und Verwirrung bei der Gestaltung und Verwendung von GraphQL-APIs führen.
Sicherheit
Das Tolle an GraphQL ist, dass die Clients genau das anfordern können, was sie brauchen, aber andererseits kann das auch ein potenzielles Sicherheitsrisiko darstellen. Es ist wichtig, die Benutzereingaben ordnungsgemäß zu validieren und zu bereinigen, um zu verhindern, dass bösartige Abfragen ausgeführt werden.
Wie erstellt man eine GraphQL API?
In diesem Abschnitt des Artikels geht es darum, wie man eine GraphQL-API mit Back4app erstellt und sich mit ihr von einem Next.js-Frontend aus verbindet.
Voraussetzungen
- Erfahrung mit JavaScript ES6
- Erfahrung mit React und Next.js
- Grundlegendes Verständnis von GraphQL
Was ist Back4app?
Back4app ist eine außergewöhnliche Backend-as-a-Service (BaaS)-Lösung, die auf einer Open-Source-Software aufbaut. Die Plattform bietet eine breite Palette von Funktionen, die den Benutzern eine einfachere und schnellere Entwicklung von Web- und Mobilanwendungen ermöglichen. Sie ermöglicht es Unternehmen, sich auf ihre Geschäftslogik zu konzentrieren, ohne sich um das Backend oder die zugrunde liegende Infrastruktur kümmern zu müssen.
Back4app verfügt über ein benutzerfreundliches Dashboard mit vielen Funktionen und eine Befehlszeilenschnittstelle (CLI). Es bietet auch Software Development Kits (SDKs) für verschiedene beliebte Tools wie Node.js, Flutter, React Native, Android, Angular, iOS und mehr.
Back4app verfolgt ein unkompliziertes Preismodell, das den Anforderungen jeder App gerecht wird. Sie bieten auch einen kostenlosen Plan (keine Kreditkarte erforderlich), der sich hervorragend zum Testen und Prototyping eignet.
Möchten Sie mehr über Back4app erfahren? Schauen Sie unter Warum Back4app benutzen?
Projekt-Einführung
Wir werden eine einfache Web-TODO-Anwendung erstellen. Die Anwendung wird aus zwei Teilen bestehen: dem Backend und dem Frontend. Das Backend wird über eine GraphQL-API betrieben und auf Back4app bereitgestellt. Das Frontend hingegen wird in TypeScript geschrieben und nutzt das Next.js Framework. Um das Frontend mit dem Backend zu verbinden, werden wir den Apollo Client verwenden.
Die endgültige Anwendung wird wie folgt aussehen:
Backend
Back4app App erstellen
Um mit den folgenden Schritten fortzufahren, müssen Sie ein Back4app-Konto haben. Wenn Sie bereits eines haben, melden Sie sich bitte an. Andernfalls können Sie sich gerne für ein kostenloses Konto anmelden.
Um Back4app nutzen zu können, müssen Sie zunächst eine App erstellen. Sobald Sie sich in Ihrem Dashboard angemeldet haben, können Sie eine Liste Ihrer aktuellen Apps sehen. Um eine neue App zu erstellen, klicken Sie auf “Build a new app”.
Da wir eine GraphQL-API erstellen, wählen Sie die Option “Backend as a Service” und geben Sie einen eindeutigen Namen für Ihre Anwendung an. Wählen Sie außerdem “NoSQL” als Datenbanktyp.
Warten Sie geduldig darauf, dass Back4app alles konfiguriert, was für Ihre Anwendung erforderlich ist, einschließlich Datenbank, Anwendungsschicht, Skalierung, Backups und Sicherheit.
Nachdem die Einrichtung abgeschlossen ist, werden Sie zum Dashboard Ihrer App weitergeleitet.
Definieren von Datenbankmodellen
Da wir eine einfache TODO-Anwendung erstellen, benötigen wir nur ein Datenbankmodell.
Um loszulegen, gehen Sie zu Ihrem Back4app-Dashboard und suchen Sie in der Seitenleiste die Option “Datenbank”. Wählen Sie dort “Klasse erstellen” und geben Sie ihr den Namen “Aufgabe”. Stellen Sie sicher, dass Sie “Public Read and Write Enabled” auswählen und klicken Sie dann auf “Create class & add columns”.
Fügen Sie die folgenden Spalten ein:
+-----------+------------------+---------------+----------+
| Data type | Name | Default value | Required |
+-----------+------------------+---------------+----------+
| String | name | <leave blank> | yes |
+-----------+------------------+---------------+----------+
| String | description | <leave blank> | no |
+-----------+------------------+---------------+----------+
| Boolean | isDone | false | no |
+-----------+------------------+---------------+----------+
Nachdem Sie Ihr Datenbankmodell erstellt haben, werden Sie feststellen, dass vier Datenbankspalten automatisch hinzugefügt worden sind:
objectId
ist der Primärschlüssel Ihres ObjektsupdatedAt
ist der Zeitstempel der letzten AktualisierungcreatedAt
ist der Zeitstempel der ErstellungACL
definiert die “Zugriffskontrollliste”.
Behalten Sie sie im Hinterkopf, da wir sie im weiteren Verlauf des Tutorials bei der Arbeit an GraphQL-Abfragen und -Mutationen benötigen werden.
Um sich mit dem Back4app-Dashboard vertraut zu machen, fügen Sie zwei Beispielaufgaben hinzu, z. B:
+-----------------+----------------------------------------+--------+
| name | description | isDone |
+-----------------+----------------------------------------+--------+
| GraphQL backend | Create a GraphQL backend via Back4app. | false |
+-----------------+----------------------------------------+--------+
| Learn GraphQL | Learn the basics of GraphQL. | true |
+-----------------+----------------------------------------+--------+
GraphQL API-Konsole
Mit der GraphQL-API-Konsole können wir GraphQL-Abfragen und -Mutationen testen, bevor wir sie in Code umsetzen. Um auf die Konsole zuzugreifen, wählen Sie “API” in der Seitenleiste und dann “Console > GraphQL”.
Die Konsole ist extrem einfach zu bedienen. Auf der linken Seite können wir unsere benutzerdefinierten Abfragen und Mutationen eingeben und die Ergebnisse werden dann auf der rechten Seite angezeigt.
Um zu überprüfen, ob alles funktioniert, führen Sie die folgende Abfrage aus:
query CheckHealth {
health
}
Sie sollten die folgende JSON-Antwort erhalten:
{
"data": {
"health": true
}
}
Eine der großartigen Eigenschaften von Back4app ist, dass es auf Parse basiert. Als wir unser Datenbankmodell erstellt haben, hat Parse automatisch GraphQL für uns konfiguriert. Dazu gehört die Erstellung eines GraphQL-Schemas, von Dokumenten und so weiter.
Versuchen wir, die Aufgaben und ihre Details aus der Datenbank aufzulisten:
query GetTasks {
tasks {
count
edges {
node {
id
name
description
isDone
}
}
}
}
Sie sollten eine ähnliche Antwort erhalten:
{
"data": {
"tasks": {
"count": 2,
"edges": [
{
"node": {
"id": "VGFzazpXQkJzSkRtV2xU",
"name": "GraphQL backend",
"description": "Create a GraphQL backend via Back4app.",
"isDone": false
}
},
{
"node": {
"id": "VGFzazpnM2lhNzdwUXBp",
"name": "Learn GraphQL",
"description": "Learn the basics of GraphQL.",
"isDone": true
}
}
]
}
}
}
Das Abrufen eines bestimmten Objekts, das Erstellen von Objekten, das Aktualisieren von Objekten usw. erfolgt auf ähnliche Weise. Ich werde jetzt nicht zu sehr ins Detail gehen, da ich diese Abfragen und Mutationen später im Tutorium erläutern werde. Außerdem werden diese Themen in den Back4app-Dokumenten gut behandelt:
- Erstellen eines Objekts
- Ein Objekt erhalten
- Objekte finden
- Aktualisieren eines Objekts
- Löschen eines Objekts
- Authentifizierung
Das war’s mit dem Backend-Teil. Im nächsten Abschnitt werden wir mit der Arbeit am Frontend beginnen.
Frontend
Nächste App erstellen
Der einfachste Weg, ein Next.js-Projekt zu booten, ist die Verwendung des Dienstprogramms create-next-app
. Öffnen Sie Ihr Terminal und führen Sie den folgenden Befehl aus:
$ yarn create next-app
√ What is your project named? ... back4app-graphql
√ Would you like to use TypeScript with this project? ... No
√ Would you like to use ESLint with this project? ... Yes
√ Would you like to use the `src/` directory with this project? ... No
√ Would you like to use the experimental `app/` directory with this project? ... No
√ What import alias would you like configured? ... @/*
Successfully created a Next.js app.
Als Nächstes starten Sie den Entwicklungsserver:
$ yarn dev
Navigieren Sie zu http://localhost:3000 und Sie sollten die standardmäßige Next.js Landing Page sehen.
ChakraUI
Um den UI/UX-Erstellungsprozess zu beschleunigen und zu vereinfachen, werden wir ChakraUI verwenden. Chakra UI ist eine einfache, modulare und zugängliche Komponentenbibliothek, die Ihnen alles bietet, was Sie zum Erstellen Ihrer React-Apps benötigen.
Falls Sie auf Probleme stoßen, lesen Sie bitte ChakraUI: Erste Schritte mit Next.js.
Zum Installieren führen Sie es aus:
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion
Als nächstes navigieren Sie zu Ihrer _pages/app.tsx und umhüllen Ihre App mit dem ChakraProvider
wie folgt:
// pages/_app.tsx
import "../styles/globals.css";
import type {AppProps} from "next/app";
import {ChakraProvider} from "@chakra-ui/react";
export const theme = extendTheme({});
function MyApp({ Component, pageProps }: AppProps) {
return (
<ChakraProvider theme={theme}>
<Component {...pageProps} />
</ChakraProvider>
);
}
export default MyApp;
Vergessen Sie nicht, den ChakraProvider
zu importieren:
import {ChakraProvider} from "@chakra-ui/provider";
Um zufällige Farbblitze zu vermeiden, müssen Sie das Farbmodus-Skript vor dem Inhalt laden. Dazu können Sie _document.js wie folgt verwenden:
// pages/_document.tsx
import {ColorModeScript} from "@chakra-ui/react";
import { Html, Head, Main, NextScript } from "next/document";
import {theme} from "@/pages/_app";
export default function Document() {
return (
<Html lang='en'>
<Head />
<body>
<ColorModeScript initialColorMode={theme.config.initialColorMode} />
<Main />
<NextScript />
</body>
</Html>
);
}
Großartig, Sie haben ChakraUI erfolgreich installiert.
Benutzeroberfläche
Lassen Sie uns nun die Benutzeroberfläche erstellen. Unsere Web-App wird die folgenden zwei Seiten haben:
/
zeigt die Liste der Aufgaben anerstellen/
zeigt das Formular zum Erstellen von Aufgaben an
Beginnen Sie damit, pages/index.tsx durch den folgenden Inhalt zu ersetzen:
// pages/index.tsx
import type {NextPage} from "next";
import {
Button, Card, CardBody, Container,
Heading, HStack, Stack, Text, VStack
} from "@chakra-ui/react";
import Link from "next/link";
let data = {
"tasks": {
"count": 2,
"edges": [
{
"node": {
"id": "VGFzazpXQkJzSkRtV2xU",
"name": "GraphQL backend",
"description": "Create a GraphQL backend via Back4app.",
"isDone": false
}
},
{
"node": {
"id": "VGFzazpnM2lhNzdwUXBp",
"name": "Learn GraphQL",
"description": "Learn the basics of GraphQL.",
"isDone": true
}
}
]
}
};
const ListPage: NextPage = () => {
const handleMarkAsDone = async (id: string, isDone: boolean) => {
console.log("TODO: mark task as done and refetch");
};
const handleDelete = async (id: string) => {
console.log("TODO: delete task and refetch");
};
return (
<>
<Container maxWidth="container.lg">
<HStack w="fill" justifyContent="space-between" mt={8} mb={4}>
<Heading as="h1" size="lg">back4app-graphql</Heading>
<Link href="/create">
<Button size="sm" colorScheme="blue">
Create task
</Button>
</Link>
</HStack>
<VStack spacing={4}>
{data.tasks.edges.map((edge) => {
let task = edge.node;
return (
<Card key={task.id} w="100%">
<CardBody>
<Stack direction="column">
<Heading as="h2" size="md">
{task.isDone ? "✔️" : "❌"}{" "}
{task.name}
</Heading>
<Text>
{task.description}
</Text>
<Stack direction="row" pt={2}>
<Button size="sm" colorScheme="blue" onClick={() => handleMarkAsDone(task.id, task.isDone)}>
Toggle done
</Button>
<Button size="sm" colorScheme="red" onClick={() => handleDelete(task.id)}>
Delete
</Button>
</Stack>
</Stack>
</CardBody>
</Card>
);
})}
</VStack>
</Container>
</>
);
};
export default ListPage;
- Für die Gestaltung der Benutzeroberfläche haben wir ChakraUI verwendet.
- Die Aufgaben werden derzeit aus dem statischen Array namens
data
geladen. - Wir werden später
handleMarkAsDone()
undhandleDelete()
verwenden, um GraphQL-API-Anfragen zu senden.
Erstellen Sie dann im Ordner pages eine Datei create.tsx mit folgendem Inhalt:
// pages/create.tsx
import type {NextPage} from "next";
import {
Button, Card, CardBody, CardHeader, Container, FormControl,
FormLabel, Heading, HStack, Input, Stack, Switch, Text
} from "@chakra-ui/react";
import Link from "next/link";
import {useState} from "react";
import {useRouter} from "next/router";
const CreatePage: NextPage = () => {
const router = useRouter();
const [name, setName] = useState("");
const [description, setDescription] = useState("");
const [isDone, setIsDone] = useState(false);
const [formError, setFormError] = useState("");
const handleSubmit = (event) => {
event.preventDefault();
if (!name || !description) {
setFormError("Please enter the title and the description.");
return;
}
console.log("TODO: call the GraphQL API and redirect");
};
return (
<>
<Container maxWidth="container.lg">
<HStack w="fill" justifyContent="space-between" mt={8} mb={4}>
<Heading as="h1" size="lg">back4app-graphql</Heading>
<Link href="/">
<Button size="sm" colorScheme="blue">
View list
</Button>
</Link>
</HStack>
<Card>
<CardHeader>
<Stack direction="column">
<Heading as="h2" size="md">Create task</Heading>
<Text>
Fill out the form and press "Create" to create a new task.
</Text>
</Stack>
</CardHeader>
<CardBody>
<form onSubmit={handleSubmit}>
<Stack direction="column">
{formError && <Text color="red.500" fontWeight="bold">{formError}</Text>}
<FormControl>
<FormLabel>Name</FormLabel>
<Input type="text" value={name} onChange={(event) => setName(event.target.value)}/>
</FormControl>
<FormControl>
<FormLabel>Description</FormLabel>
<Input type="text" value={description} onChange={(event) => setDescription(event.target.value)}/>
</FormControl>
<FormControl display="flex" alignItems="center">
<FormLabel mb="0">
Is done?
</FormLabel>
<Switch isChecked={isDone} onChange={() => setIsDone(!isDone)}/>
</FormControl>
<Button size="sm" colorScheme="blue" type="submit">Create task</Button>
</Stack>
</form>
</CardBody>
</Card>
</Container>
</>
);
};
export default CreatePage;
- Wir haben wieder ChakraUI-Komponenten verwendet, um die Benutzeroberfläche zu erstellen.
- Wir haben ein React-gesteuertes Formular für die Erstellung von Aufgaben erstellt.
- Die Funktion
handleSubmit()
wird später zum Senden einer API-Anfrage verwendet.
Starten Sie Ihren Webserver neu und besuchen Sie Ihre Webanwendung unter http://localhost:3000. Sie sollten die beiden fest kodierten Aufgaben sehen. Klicken Sie anschließend auf “Aufgabe erstellen”, um das Formular zur Aufgabenerstellung anzuzeigen.
GraphQL-Klient
Um eine Verbindung zu einer GraphQL-API vom Frontend aus herzustellen, müssen Sie zunächst einen GraphQL-Client installieren. Ich empfehle Ihnen den Apollo Client, da er einfach einzurichten ist, nicht rechthaberisch ist und nicht viel Boilerplate benötigt.
Beginnen Sie mit der Installation von @apollo/client
und graphql
:
$ yarn add @apollo/client graphql
Um den Client zu initialisieren, müssen Sie Ihre Back4app-API-Anmeldedaten angeben. Am einfachsten erhalten Sie Ihre Anmeldedaten, indem Sie zu Ihrer GraphQL-Konsole navigieren und sich die Header notieren.
Da Sie Ihre API-Schlüssel nicht im Quellcode offenlegen wollen, erstellen Sie eine .env.local-Datei im Stammverzeichnis des Projekts mit folgendem Inhalt:
# .env.local
NEXT_PUBLIC_PARSE_APPLICATION_ID=<YOUR_PARSE_APP_ID>
NEXT_PUBLIC_PARSE_MASTER_KEY=<YOUR_PARSE_MASTER_KEY>
NEXT_PUBLIC_PARSE_CLIENT_KEY=<YOUR_PARSE_CLIENT_KEY>
Als Nächstes navigieren Sie zu pages/_app.tsx und initialisieren den Apollo-Client, dann verpacken Sie Ihre Anwendung mit dem ApolloProvider
wie folgt:
// pages/_app.tsx
// ...
import {ApolloClient, ApolloProvider, InMemoryCache} from "@apollo/client";
const client = new ApolloClient({
uri: "https://parseapi.back4app.com/graphql",
headers: {
"X-Parse-Application-Id": process.env.NEXT_PUBLIC_PARSE_APPLICATION_ID,
"X-Parse-Master-Key": process.env.NEXT_PUBLIC_PARSE_MASTER_KEY,
"X-Parse-Client-Key": process.env.NEXT_PUBLIC_PARSE_CLIENT_KEY,
},
cache: new InMemoryCache(),
});
function MyApp({ Component, pageProps }: AppProps) {
return (
<ChakraProvider theme={theme}>
<ApolloProvider client={client}>
<Component {...pageProps} />
</ApolloProvider>
</ChakraProvider>
);
}
Warten Sie, bis Ihr Frontend neu kompiliert ist, besuchen Sie dann Ihre Webanwendung und überprüfen Sie die Konsole auf Fehler. Keine Fehler bedeuten, dass die Verbindung erfolgreich war.
GraphQL-Abfragen und Mutationen
Als Letztes müssen Sie Ihre GraphQL-Abfragen und -Mutationen definieren und sie dann von Ihrem React-Code aus aufrufen.
Um die GraphQL-Codeunterstützung in Ihrer IDE zu aktivieren, navigieren Sie zur Back4app GraphQL Console, wählen Sie “Schema” in der Seitenleiste und laden Sie es als SDL herunter. Erstellen Sie dann eine neue Datei namens schema.graphql im Stammverzeichnis des Projekts und fügen Sie den SDL Inhalt ein.
Navigieren Sie zunächst zu pages/index.tsx und fügen Sie die folgenden Abfragen nach den Importen hinzu:
// pages/index.tsx
const GET_TASKS = gql`
query GetTasks {
tasks {
count
edges {
node {
id
name
description
isDone
}
}
}
}
`;
const UPDATE_TASK = gql`
mutation UpdateTask($id: ID!, $isDone: Boolean!) {
updateTask(input: { id: $id, fields: { isDone: $isDone } }) {
task {
isDone
updatedAt
}
}
}
`;
const DELETE_TASK = gql`
mutation DeleteTask($id: ID!) {
deleteTask(input: { id: $id }) {
task {
id
}
}
}
`;
Diese drei Abfragen sind ziemlich selbsterklärend. Die erste gibt eine Liste aller Aufgaben zurück, die zweite aktualisiert die Eigenschaft "isDone"
einer bestimmten Aufgabe, und die dritte löscht eine bestimmte Aufgabe.
Als nächstes ändern Sie den oberen Teil der ListPage
wie folgt:
// pages_index.tsx
// ...
const ListPage: NextPage = () => {
const {loading, error, data, refetch} = useQuery(GET_TASKS);
const [deleteTask] = useMutation(DELETE_TASK);
const [updateTask] = useMutation(UPDATE_TASK);
const handleMarkAsDone = async (id: string, isDone: boolean) => {
try {
const updateTaskResponse = await updateTask({
variables: {id: id, isDone: !isDone}
});
console.debug(updateTaskResponse);
refetch();
} catch (error) {
console.error(error);
}
};
const handleDelete = async (id: string) => {
try {
const deleteTaskResponse = await deleteTask({
variables: {id: id},
});
console.debug(deleteTaskResponse);
refetch();
} catch (error) {
console.error(error);
}
};
if (error) return <p>Oops, something went wrong.</p>;
if (loading) return <Spinner/>;
// ...
};
export default ListPage;
- Wir haben
useQuery()
verwendet, um dieGET_TASKS-Abfrage
auszuführen und das Ergebnis zu speichern. - Wir haben
useMutation()
verwendet, um die GraphQL-Mutationen zu definieren. - Wir haben
handleMarkAsDone()
undhandleDelete()
aktualisiert, um die Mutationshaken zu nutzen.
Ändern Sie pages/create.tsx auf ähnliche Weise:
const CREATE_TASK = gql`
mutation CreateTask($name: String!, $description: String, $isDone: Boolean!) {
createTask(
input: {
fields: { name: $name, description: $description, isDone: $isDone }
}
) {
task {
id
}
}
}
`;
const CreatePage: NextPage = () => {
// ...
const [createTask] = useMutation(CREATE_TASK);
const handleSubmit = (event) => {
event.preventDefault();
if (!name || !description) {
setFormError("Please enter the title and the description.");
return;
}
createTask({
variables: {name: name, description: description, isDone: isDone}
}).then(response => {
router.push("/");
});
};
// ...
};
export default CreatePage;
Vergessen Sie nicht die Einfuhr:
import {gql, useMutation, useQuery} from "@apollo/client";
Gut, das war’s!
Starten Sie Ihren Entwicklungsserver neu und besuchen Sie Ihre Webanwendung. Prüfen Sie, ob Aufgaben aus der Datenbank geladen werden. Versuchen Sie, eine neue Aufgabe zu erstellen, sie als erledigt zu markieren und sie zu löschen.
Schlussfolgerung
Zusammenfassend lässt sich sagen, dass GraphQL aufgrund seiner flexiblen Abfragemöglichkeiten und des effizienten Datenabrufs eine gute Wahl für den Aufbau komplexer APIs ist. Obwohl es viele Vorteile gegenüber herkömmlichen REST-APIs hat, gibt es einige Nachteile, die Sie beim Start eines Projekts berücksichtigen sollten.
In diesem Artikel haben wir die Vor- und Nachteile von GraphQL besprochen, es mit REST-APIs verglichen und einige der wichtigsten GraphQL-Terminologie eingeführt. Sie sollten nun in der Lage sein, Ihre eigene einfache GraphQL-API auf Back4app zu erstellen und sich von einem JavaScript-Frontend aus mit ihr zu verbinden.
Sie können den endgültigen Quellcode aus dem GitHub-Repository herunterladen.
FAQ
Was ist GraphQL?
GraphQL ist eine Abfragesprache und eine serverseitige Laufzeitumgebung zur Entwicklung leistungsstarker und flexibler APIs.
Was sind die Hauptunterschiede zwischen REST und GraphQL?
REST ist ein standardisierter und einfacher Ansatz zur Erstellung von Webdiensten, während GraphQL flexiblere Abfragemöglichkeiten bietet und das Unter- oder Überabrufen von Daten vermeidet.
Welche Begriffe werden häufig in GraphQL verwendet?
– Schema ist eine Beschreibung der über eine GraphQL-API verfügbaren Daten.
– Resolver ist eine Funktion, die die Daten für ein bestimmtes Feld in einer GraphQL-Abfrage abruft.
– Query ist eine schreibgeschützte Anfrage für Daten aus einer GraphQL-API.
– Mutation ist eine Anfrage zur Veränderung von Daten in einer GraphQL-API.
– Subscription ist eine Anfrage für Echtzeit-Updates aus einer GraphQL-API.
Wie erstellt man eine GraphQL-API?
1. Erstellen Sie ein kostenloses Konto auf Back4app.
2. Entwerfen Sie die Datenbankmodelle.
3. Schreiben Sie Abfragen und Mutationen über die Back4app GraphQL API-Konsole.
4. Installieren Sie einen GraphQL-Client (z. B. Apollo oder Relay) in Ihrem Frontend-Projekt.
5. Initialisieren Sie den Client und verbinden Sie ihn mit der GraphQL-API.