GraphQL - Kurzanleitung
GraphQL ist eine Open-Source-serverseitige Technologie, die von Facebook entwickelt wurde, um RESTful-API-Aufrufe zu optimieren. Es ist eine Ausführungs-Engine und eine Datenabfragesprache. In diesem Kapitel werden die Vorteile der Verwendung von GraphQL erläutert.
Warum GraphQL?
RESTful APIs verfolgen einen klaren und gut strukturierten ressourcenorientierten Ansatz. Wenn die Daten jedoch komplexer werden, werden die Routen länger. Manchmal ist es nicht möglich, Daten mit einer einzigen Anforderung abzurufen. Hier bietet sich GraphQL an. GraphQL strukturiert Daten in Form eines Diagramms mit seiner leistungsstarken Abfragesyntax zum Durchlaufen, Abrufen und Ändern von Daten.
Im Folgenden sind die Vorteile der Verwendung der GraphQL-Abfragesprache aufgeführt:
Fragen Sie nach dem, was Sie wollen - und holen Sie es sich
Senden Sie eine GraphQL-Abfrage an Ihre API und erhalten Sie genau das, was Sie benötigen. GraphQL-Abfragen liefern immer vorhersehbare Ergebnisse. Anwendungen mit GraphQL sind schnell und stabil. Im Gegensatz zu Restful-Diensten können diese Anwendungen Daten einschränken, die vom Server abgerufen werden sollen.
Das folgende Beispiel hilft Ihnen dabei, dies besser zu verstehen -
Betrachten wir ein Geschäftsobjekt Student mit den Attributen id, firstName, lastName und collegeName . Angenommen, eine mobile Anwendung muss nur den Vornamen und die ID abrufen . Wenn wir einen REST-Endpunkt wie / api / v1 / students entwerfen , werden Daten für alle Felder eines Schülerobjekts abgerufen. Dies bedeutet, dass Daten vom RESTful-Service überabgerufen werden. Dieses Problem kann mit GraphQL gelöst werden.
Betrachten Sie die unten angegebene GraphQL-Abfrage -
{
students {
id
firstName
}
}
Dies gibt nur Werte für die Felder id und firstname zurück. Die Abfrage ruft keine Werte für andere Attribute des Schülerobjekts ab. Die Antwort der oben dargestellten Abfrage ist wie folgt:
{
"data": {
"students": [
{
"id": "S1001",
"firstName": "Mohtashim"
},
{
"id": "S1002",
"firstName": "Kannan"
}
]
}
}
Holen Sie sich viele Ressourcen in einer einzigen Anfrage
GraphQL-Abfragen helfen dabei, zugeordnete Geschäftsobjekte reibungslos abzurufen, während typische REST-APIs das Laden von mehreren URLs erfordern. GraphQL-APIs rufen alle Daten, die Ihre Anwendung benötigt, in einer einzigen Anforderung ab. Anwendungen, die GraphQL verwenden, können auch bei langsamen Mobilfunknetzverbindungen schnell sein.
Betrachten wir noch ein Geschäftsobjekt, das College, das die Attribute hat: Name und Standort. Das Geschäftsobjekt Student hat eine Zuordnungsbeziehung zum College-Objekt. Wenn wir eine REST-API verwenden, um die Details der Studenten und ihres Colleges abzurufen, werden wir am Ende zwei Anfragen an den Server stellen, z. B. / api / v1 / Studenten und / api / v1 / Colleges . Dies führt dazu, dass bei jeder Anforderung zu wenig Daten abgerufen werden. Daher müssen mobile Anwendungen mehrere Anrufe beim Server tätigen, um die gewünschten Daten abzurufen.
Die mobile Anwendung kann jedoch mithilfe von GraphQL Details für Student- und College-Objekte in einer einzigen Anforderung abrufen.
Das Folgende ist eine GraphQL-Abfrage zum Abrufen von Daten -
{
students{
id
firstName
lastName
college{
name
location
}
}
}
Die Ausgabe der obigen Abfrage enthält genau die Felder, die wir angefordert haben, wie unten gezeigt -
{
"data": {
"students": [
{
"id": "S1001",
"firstName": "Mohtashim",
"lastName": "Mohammad",
"college": {
"name": "CUSAT",
"location": "Kerala"
}
},
{
"id": "S1002",
"firstName": "Kannan",
"lastName": "Sudhakaran",
"college": {
"name": "AMU",
"location": "Uttar Pradesh"
}
},
{
"id": "S1003",
"firstName": "Kiran",
"lastName": "Panigrahi",
"college": {
"name": "AMU",
"location": "Uttar Pradesh"
}
}
]
}
}
Beschreiben Sie, was mit einem Typsystem möglich ist
GraphQL ist stark typisiert und die Abfragen basieren auf Feldern und den zugehörigen Datentypen. Wenn eine GraphQL-Abfrage nicht mit dem Typ übereinstimmt, geben Serveranwendungen eindeutige und hilfreiche Fehlermeldungen zurück. Dies hilft beim reibungslosen Debuggen und beim einfachen Erkennen von Fehlern durch Clientanwendungen. GraphQL bietet auch clientseitige Bibliotheken, mit deren Hilfe die explizite Datenkonvertierung und -analyse reduziert werden kann.
Ein Beispiel für die Datentypen Student und College finden Sie unten -
type Query {
students:[Student]
}
type Student {
id:ID!
firstName:String
lastName:String
fullName:String
college:College
}
type College {
id:ID!
name:String
location:String
rating:Float
students:[Student]
}
Bewegen Sie sich mit leistungsstarken Entwicklertools schneller
GraphQL bietet umfangreiche Entwicklertools zum Dokumentieren und Testen von Abfragen. GraphiQL ist ein hervorragendes Tool, das die Dokumentation der Abfrage und ihres Schemas generiert. Es bietet auch einen Abfrageeditor zum Testen von GraphQL-APIs und zur intelligenten Codevervollständigung beim Erstellen von Abfragen.
In diesem Kapitel erfahren Sie mehr über das Umgebungssetup für GraphQL. Um die Beispiele in diesem Tutorial auszuführen, benötigen Sie Folgendes:
Ein Computer unter Linux, MacOS oder Windows.
Ein Webbrowser, vorzugsweise die neueste Version von Google Chrome.
Eine neuere Version von Node.js wurde installiert. Die neueste LTS-Version wird empfohlen.
Visual Studio-Code mit installierter Erweiterung GraphQL für VSCode oder einem Code-Editor Ihrer Wahl.
So erstellen Sie einen GraphQL-Server mit Nodejs
Wir werden einen detaillierten schrittweisen Ansatz zum Erstellen eines GraphQL-Servers mit Nodejs durchlaufen, wie unten gezeigt -
Schritt 1 - Überprüfen Sie die Knoten- und Npm-Versionen
Überprüfen Sie nach der Installation von NodeJs die Version von Node und npm mit den folgenden Befehlen auf dem Terminal:
C:\Users\Admin>node -v
v8.11.3
C:\Users\Admin>npm -v
5.6.0
Schritt 2 - Erstellen Sie einen Projektordner und öffnen Sie ihn in VSCode
Der Stammordner des Projekts kann als Test-App bezeichnet werden.
Öffnen Sie den Ordner mit dem Visual Studio Code Editor, indem Sie die folgenden Anweisungen befolgen -
C:\Users\Admin>mkdir test-app
C:\Users\Admin>cd test-app
C:\Users\Admin\test-app>code.
Schritt 3 - Erstellen Sie package.json und installieren Sie die Abhängigkeiten
Erstellen Sie eine package.json-Datei, die alle Abhängigkeiten der GraphQL-Serveranwendung enthält.
{
"name": "hello-world-server",
"private": true,
"scripts": {
"start": "nodemon --ignore data/ server.js"
},
"dependencies": {
"apollo-server-express": "^1.4.0",
"body-parser": "^1.18.3",
"cors": "^2.8.4",
"express": "^4.16.3",
"graphql": "^0.13.2",
"graphql-tools": "^3.1.1"
},
"devDependencies": {
"nodemon": "1.17.1"
}
}
Installieren Sie die Abhängigkeiten mit dem folgenden Befehl:
C:\Users\Admin\test-app>npm install
Schritt 4 - Erstellen Sie eine Flatfile-Datenbank im Datenordner
In diesem Schritt verwenden wir Flatfiles zum Speichern und Abrufen von Daten. Erstellen Sie Ordnerdaten und fügen Sie zwei Dateien hinzustudents.json und colleges.json.
Es folgt die colleges.json Datei -
[
{
"id": "col-101",
"name": "AMU",
"location": "Uttar Pradesh",
"rating":5.0
},
{
"id": "col-102",
"name": "CUSAT",
"location": "Kerala",
"rating":4.5
}
]
Es folgt die students.json Datei -
[
{
"id": "S1001",
"firstName":"Mohtashim",
"lastName":"Mohammad",
"email": "[email protected]",
"password": "pass123",
"collegeId": "col-102"
},
{
"id": "S1002",
"email": "[email protected]",
"firstName":"Kannan",
"lastName":"Sudhakaran",
"password": "pass123",
"collegeId": "col-101"
},
{
"id": "S1003",
"email": "[email protected]",
"firstName":"Kiran",
"lastName":"Panigrahi",
"password": "pass123",
"collegeId": "col-101"
}
]
Schritt 5 - Erstellen Sie eine Datenzugriffsschicht
Wir müssen einen Datenspeicher erstellen, der den Inhalt des Datenordners lädt. In diesem Fall benötigen wir Sammlungsvariablen, Studenten und Hochschulen . Wann immer die Anwendung Daten benötigt, verwendet sie diese Erfassungsvariablen.
Erstellen Sie die Datei db.js mit im Projektordner wie folgt:
const { DataStore } = require('notarealdb');
const store = new DataStore('./data');
module.exports = {
students:store.collection('students'),
colleges:store.collection('colleges')
};
Schritt 6 - Schemadatei erstellen, schema.graphql
Erstellen Sie eine Schemadatei im aktuellen Projektordner und fügen Sie den folgenden Inhalt hinzu:
type Query {
test: String
}
Schritt 7 - Resolver-Datei erstellen, resolvers.js
Erstellen Sie eine Resolver-Datei im aktuellen Projektordner und fügen Sie den folgenden Inhalt hinzu:
const Query = {
test: () => 'Test Success, GraphQL server is up & running !!'
}
module.exports = {Query}
Schritt 8 - Erstellen Sie Server.js und konfigurieren Sie GraphQL
Erstellen Sie eine Serverdatei und konfigurieren Sie GraphQL wie folgt:
const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const db = require('./db');
const port = process.env.PORT || 9000;
const app = express();
const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
const resolvers = require('./resolvers')
const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})
app.use(cors(), bodyParser.json());
const {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))
app.listen(
port, () => console.info(
`Server started on port ${port}`
)
);
Schritt 9 - Führen Sie die Anwendung aus und testen Sie sie mit GraphiQL
Überprüfen Sie die Ordnerstruktur der Projekttest-App wie folgt:
test-app /
-->package.json
-->db.js
-->data
students.json
colleges.json
-->resolvers.js
-->schema.graphql
-->server.js
Führen Sie den Befehl npm start wie unten angegeben aus -
C:\Users\Admin\test-app>npm start
Der Server läuft im 9000-Port, sodass wir die Anwendung mit dem GraphiQL-Tool testen können. Öffnen Sie den Browser und geben Sie die URL http: // localhost: 9000 / graphiql ein. Geben Sie die folgende Abfrage in den Editor ein -
{
Test
}
Die Antwort vom Server ist unten angegeben -
{
"data": {
"test": "Test Success, GraphQL server is running !!"
}
}
GraphQL ist eine Spezifikation, die das Verhalten eines GraphQL-Servers beschreibt. Es handelt sich um eine Reihe von Richtlinien, wie Anforderungen und Antworten wie unterstützte Protokolle behandelt werden sollen, Format der Daten, die vom Server akzeptiert werden können, Format der vom Server zurückgegebenen Antwort usw. Die Anforderung eines Clients an GraphQL Server wird als Abfrage bezeichnet. Ein weiteres wichtiges Konzept von GraphQL ist die Transportschicht-Agnostik. Es kann mit jedem verfügbaren Netzwerkprotokoll wie TCP, Websocket oder jedem anderen Transportschichtprotokoll verwendet werden. Es ist auch für Datenbanken neutral, sodass Sie es mit relationalen oder NoSQL-Datenbanken verwenden können.
GraphQL Server kann mit einer der drei unten aufgeführten Methoden bereitgestellt werden:
- GraphQL-Server mit verbundener Datenbank
- GraphQL-Server, der vorhandene Systeme integriert
- Hybrider Ansatz
GraphQL Server mit verbundener Datenbank
Diese Architektur verfügt über einen GraphQL Server mit einer integrierten Datenbank und kann häufig mit neuen Projekten verwendet werden. Beim Empfang einer Abfrage liest der Server die Anforderungsnutzdaten und ruft Daten aus der Datenbank ab. Dies wird als Auflösen der Abfrage bezeichnet. Die an den Client zurückgegebene Antwort entspricht dem in der offiziellen GraphQL-Spezifikation angegebenen Format.
Im obigen Diagramm sind der GraphQL-Server und die Datenbank auf einem einzelnen Knoten integriert. Der Client (Desktop / Mobile) kommuniziert über HTTP mit dem GraphQL-Server. Der Server verarbeitet die Anforderung, ruft Daten aus der Datenbank ab und gibt sie an den Client zurück.
GraphQL Server Integration bestehender Systeme
Dieser Ansatz ist hilfreich für Unternehmen mit Legacy-Infrastruktur und verschiedenen APIs. Mit GraphQL können Microservices, Legacy-Infrastrukturen und APIs von Drittanbietern im vorhandenen System vereinheitlicht werden.
Im obigen Diagramm fungiert eine GraphQL-API als Schnittstelle zwischen dem Client und den vorhandenen Systemen. Clientanwendungen kommunizieren mit dem GraphQL-Server, wodurch die Abfrage aufgelöst wird.
Hybridansatz
Schließlich können wir die beiden oben genannten Ansätze kombinieren und einen GraphQL-Server erstellen. In dieser Architektur löst der GraphQL-Server alle empfangenen Anforderungen auf. Es werden entweder Daten aus der verbundenen Datenbank oder von den integrierten APIs abgerufen. Dies ist in der folgenden Abbildung dargestellt -
In diesem Kapitel werden verschiedene GraphQL-Komponenten und ihre Kommunikation miteinander erläutert. Die gesamten Anwendungskomponenten können wie folgt unterschieden werden:
- Serverseitige Komponenten
- Clientseitige Komponenten
Serverseitige Komponenten
Der GraphQL-Server bildet die Kernkomponente auf der Serverseite und ermöglicht das Parsen der Abfragen, die von GraphQL-Clientanwendungen stammen. Apollo Server ist die am häufigsten verwendete Implementierung der GraphQL-Spezifikation. Andere Server-Programmierkomponenten umfassen Folgendes:
Sr.Nr. | Server Essentials & Beschreibung |
---|---|
1 | Schema Ein GraphQL-Schema steht im Mittelpunkt jeder GraphQL-Server-Implementierung und beschreibt die Funktionen, die den Clients zur Verfügung stehen, die eine Verbindung zu ihm herstellen. |
2 | Query Eine GraphQL-Abfrage ist die Clientanwendungsanforderung zum Abrufen von Daten aus Datenbank- oder Legacy-APIs. |
3 | Resolver Resolver enthalten Anweisungen zum Umwandeln einer GraphQL-Operation in Daten. Sie lösen die Abfrage in Daten auf, indem sie Resolverfunktionen definieren. |
Clientseitige Komponenten
Nachfolgend sind die clientseitigen Komponenten aufgeführt -
Sr.Nr. | Werkzeug & Beschreibung |
---|---|
1 | GraphiQL Browserbasierte Oberfläche zum Bearbeiten und Testen von GraphQL-Abfragen und -Mutationen. |
2 | ApolloClient Bestes Tool zum Erstellen von GraphQL-Client-Anwendungen. Lässt sich gut in alle Javascript-Frontends integrieren. |
Das folgende Diagramm zeigt a Client-Server architecture. Der Webserver basiert auf NodeJs und Express Framework. Eine Anfrage an den Apollo GraphQL Server wird von der ReactJS-Anwendung (erstellt mit der Apollo Client-Bibliothek) oder der GraphiQL-Browseranwendung gestellt. Die Abfrage wird analysiert und anhand eines auf dem Server definierten Schemas überprüft. Wenn das Anforderungsschema die Validierung besteht, werden die zugehörigen Resolverfunktionen ausgeführt. Der Resolver enthält Code zum Abrufen von Daten von einer API oder einer Datenbank.
In diesem Kapitel erstellen wir eine einfache API, die eine Begrüßungsnachricht, HelloWorld, zurückgibt und mit GraphiQL darauf zugreift.
Beispiel
Dieses Beispiel basiert auf NodeJS-, Express- und Apollo-Servern. Wir werden lernen, alle Konzepte mit den folgenden Schritten zusammenzufügen:
Schritt 1 - Express einrichten
ExpressJS ist ein Webanwendungsframework, mit dem Websites und Webanwendungen erstellt werden können. In diesem Beispiel erstellen wir eine GraphQL-API auf dem Express-Framework.
Der nächste Schritt besteht darin, einen Ordner zu erstellen hello-world-serverund navigieren Sie vom Terminal zum selben Ordner. Fügen Sie package.json hinzu und geben Sie dem Paket einen Namen. Da dieses Paket nur intern verwendet wird, können wir es als privat deklarieren.
{
"name":"hello-world-server",
"private":true
}
Installieren Sie die Abhängigkeiten für den Express-Server wie unten gezeigt -
C:\Users\Admin\hello-world-server>npm install express body-parser cors
body-parser ist ein Middleware-Paket, mit dem Express HTTP-Post-Anforderungen effizient bearbeiten kann. cors ist ein weiteres Middleware-Paket, das die gemeinsame Nutzung von Ressourcen zwischen verschiedenen Ursprüngen übernimmt.
Ein ... kreieren server.js Datei im Projektordner und geben Sie Folgendes ein -
const bodyParser = require('body-parser')
const cors = require('cors')
const express = require('express')
const port = process.env.PORT|| 9000
const app = express()
//register middleware
app.use(bodyParser.json() , cors())
app.listen(port, () => console.log(`server is up and running at ${port}`)
Führen Sie den folgenden Code im Terminalfenster aus, um zu überprüfen, ob der Express-Server betriebsbereit ist:
C:\Users\Admin\hello-world-server>node server.js
Die folgende Ausgabe wird in der Serverkonsole angezeigt. Dies zeigt, dass der Express-Server auf Port 9000 ausgeführt wird.
server is up and running at 9000
Wenn Sie den Browser öffnen und eingeben http://localhost:9000erhalten Sie den folgenden Bildschirm -
Drücken Sie, um den Server zu stoppen Ctrl + C.
Schritt 2 - Installieren Sie GraphQL und Apollo Server
Nachdem Express konfiguriert wurde, müssen Sie im nächsten Schritt die folgenden GraphQL-Abhängigkeiten herunterladen:
- graphql
- graphql-tools
- apollo-server-express@1
Wir werden Apollo Server v1.0 verwenden, da es sich um eine stabile Version handelt. Geben Sie die folgenden Befehle ein, um diese Abhängigkeiten zu installieren:
C:\Users\Admin\hello-world-server>npm install graphql graphql-tools apollo-server-express@1
Wir können überprüfen, ob diese Abhängigkeiten erfolgreich installiert wurden, indem wir das überprüfen package.json Datei, die wir zuvor erstellt haben.
{
"name": "hello-world-server",
"private": true,
"dependencies": {
"apollo-server-express": "^1.4.0",
"body-parser": "^1.18.3",
"cors": "^2.8.4",
"express": "^4.16.3",
"graphql": "^0.13.2",
"graphql-tools": "^3.1.1"
}
}
Schritt 3 - Definieren Sie das Schema
Ein GraphQL-Schema definiert, welche Art von Objekt von einem Dienst abgerufen werden kann und welche Felder es hat. Das Schema kann mit definiert werdenGraphQL Schema Definition Language. Fügen Sie nun das folgende Code-Snippet in das Feld einserver.js Datei -
// Adding Type Definitions
const typeDefinition = `
type Query {
greeting: String
}
Hier enthält die Abfrage ein Begrüßungsattribut , das einen Zeichenfolgenwert zurückgibt .
Schritt 4 - Erstellen Sie einen Resolver
Der erste Schritt beim Erstellen eines Resolvers besteht darin, Code hinzuzufügen, um das Anforderungsanforderungsfeld zu verarbeiten. Dies ist in a angegebenresolver. Die Struktur der Resolverfunktion muss mit dem Schema übereinstimmen. Fügen Sie das folgende Code-Snippet in das Feld einserver.js Datei.
// Adding resolver
const resolverObject = {
Query : {
greeting: () => 'Hello GraphQL From TutorialsPoint !!'
}
}
Der zweite Schritt besteht darin, das Schema und den Resolver mit zu binden makeExecutableSchema. Diese Funktion ist im Modul graphql-tools vordefiniert. Fügen Sie das folgende Code-Snippet in das Feld ein server.js Datei.
const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs:typeDefinition, resolvers:resolverObject})
Schritt 5 - Definieren Sie Routen zum Abrufen von Daten aus der ReactJS / GraphiQL-Anwendung
Fügen Sie das folgende Code-Snippet in das Feld ein server.js Datei -
const {graphqlExpress, graphiqlExpress} = require('apollo-server-express')
//create routes for graphql and graphiql
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))
Die Funktion graphqlExpress hilft beim Registrieren der Routehttp://localhost:9000/graphql. Die ReactJS-Anwendung kann diesen Endpunkt zum Abfragen von Daten verwenden. Ebenso hilft die graphqliExpress- Funktion beim Registrieren der Routehttp://localhost:9000/graphiql. Dies wird vom GraphiQL-Browser-Client zum Testen der API verwendet.
Der vollständige server.js-Code lautet wie folgt:
const bodyParser = require('body-parser')
const cors = require('cors')
const express = require('express')
const port = process.env.PORT||9000
const app = express()
app.use(bodyParser.json() , cors())
const typeDefinition = `
type Query {
greeting: String
}`
const resolverObject = {
Query : {
greeting: () => 'Hello GraphQL From TutorialsPoint !!'
}
}
const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs:typeDefinition, resolvers:resolverObject})
const {graphqlExpress,graphiqlExpress} = require('apollo-server-express')
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))
app.listen(port, () => console.log(`server is up and running ${port}`))
Schritt 6 - Starten Sie die Anwendung
Ausführen server.js mit Node.js wie folgt -
C:\Users\Admin\hello-world-server>node server.js
Schritt 7 - Testen Sie die GraphQL-API
Öffnen Sie den Browser und geben Sie ein http://localhost:9000/graphiql. Geben Sie auf der Registerkarte "Abfrage" von GraphiQL Folgendes ein:
{
greeting
}
Die Antwort vom Server ist unten angegeben -
{
"data": {
"greeting": "Hello GraphQL From TutorialsPoint !!"
}
}
Das folgende Bild zeigt die Antwort -
Note - Stellen Sie sicher, dass Apollo Server Version 1.0 verwendet wird.
GraphQL ist eine stark typisierte Sprache. Das Typsystem definiert verschiedene Datentypen, die in einer GraphQL-Anwendung verwendet werden können. Das Typsystem hilft bei der Definition des Schemas, bei dem es sich um einen Vertrag zwischen Client und Server handelt. Die häufig verwendeten GraphQL-Datentypen sind wie folgt:
Sr.Nr. | Typen & Beschreibung |
---|---|
1 | Scalar Speichert einen einzelnen Wert |
2 | Object Zeigt an, welche Art von Objekt abgerufen werden kann |
3 | Query Einstiegspunkttyp zu anderen spezifischen Typen |
4 | Mutation Einstiegspunkt für die Datenmanipulation |
5 | Enum Nützlich in Situationen, in denen der Benutzer aus einer vorgeschriebenen Liste von Optionen auswählen muss |
Skalartyp
Skalartypen sind primitive Datentypen, die nur einen einzigen Wert speichern können. Die von GraphQL angebotenen Standard-Skalartypen sind:
Int - Signierte 32-Bit-Ganzzahl
Float - Vorzeichenbehafteter Gleitkommawert mit doppelter Genauigkeit
String - UTF - 8-stellige Sequenz
Boolean - Richtig oder falsch
ID - Eine eindeutige Kennung, die häufig als eindeutige Kennung zum Abrufen eines Objekts oder als Schlüssel für einen Cache verwendet wird.
Die Syntax zum Definieren eines Skalartyps lautet wie folgt:
field: data_type
Das unten angegebene Snippet definiert ein Feld mit dem Namen greeting, das den String-Wert zurückgibt.
greeting: String
Objekttyp
Der Objekttyp ist der am häufigsten in einem Schema verwendete Typ und repräsentiert eine Gruppe von Feldern. Jedes Feld innerhalb eines Objekttyps wird einem anderen Typ zugeordnet, wodurch verschachtelte Typen zugelassen werden. Mit anderen Worten, ein Objekttyp besteht aus mehreren Skalartypen oder Objekttypen.
Die Syntax zum Definieren eines Objekttyps ist unten angegeben -
type object_type_name
{
field1: data_type
field2:data_type
....
fieldn:data_type
}
Sie können das folgende Code-Snippet betrachten -
--Define an object type--
type Student {
stud_id:ID
firstname: String
age: Int
score:Float
}
--Defining a GraphQL schema--
type Query
{
stud_details:[Student]
}
Das oben angegebene Beispiel definiert einen Objektdatentyp Student. Das Feld stud_details im Stammabfrageschema gibt eine Liste der Student-Objekte zurück.
Abfragetyp
Eine GraphQL-Abfrage wird zum Abrufen von Daten verwendet. Es ist wie das Anfordern einer Ressource in REST-basierten APIs. Zur Vereinfachung ist der Abfragetyp die Anforderung, die von einer Clientanwendung an den GraphQL-Server gesendet wird. GraphQL verwendet dieSchema Definition Language (SDL)eine Abfrage definieren. Der Abfragetyp ist einer der vielen Stammtypen in GraphQL.
Die Syntax zum Definieren einer Abfrage lautet wie folgt:
type Query {
field1: data_type
field2:data_type
field2(param1:data_type,param2:data_type,...paramN:data_type):data_type
}
Ein Beispiel für die Definition einer Abfrage -
type Query {
greeting: String
}
Mutationstyp
Mutationen sind Operationen, die an den Server gesendet werden create, update oder deleteDaten. Diese sind analog zu den Verben PUT, POST, PATCH und DELETE, um REST-basierte APIs aufzurufen.
Mutation ist einer der Datentypen auf Stammebene in GraphQL. Der Abfragetyp definiert die Einstiegspunkte für Datenabrufoperationen, während der Mutationstyp die Einstiegspunkte für Datenmanipulationsoperationen angibt.
Die Syntax zum Definieren eines Mutationstyps ist unten angegeben -
type Mutation {
field1: data_type
field2(param1:data_type,param2:data_type,...paramN:data_type):data_type
}
Zum Beispiel können wir einen Mutationstyp definieren, um einen neuen Schüler wie folgt hinzuzufügen:
type Mutation {
addStudent(firstName: String, lastName: String): Student
}
Aufzählungstyp
Eine Aufzählung ähnelt einem Skalartyp. Aufzählungen sind in Situationen nützlich, in denen der Wert für ein Feld aus einer vorgeschriebenen Liste von Optionen stammen muss.
Die Syntax zum Definieren eines Aufzählungstyps lautet -
type enum_name{
value1
value2
}
Das folgende Snippet zeigt, wie ein Aufzählungstyp definiert werden kann:
type Days_of_Week{
SUNDAY
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
}
Listentyp
Listen können verwendet werden, um ein Array von Werten eines bestimmten Typs darzustellen. Listen werden mit einem Typmodifikator [] definiert, der Objekttypen, Skalare und Aufzählungen umschließt.
Die folgende Syntax kann verwendet werden, um einen Listentyp zu definieren:
field:[data_type]
Das folgende Beispiel definiert einen Listentyp todos -
type Query {
todos: [String]
}
Nicht nullbarer Typ
Standardmäßig kann jeder der Kernskalartypen auf Null gesetzt werden. Mit anderen Worten, diese Typen können entweder einen Wert des angegebenen Typs zurückgeben oder sie können keinen Wert haben. Um diese Standardeinstellung zu überschreiben und anzugeben, dass ein Feld definiert werden muss, kann ein Ausrufezeichen (!) An einen Typ angehängt werden. Dadurch wird sichergestellt, dass in den von der Abfrage zurückgegebenen Ergebnissen ein Wert vorhanden ist.
Die folgende Syntax kann verwendet werden, um ein nicht nullbares Feld zu definieren:
field:data_type!
Im folgenden Beispiel wird stud_id als Pflichtfeld deklariert.
type Student {
stud_id:ID!
firstName:String
lastName:String
fullName:String
college:College
}
Ein GraphQL-Schema ist der Kern jeder GraphQL-Server-Implementierung. Es beschreibt die Funktionen, die den Clientanwendungen zur Verfügung stehen, die eine Verbindung herstellen. Wir können jede Programmiersprache verwenden, um ein GraphQL-Schema zu erstellen und eine Schnittstelle darum herum zu erstellen.
Die GraphQL-Laufzeit definiert ein generisches graphbasiertes Schema, um die Funktionen des Datendienstes zu veröffentlichen, den es darstellt. Clientanwendungen können das Schema innerhalb seiner Funktionen abfragen. Dieser Ansatz entkoppelt Clients von Servern und ermöglicht die unabhängige Entwicklung und Skalierung.
In diesem Kapitel verwenden wir den Apollo-Server, um GraphQL-Abfragen auszuführen. DasmakeExecutableSchema Die Funktion in graphql-tools hilft Ihnen beim Binden von Schema und Resolvern.
makeExecutableSchema Funktionssyntax
Das makeExecutableSchemaDie Funktion verwendet ein einzelnes Argument {} vom Objekttyp. Die Syntax für die Verwendung dieser Funktion ist unten angegeben -
import { makeExecutableSchema } from 'graphql-tools';
const jsSchema = makeExecutableSchema({
typeDefs,
resolvers, // optional
logger, // optional
allowUndefinedInResolve = false, // optional
resolverValidationOptions = {}, // optional
directiveResolvers = null, // optional
schemaDirectives = null, // optional
parseOptions = {}, // optional
inheritResolversFromInterfaces = false // optional
});
Sr.Nr. | Parameter & Beschreibung |
---|---|
1 | typeDefs Dies ist ein erforderliches Argument. Es stellt eine GraphQL-Abfrage als UTF-8-Zeichenfolge dar. |
2 | Resolvers Dies ist ein optionales Argument (standardmäßig leeres Objekt). Dies hat Funktionen, die die Abfrage behandeln. |
3 | logger Dies ist ein optionales Argument und kann zum Drucken von Fehlern auf der Serverkonsole verwendet werden. |
4 | parseOptions Dies ist ein optionales Argument und ermöglicht die Anpassung der Analyse, wenn typeDefs als Zeichenfolge angegeben wird. |
5 | allowUndefinedInResolve Dies gilt standardmäßig. Wenn diese Option auf false gesetzt ist, lösen Ihre Auflösungsfunktionen Fehler aus, wenn sie undefiniert zurückgegeben werden. |
6 | resolverValidationOptions Dies ist ein optionales Argument und akzeptiert ein Objekt mit booleschen Eigenschaften. |
7 | inheritResolversFromInterfaces Dies ist ein optionales Argument und akzeptiert ein boolesches Argument zum Überprüfen der Resolver-Objektvererbung. |
Illustration
Lassen Sie uns eine einfache Anwendung erstellen, um dieses Schema zu verstehen. Dadurch wird ein Schema zum Abfragen der Liste der Schüler vom Server erstellt. Die Studentendaten werden in einer flachen Datei gespeichert und wir verwenden ein Knotenmodul namensnotarealdb eine Datenbank fälschen und aus der Flatfile lesen.
Schritt 1 - Laden Sie die erforderlichen Abhängigkeiten für das Projekt herunter und installieren Sie sie
Erstellen Sie einen Ordner mit dem Namen schema-app. Ändern Sie Ihr Verzeichnis vom Terminal in Schema-App. Befolgen Sie dann die Schritte 3 bis 5, die im Kapitel Umgebungs-Setup erläutert wurden, um den Download und den Installationsvorgang abzuschließen.
Schritt 2 - Erstellen Sie ein Schema
Hinzufügen schema.graphql Datei im Projektordner, schema-app und fügen Sie den folgenden Code hinzu -
type Query {
greeting:String
students:[Student]
}
type Student {
id:ID!
firstName:String
lastName:String
password:String
collegeId:String
}
Das Stammverzeichnis des Schemas ist der Abfragetyp. Die Abfrage enthält zwei Felder - Begrüßung und Schüler, die einen String bzw. eine Liste der Schüler zurückgeben. Student wird als Objekttyp deklariert, da er mehrere Felder enthält. Das ID-Feld wird als nicht nullwertfähig deklariert.
Schritt 3 - Resolver erstellen
Erstellen Sie eine Datei resolvers.js im Projektordner und fügen Sie den folgenden Code hinzu -
const db = require('./db')
const Query = {
greeting:() => {
return "hello from TutorialsPoint !!!"
},
students:() => db.students.list()
}
module.exports = {Query}
Hier sind Begrüßung und Schüler die Resolver, die die Abfrage bearbeiten. students resolver functionGibt eine Liste der Schüler aus der Datenzugriffsebene zurück. Um auf Resolver-Funktionen außerhalb des Moduls zugreifen zu können, muss das Abfrageobjekt mit exportiert werdenmodule.exports.
Schritt 4 - Führen Sie die Anwendung aus
Erstellen Sie eine server.js-Datei und lesen Sie Schritt 8 im Kapitel Umgebungs-Setup. Der nächste Schritt besteht darin, den Befehl npm start im Terminal auszuführen. Der Server ist am 9000-Port betriebsbereit. Hier verwenden wir GraphiQL als Client, um die Anwendung zu testen. Öffnen Sie den Browser und geben Sie die URL ein.http://localhost:9000/graphiql.
Geben Sie die folgende Abfrage in den Editor ein -
{
greeting
students {
id
firstName
lastName
}
}
Die Abfrage zeigt die Ausgabe wie unten gezeigt an -
Note- Wir können die Datei students.json durch einen RESTful-API-Aufruf ersetzen, um Schülerdaten oder sogar eine echte Datenbank wie MySQL oder MongoDB abzurufen. GraphQL wird zu einem dünnen Wrapper um Ihre ursprüngliche Anwendungsschicht, um die Leistung zu verbessern.
Resolver ist eine Sammlung von Funktionen, die eine Antwort auf eine GraphQL-Abfrage generieren. In einfachen Worten fungiert ein Resolver als GraphQL-Abfragehandler. Jede Resolver-Funktion in einem GraphQL-Schema akzeptiert vier Positionsargumente wie folgt:
fieldName:(root, args, context, info) => { result }
Ein Beispiel für Resolverfunktionen ist unten dargestellt -
//resolver function with no parameters and returning string
greeting:() => {
return "hello from TutorialsPoint !!!"
}
//resolver function with no parameters and returning list
students:() => db.students.list()
//resolver function with arguments and returning object
studentById:(root,args,context,info) => {
return db.students.get(args.id);
}
Nachstehend sind die Positionsargumente und ihre Beschreibung aufgeführt.
Sr.Nr. | Argumente & Beschreibung |
---|---|
1 | root Das Objekt, das das vom Resolver zurückgegebene Ergebnis im übergeordneten Feld enthält. |
2 | args Ein Objekt mit den Argumenten, die in der Abfrage an das Feld übergeben wurden. |
3 | context Dies ist ein Objekt, das von allen Resolvern in einer bestimmten Abfrage gemeinsam genutzt wird. |
4 | info Es enthält Informationen zum Ausführungsstatus der Abfrage, einschließlich des Feldnamens und des Pfads zum Feld vom Stammverzeichnis. |
Resolver-Ergebnisformat
Resolver in GraphQL können verschiedene Arten von Werten zurückgeben, wie unten angegeben -
Sr.Nr. | Argumente und Beschreibung |
---|---|
1 | null or undefined Dies zeigt an, dass das Objekt nicht gefunden wurde |
2 | array Dies ist nur gültig, wenn das Schema angibt, dass das Ergebnis eines Feldes eine Liste sein soll |
3 | promise Resolver führen häufig asynchrone Aktionen wie das Abrufen aus einer Datenbank oder einer Backend-API aus, damit sie Versprechen zurückgeben können |
4 | scalar or object Ein Resolver kann auch andere Werte zurückgeben |
Illustration
Lassen Sie uns eine einfache Anwendung erstellen, um den Resolver zu verstehen. Dadurch wird ein Schema zum Abfragen eines Schülers nach seiner ID vom Server erstellt. Die Studentendaten werden in einer flachen Datei gespeichert und wir verwenden ein Knotenmodul namensnotarealdb eine Datenbank fälschen und aus einer Flatfile lesen.
Das Folgende ist ein schrittweiser Prozess zum Erstellen einer einfachen Anwendung:
Schritt 1 - Laden Sie die erforderlichen Abhängigkeiten für das Projekt herunter und installieren Sie sie
Erstellen Sie einen Ordner mit dem Namen resolver-app. Ändern Sie Ihr Verzeichnis inresolver-appvom Terminal. Befolgen Sie später die Schritte 3 bis 5 im Kapitel Umgebungs-Setup.
Schritt 2 - Erstellen Sie ein Schema
Fügen Sie die Datei schema.graphql im Projektordner resolver-app hinzu und fügen Sie den folgenden Code hinzu:
type Query {
greeting:String
students:[Student]
studentById(id:ID!):Student
}
type Student {
id:ID!
firstName:String
lastName:String
password:String
collegeId:String
}
Die Schemadatei zeigt, dass der Benutzer nach Begrüßung, Schülern und studentById fragen kann . Um Schüler mit einer bestimmten ID abzurufen, verwenden wirdata type ID!Dies zeigt ein nicht nullbares eindeutiges Bezeichnerfeld. Das Schülerfeld gibt ein Array von Schülern zurück, und die Begrüßung gibt einen einfachen Zeichenfolgenwert zurück.
Schritt 3 - Resolver erstellen
Erstellen Sie eine Datei resolvers.js im Projektordner und fügen Sie den folgenden Code hinzu -
const db = require('./db')
const Query = {
//resolver function for greeting
greeting:() => {
return "hello from TutorialsPoint !!!"
},
//resolver function for students returns list
students:() => db.students.list(),
//resolver function for studentbyId
studentById:(root,args,context,info) => {
//args will contain parameter passed in query
return db.students.get(args.id);
}
}
module.exports = {Query}
Hier nimmt studentById drei Parameter auf. Wie in diesem Kapitel erläutert, kann die studentId aus args abgerufen werden. root enthält das Abfrageobjekt selbst. Um einen bestimmten Schüler zurückzugeben, müssen wir die get-Methode mit dem Parameter id in der Schülersammlung aufrufen.
Hier sind Begrüßung, Studenten, studentById die Resolver, die die Abfrage verarbeiten.students resolver functionGibt eine Liste der Schüler aus der Datenzugriffsebene zurück. Um auf Resolver-Funktionen außerhalb des Moduls zugreifen zu können, muss das Abfrageobjekt mit module.exports exportiert werden.
Schritt 4 - Führen Sie die Anwendung aus
Erstellen Sie eine server.js-Datei. Siehe Schritt 8 im Kapitel Umgebungs-Setup. Führen Sie den Befehl npm start im Terminal aus. Der Server ist am 9000-Port betriebsbereit. Hier verwenden wir GraphiQL als Client, um die Anwendung zu testen.
Öffnen Sie den Browser und geben Sie die URL ein. http://localhost:9000/graphiql. Geben Sie die folgende Abfrage in den Editor ein -
{
studentById(id:"S1001") {
id
firstName
lastName
}
}
Die Ausgabe für die obige Abfrage ist wie folgt:
{
"data": {
"studentById": {
"id": "S1001",
"firstName": "Mohtashim",
"lastName": "Mohammad"
}
}
}
Eine GraphQL-Operation kann entweder eine Lese- oder eine Schreiboperation sein. Eine GraphQL-Abfrage wird zum Lesen oder Abrufen von Werten verwendet, während eine Mutation zum Schreiben oder Veröffentlichen von Werten verwendet wird. In beiden Fällen handelt es sich bei der Operation um eine einfache Zeichenfolge, die ein GraphQL-Server analysieren und mit Daten in einem bestimmten Format beantworten kann. Das beliebte Antwortformat, das normalerweise für Mobil- und Webanwendungen verwendet wird, ist JSON.
Die Syntax zum Definieren einer Abfrage lautet wie folgt:
//syntax 1
query query_name{ someField }
//syntax 2
{ someField }
Das Folgende ist ein Beispiel für eine Abfrage -
//query with name myQuery
query myQuery{
greeting
}
// query without any name
{
greeting
}
Aus dem obigen Beispiel geht hervor, dass das Abfrage-Schlüsselwort optional ist.
GraphQL-Abfragen helfen dabei, das Abrufen von Daten zu reduzieren. Im Gegensatz zu einer Restful-API kann ein Benutzer mit GraphQL Felder einschränken, die vom Server abgerufen werden sollen. Dies bedeutet kleinere Abfragen und weniger Verkehr über das Netzwerk. Dies reduziert wiederum die Reaktionszeit.
Abbildung 1 - Schülermodell mit einem benutzerdefinierten Feld abfragen
In diesem Beispiel haben wir eine Reihe von Schülern in einer JSON-Datei gespeichert. Jedes Studentenmodell hat Felder wie Vorname, Nachname und ID, aber keinen vollständigen Namen. Hier werden wir diskutieren, wie eine Abfrage durchgeführt wird, um den vollständigen Namen aller Schüler abzurufen. Dazu müssen wir in beiden Schema-Resolvern das Feld fullName erstellen.
Lassen Sie uns sehen, wie diese Abbildung mit den folgenden Schritten erstellt wird:
Schritt 1 - Laden Sie die erforderlichen Abhängigkeiten für das Projekt herunter und installieren Sie sie
Erstellen Sie einen Ordner mit dem Namen query-app. Ändern Sie Ihr Verzeichnis inquery-appvom Terminal. Befolgen Sie später die Schritte 3 bis 5, die im Kapitel Umgebungs-Setup erläutert werden.
Schritt 2 - Erstellen Sie ein Schema
Hinzufügen schema.graphql Datei im Projektordner Abfrage-App und fügen Sie den folgenden Code hinzu -
type Query {
greeting:String
students:[Student]
studentById(id:ID!):Student
}
type Student {
id:ID!
firstName:String
lastName:String
fullName:String
}
Beachten Sie, dass das Feld fullName kein enthältstudents.jsonDatei. Wir müssen jedoch den vollständigen Namen des Schülers über eine Abfrage abrufen . Der vollständige Name ist in diesem Fall ein benutzerdefiniertes Feld, das mit der Datenquelle nicht verfügbar ist.
Schritt 3 - Resolver erstellen
Erstellen Sie eine Datei resolvers.js im Projektordner und fügen Sie den folgenden Code hinzu -
const db = require('./db')
const Query = {
//resolver function for greeting
greeting:() => {
return "hello from TutorialsPoint !!!"
},
//resolver function for students returns list
students:() => db.students.list(),
//resolver function for studentbyId
studentById:(root,args,context,info) => {
//args will contain parameter passed in query
return db.students.get(args.id);
}
}
//for each single student object returned,resolver is invoked
const Student = {
fullName:(root,args,context,info) => {
return root.firstName+":"+root.lastName
}
}
module.exports = {Query,Student}
Schritt 4 - Führen Sie die Anwendung aus
Ein ... kreieren server.jsDatei. Siehe Schritt 8 im Kapitel Umgebungs-Setup. Führen Sie den Befehl npm start im Terminal aus. Der Server ist am 9000-Port betriebsbereit. Hier verwenden wir GraphiQL als Client, um die Anwendung zu testen.
Öffnen Sie den Browser und geben Sie die URL ein http://localhost:9000/graphiql. Geben Sie die folgende Abfrage in den Editor ein -
{
students{
id
fullName
}
}
Die Antwort auf die Abfrage ist unten angegeben -
{
"data": {
"students": [
{
"id": "S1001",
"fullName": "Mohtashim:Mohammad"
},
{
"id": "S1002",
"fullName": "Kannan:Sudhakaran"
},
{
"id": "S1003",
"fullName": "Kiran:Panigrahi"
}
]
}
}
Ein ... kreieren server.js und fügen Sie den folgenden Code hinzu -
const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const db = require('./db');
const port = 9000;
const app = express();
//loading type definitions from schema file
const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
//loading resolvers
const resolvers = require('./resolvers')
//binding schema and resolver
const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})
//enabling cross domain calls and form post
app.use(cors(), bodyParser.json());
//enabling routes
const {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))
//registering port
app.listen(port, () => console.info(`Server started on port ${port}`));
Führen Sie den Befehl npm start im Terminal aus. Der Server ist am 9000-Port betriebsbereit. Hier verwenden wir GraphiQL als Client, um die Anwendung zu testen.
Öffnen Sie den Browser und geben Sie die URL ein http://localhost:9000/graphiql. Geben Sie die folgende Abfrage in den Editor ein -
{
students{
id
fullName
}
}
Die Antwort auf die Abfrage ist unten angegeben -
{
"data": {
"students": [
{
"id": "S1001",
"fullName": "Mohtashim:Mohammad"
},
{
"id": "S1002",
"fullName": "Kannan:Sudhakaran"
},
{
"id": "S1003",
"fullName": "Kiran:Panigrahi"
}
]
}
}
Abbildung 2 - Verschachtelte Abfrage
Lassen Sie uns eine verschachtelte Abfrage zum Abrufen der Studentendetails und ihrer College-Details erstellen. Wir werden mit demselben Projektordner arbeiten.
Schritt 1 - Bearbeiten Sie das Schema
Die Schemadatei enthält bereits das Schülerfeld . Fügen wir ein Feldkolleg hinzu und definieren seinen Typ.
type College {
id:ID!
name:String
location:String
rating:Float
}
type Student {
id:ID!
firstName:String
lastName:String
fullName:String
college:College
}
Schritt 2 - Ändern Sie die Datei resolver.js
Wir müssen eine College-Resolver-Funktion wie unten hinzufügen. Die College-Resolver-Funktion wird für jedes zurückgegebene Schülerobjekt ausgeführt. Der Root-Parameter von Resolver enthält in diesem Fall student .
const Student = {
fullName:(root,args,context,info) => {
return root.firstName+":"+root.lastName
},
college:(root) => {
return db.colleges.get(root.collegeId);
}
}
module.exports = {Query,Student}
Der Resolver gibt das College jedes Studenten zurück, indem er die Methode get der College-Sammlung aufruft und die College- ID übergibt . Wir haben eine Assoziationsbeziehung zwischen Student und College über die collegeId .
Schritt 3 - Testen Sie die Anwendung
Öffnen Sie das Terminalfenster und navigieren Sie zum Projektordner. Geben Sie den Befehl -npm start ein. Starten Sie den Browser und geben Sie die URL einhttp://localhost:9000/graphiql.
Geben Sie die folgende Abfrage in das GraphiQL-Fenster ein:
{
students{
id
firstName
college {
id
name
location
rating
}
}
}
Die Antwort auf die Abfrage lautet wie folgt:
{
"data": {
"students": [
{
"id": "S1001",
"firstName": "Mohtashim",
"college": {
"id": "col-102",
"name": "CUSAT",
"location": "Kerala",
"rating": 4.5
}
},
{
"id": "S1002",
"firstName": "Kannan",
"college": {
"id": "col-101",
"name": "AMU",
"location": "Uttar Pradesh",
"rating": 5
}
},
{
"id": "S1003",
"firstName": "Kiran",
"college": {
"id": "col-101",
"name": "AMU",
"location": "Uttar Pradesh",
"rating": 5
}
}
]
}
}
Was ist eine Abfragevariable?
Wenn für eine Abfrage einige dynamische Werte übergeben werden müssen, stellen Sie diese dynamischen Werte mithilfe von Variablen dar. Daher kann die Abfrage von den Clientanwendungen wiederverwendet werden.
Illustration
Lassen Sie uns eine einfache Anwendung erstellen, um die Abfragevariable zu verstehen.
Schritt 1 - Schemadatei bearbeiten
Fügen Sie ein sayHello- Feld hinzu, das einen Zeichenfolgenparameter verwendet und eine Zeichenfolge zurückgibt. Die Namenswerte sind in der Clientanwendung dynamisch.
type Query {
sayHello(name:String!):String
}
Schritt 2 - Bearbeiten Sie die Datei resolver.js
Fügen Sie einen sayHello- Resolver hinzu, der die folgenden Parameter verwendet -
sayHello:(root,args,context,info) => `Hi ${args.name} GraphQL server says Hello to you!!`
Schritt 3 - Deklarieren Sie die Abfragevariable in GraphiQL
Eine Variable wird mit $ deklariert, gefolgt vom Namen der Variablen. Zum Beispiel: $ myname_Variable.
Sobald $ myname_Variable deklariert ist, muss es mit einer benannten Abfragesyntax verwendet werden. Die Abfrage myQuery nimmt den Zeichenfolgenwert und gibt ihn wie unten gezeigt an sayHello weiter.
query myQuery($myname_Variable:String!) { sayHello(name:$myname_Variable)
}
Legen Sie den Wert für $ myname_Variable als JSON-Objekt im Abschnitt Abfragevariablen des GraphiQL-Clients fest.
{
"myname_Variable": "Mohtashim"
}
Die Ausgabe des obigen Codes lautet wie folgt:
{
"data": {
"sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
}
}
Verwendung der Abfragevariablen mit Enum
Lassen Sie uns sehen, wie eine Abfragevariable verwendet wird, wenn der Feldparameter ist enum type.
Schritt 1 - Bearbeiten Sie die Datei schema.graphql
enum ColorType {
RED
BLUE
GREEN
}
type Query {
setFavouriteColor(color:ColorType):String
}
Die Funktion setFavouriteColor verwendet enum als Eingabe und gibt einen Zeichenfolgenwert zurück.
Schritt 2 - Bearbeiten Sie die Datei resolvers.js
Die Resolverfunktion setFavouriteColor übernimmt root und args . Auf den zur Laufzeit an function übergebenen Aufzählungswert kann über den Parameter args zugegriffen werden.
setFavouriteColor:(root,args) => {
return "Your Fav Color is :"+args.color;
}
Schritt 3 - Deklarieren Sie eine Abfragevariable in GraphiQL
Die Abfrage heißt query_to_setColorDies nimmt eine Variable mit dem Namen color_variable von ColorType an. Diese Variable wird an die Methode setFavouriteColor übergeben.
query query_to_setColor($color_variable:ColorType) {
setFavouriteColor(color:$color_variable)
}
Geben Sie im Abschnitt Abfragevariable von GraphiQL den folgenden Code ein:
{
"color_variable":"RED"
}
Die Antwort ist unten gezeigt -
{
"data": {
"setFavouriteColor": "Your Fav Color is: RED"
}
}
In diesem Kapitel lernen wir Mutationsabfragen in GraphQL kennen.
Mutationsabfragen ändern Daten im Datenspeicher und geben einen Wert zurück. Es kann zum Einfügen, Aktualisieren oder Löschen von Daten verwendet werden. Mutationen werden als Teil des Schemas definiert.
Die Syntax einer Mutationsabfrage ist unten angegeben -
mutation{
someEditOperation(dataField:"valueOfField"):returnType
}
Illustration
Lassen Sie uns verstehen, wie Sie mithilfe einer Mutationsabfrage einen neuen Schülerdatensatz zum Datenspeicher hinzufügen.
Schritt 1 - Laden Sie die erforderlichen Abhängigkeiten für das Projekt herunter und installieren Sie sie
Erstellen Sie einen Projektordner mit dem Namen Mutations-App. Ändern Sie Ihr Verzeichnis vom Terminal in Mutation-App. Befolgen Sie die Schritte 3 bis 5, die im Kapitel Umgebungs-Setup erläutert werden.
Schritt 2 - Erstellen Sie eine schema.graphql-Datei
Hinzufügen schema.graphql Datei im Projektordner Mutation-App und fügen Sie den folgenden Code hinzu -
type Query {
greeting:String
}
type Mutation {
createStudent(collegeId:ID,firstName:String,lastName:String):String
}
Beachten Sie, dass die Funktion createStudent einen String-Typ zurückgibt. Dies ist eine eindeutige Kennung (ID), die nach dem Erstellen eines Schülers generiert wird.
Schritt 3 - Erstellen Sie eine resolver.js-Datei
Erstellen Sie eine Datei resolvers.js im Projektordner und fügen Sie den folgenden Code hinzu:
const db = require('./db')
const Mutation = {
createStudent:(root,args,context,info) => {
return db.students.create({collegeId:args.collegeId,
firstName:args.firstName,
lastName:args.lastName})
}
}
const Query = {
greeting:() => "hello"
}
module.exports = {Query,Mutation}
Die Mutationsfunktion zeigt auf die Sammlung der Schüler im Datenspeicher. Rufen Sie zum Hinzufügen eines neuen Schülers die Erstellungsmethode in der Schülersammlung auf. Das args- Objekt enthält die Parameter, die in der Abfrage übergeben werden. Die create - Methode von Studenten Sammlung kehrt die ID eines neu geschaffenen Studenten Objekt.
Schritt 4 - Führen Sie die Anwendung aus
Ein ... kreieren server.jsDatei. Siehe Schritt 8 im Kapitel Umgebungs-Setup. Führen Sie den Befehl npm start im Terminal aus. Der Server ist am 9000-Port betriebsbereit. Hier verwenden wir GraphiQL als Client, um die Anwendung zu testen.
Der nächste Schritt besteht darin, den Browser zu öffnen und die URL einzugeben http://localhost:9000/graphiql. Geben Sie die folgende Abfrage in den Editor ein -
//college Id should be matched with data from colleges.json for easy retrieval
mutation {
createStudent(collegeId:"col-2",firstName:"Tim",lastName:"George")
}
Die obige Abfrage erstellt ein Schülerobjekt in der Datei student.json. Die Abfrage gibt eine eindeutige Kennung zurück. Die Antwort der Abfrage ist wie folgt:
{
"data": {
"createStudent": "SkQtxYBUm"
}
}
Um zu überprüfen, ob das Schülerobjekt erstellt wurde, können wir die Abfrage studentById verwenden. Sie können die Datei students.json auch aus dem Datenordner öffnen, um die ID zu überprüfen.
Um die studentById-Abfrage zu verwenden, bearbeiten Sie die schema.graphql wie unten angegeben -
type Query {
studentById(id:ID!):Student
}
type Student {
id:ID!
firstName:String
lastName:String
collegeId:String
}
Bearbeiten Sie die resolver.js Datei wie unten angegeben -
const db = require('./db')
const Query = {
studentById:(root,args,context,info) => {
return db.students.get(args.id);
}
}
const Mutation = {
createStudent:(root,args,context,info) => {
return db.students.create({collegeId:args.collegeId,
firstName:args.firstName,
lastName:args.lastName})
}
}
module.exports = {Query,Mutation}
Unten ist die Abfrage angegeben, um den Schüler anhand einer eindeutigen ID zu ermitteln, die von der Mutationsabfrage zurückgegeben wurde.
{
studentById(id:"SkQtxYBUm") {
id
firstName
lastName
}
}
Die Antwort vom Server lautet wie folgt:
{
"data": {
"studentById": {
"id": "SkQtxYBUm",
"firstName": "Tim",
"lastName":"George"
}
}
}
Rückgabe eines mutierten Objekts
Es wird empfohlen, ein mutiertes Objekt zurückzugeben. Beispielsweise möchte die Client-Anwendung Details zu Studenten und Hochschulen abrufen. In diesem Fall können wir, anstatt zwei verschiedene Anfragen zu stellen, eine Abfrage erstellen, die ein Objekt zurückgibt, das Studenten und ihre College-Details enthält.
Schritt 1 - Schemadatei bearbeiten
Fügen Sie eine neue Methode mit dem Namen hinzu addStudent welches Objekt im Mutationstyp von zurückgibt schema.graphql.
Lassen Sie uns lernen, wie Sie über Studentendetails auf die College-Details zugreifen können. Fügen Sie den College-Typ in die Schemadatei ein.
type Mutation {
addStudent_returns_object(collegeId:ID,firstName:String,lastName:String):Student
createStudent(collegeId:ID,firstName:String,lastName:String):String
}
type College {
id:ID!
name:String
location:String
rating:Float
}
type Student {
id:ID!
firstName:String
lastName:String
college:College
}
Schritt 2 - Aktualisieren Sie die Datei resolvers.js
Aktualisieren Sie eine Datei resolvers.js im Projektordner und fügen Sie den folgenden Code hinzu -
const Mutation = {
createStudent:(root,args,context,info) => {
return db.students.create({
collegeId:args.collegeId,
firstName:args.firstName,
lastName:args.lastName
})
},
// new resolver function
addStudent_returns_object:(root,args,context,info) => {
const id = db.students.create({
collegeId:args.collegeId,
firstName:args.firstName,
lastName:args.lastName
})
return db.students.get(id)
}
}
//for each single student object returned,resolver is invoked
const Student = {
college:(root) => {
return db.colleges.get(root.collegeId);
}
}
module.exports = {Query,Student,Mutation}
Schritt 3 - Starten Sie den Server und geben Sie die Anforderungsabfrage in GraphiQL ein
Als nächstes starten wir den Server und fordern eine Abfrage in GraphiQL mit dem folgenden Code an:
mutation {
addStudent_returns_object(collegeId:"col-101",firstName:"Susan",lastName:"George") {
id
firstName
college{
id
name
}
}
}
Die obige Abfrage fügt einen neuen Schüler hinzu und ruft das Schülerobjekt zusammen mit dem College-Objekt ab. Dies spart Roundtrips zum Server.
Die Antwort ist wie folgt:
{
"data": {
"addStudent_returns_object": {
"id": "rklUl08IX",
"firstName": "Susan",
"college": {
"id": "col-101",
"name": "AMU"
}
}
}
}
Beim Hinzufügen oder Ändern von Daten ist es wichtig, die Benutzereingaben zu überprüfen. Beispielsweise müssen wir möglicherweise sicherstellen, dass der Wert eines Felds immer nicht null ist. Wir können benutzen! (non-nullable) Geben Sie marker in GraphQL ein, um eine solche Validierung durchzuführen.
Die Syntax für die Verwendung von ! Typmarkierung ist wie unten angegeben -
type TypeName {
field1:String!,
field2:String!,
field3:Int!
}
Die obige Syntax stellt sicher, dass nicht alle Felder null sind.
Wenn wir zusätzliche Regeln implementieren möchten, z. B. die Länge einer Zeichenfolge überprüfen oder prüfen möchten, ob eine Zahl innerhalb eines bestimmten Bereichs liegt, können wir benutzerdefinierte Validatoren definieren. Die benutzerdefinierte Validierungslogik ist Teil der Resolverfunktion. Lassen Sie uns dies anhand eines Beispiels verstehen.
Abbildung - Implementieren von benutzerdefinierten Validatoren
Lassen Sie uns ein Anmeldeformular mit grundlegender Validierung erstellen. Das Formular enthält E-Mail-, Vorname- und Kennwortfelder.
Schritt 1 - Laden Sie die erforderlichen Abhängigkeiten für das Projekt herunter und installieren Sie sie
Erstellen Sie einen Ordner mit dem Namen validation-app. Ändern Sie das Verzeichnis vom Terminal in die Validierungs-App. Befolgen Sie die Schritte 3 bis 5, die im Kapitel Umgebungs-Setup erläutert werden.
Schritt 2 - Erstellen Sie ein Schema
Hinzufügen schema.graphql Datei im Projektordner validation-app und fügen Sie den folgenden Code hinzu -
type Query {
greeting:String
}
type Mutation {
signUp(input:SignUpInput):String
}
input SignUpInput {
email:String!,
password:String!,
firstName:String!
}
Note- Wir können den Eingabetyp SignUpInput verwenden, um die Anzahl der Parameter in der signUp-Funktion zu reduzieren. Die signUp-Funktion akzeptiert also nur einen Parameter vom Typ SignUpInput.
Schritt 3 - Resolver erstellen
Erstellen Sie eine Datei resolvers.js im Projektordner und fügen Sie den folgenden Code hinzu -
const Query = {
greeting:() => "Hello"
}
const Mutation ={
signUp:(root,args,context,info) => {
const {email,firstName,password} = args.input;
const emailExpression = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const isValidEmail = emailExpression.test(String(email).toLowerCase())
if(!isValidEmail)
throw new Error("email not in proper format")
if(firstName.length > 15)
throw new Error("firstName should be less than 15 characters")
if(password.length < 8 )
throw new Error("password should be minimum 8 characters")
return "success";
}
}
module.exports = {Query,Mutation}
Die Resolver-Funktion signUp akzeptiert die Parameter E-Mail, Passwort und Vorname. Diese werden über die Eingabevariable übergeben, damit über args.input darauf zugegriffen werden kann.
Schritt 4 - Führen Sie die Anwendung aus
Erstellen Sie eine server.js-Datei. Siehe Schritt 8 im Kapitel Umgebungs-Setup. Führen Sie den Befehl npm start im Terminal aus. Der Server ist am 9000-Port betriebsbereit. Hier verwenden wir GraphiQL als Client, um die Anwendung zu testen.
Öffnen Sie den Browser und geben Sie die URL ein http://localhost:9000/graphiql. Geben Sie die folgende Abfrage in den Editor ein -
mutation doSignUp($input:SignUpInput) { signUp(input:$input)
}
Da die Eingabe in die Anmeldefunktion ein komplexer Typ ist, müssen wir Abfragevariablen in graphiql verwenden. Dazu müssen wir der Abfrage zuerst einen Namen geben und sie doSignUp nennen. Die $ -Eingabe ist eine Abfragevariable.
Die folgende Abfragevariable muss auf der Registerkarte Abfragevariablen von graphiql eingegeben werden -
{
"input":{
"email": "abc@abc",
"firstName": "kannan",
"password": "pass@1234"
}
}
Das Fehlerarray enthält die Details der Validierungsfehler wie unten gezeigt -
{
"data": {
"signUp": null
},
"errors": [
{
"message": "email not in proper format",
"locations": [
{
"line": 2,
"column": 4
}
],
"path": [
"signUp"
]
}
]
}
Wir müssen für jedes Feld eine korrekte Eingabe eingeben, wie unten angegeben -
{
"input":{
"email": "[email protected]",
"firstName": "kannan",
"password": "pass@1234"
}
}
Die Antwort lautet wie folgt:
{
"data": {
"signUp": "success"
}
}
In der folgenden Abfrage weisen wir hier kein Passwort zu.
{
"input":{
"email": "[email protected]",
"firstName": "kannan"
}
}
Wenn kein erforderliches Feld angegeben wird, zeigt der qraphql-Server den folgenden Fehler an:
{
"errors": [
{
"message": "Variable \"$input\" got invalid value {\"email\":\"[email protected]\",\"firstName\":\"kannan\"}; Field value.password of required type String! was not provided.",
"locations": [
{
"line": 1,
"column": 19
}
]
}
]
}
Webanwendungen senden und rufen Daten asynchron ab (im Hintergrund). Mit AJAX können Websites Inhalte auf den Bildschirm laden, ohne die Seite zu aktualisieren. jQuery bietet verschiedene Methoden für die AJAX-Funktionalität, wodurch die Verwendung von AJAX vereinfacht wird. In diesem Kapitel erfahren Sie, wie Sie GraphQL in jQuery integrieren können.
Betrachten Sie eine Anwendung mit Client-Server-Architektur. Wir können eine Front-End-Webseite erstellen, die Daten von einem GraphQL-Server anfordert. Die Webseite führt AJAX-Aufrufe mit jQuery an den GraphQL-Server durch.
Um GraphQL in JQuery zu integrieren, überprüfen wir die GraphiQL-Anforderungsheader und verstehen die Anforderungsparameter.
Starte das hello-worldApp (siehe Kapitel 6 für die entsprechende Abbildung). Geben Sie die graphql-Abfrage {Begrüßung} in das GraphiQL-Fenster ein. Klicken Sie mit der rechten Maustaste und überprüfen Sie oder drücken Sie (Strg + Umschalt + I) auf Chrom, um zur Netzwerkregisterkarte zu gelangen, wie unten gezeigt -
Aus dem Einfachen hello-world Zum Beispiel können wir das verstehen http method verwendet wird POST. Scrollen Sie nun im Browser zum Header-Bereich, um die Anforderungsnutzdaten anzuzeigen .
Sobald Sie auf klicken view codeIm Abschnitt "Request Payload" von Chrome wird Folgendes angezeigt.
{"query":"{\n greeting\n}","variables":null,"operationName":null}
Beachten Sie auch die Anforderungs-URL, http://localhost:9000/graphql das sollte von der Client-Anwendung aufgerufen werden.
Illustration
Lassen Sie uns verstehen, wie GraphQL schrittweise in JQuery integriert wird.
Server einrichten
Wir werden lernen, den Server mit den folgenden Schritten einzurichten:
Schritt 1 - Laden Sie die erforderlichen Abhängigkeiten für das Projekt herunter und installieren Sie sie
Erstellen Sie einen Ordner mit dem Namen jquery-server-app. Ändern Sie Ihr Verzeichnis vom Terminal in jquery-server-app. Befolgen Sie die Schritte 3 bis 5, die im Kapitel Umgebungs-Setup erläutert werden.
Schritt 2 - Erstellen Sie ein Schema
Fügen Sie die Datei schema.graphql im Projektordner hinzu jquery-server-app und fügen Sie den folgenden Code hinzu -
type Query
{
greeting: String
sayHello(name:String!):String
}
Die Datei hat zwei Abfragen definiert greeting und sayHello. Die sayHello-Abfrage akzeptiert einen Zeichenfolgenparameter und gibt eine weitere Zeichenfolge zurück. Der Parameter für die Funktion sayHello () ist nicht null.
Schritt 3 - Resolver erstellen
Erstellen Sie eine Datei resolvers.js im Projektordner und fügen Sie den folgenden Code hinzu:
const Query =
{
greeting: () => 'Hello GraphQL From TutorialsPoint !!' ,
sayHello:(root,args,context,info) => `Hi ${args.name} GraphQL server says Hello to you!!`
}
module.exports = {Query}
Hier, greeting und sayHellosind zwei Resolver. In sayHello resolver kann auf den an den Parameter name übergebenen Wert über args zugegriffen werden. Um auf Resolver-Funktionen außerhalb des Moduls zugreifen zu können, muss das Abfrageobjekt mit exportiert werdenmodule.exports.
Schritt 4 - Führen Sie die Anwendung aus
Erstellen Sie eine server.js-Datei. Siehe Schritt 8 im Kapitel Umgebungs-Setup. Führen Sie den Befehl npm start im Terminal aus. Der Server ist am 9000-Port betriebsbereit. Hier verwenden wir GraphiQL als Client, um die Anwendung zu testen.
Öffnen Sie den Browser und geben Sie die URL ein http://localhost:9000/graphiql. Geben Sie die folgende Abfrage in den Editor ein -
{
greeting,
sayHello(name:"Mohtashim")
}
Die Antwort vom Server ist wie folgt:
{
"data": {
"greeting": "Hello GraphQL From TutorialsPoint !!",
"sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
}
}
Client einrichten
Da wir den Server bereits eingerichtet haben, lernen wir nun, wie der Client eingerichtet wird.
Schritt 1 - Erstellen Sie einen neuen Ordner jquery-client-app außerhalb des aktuellen Projektordners
Zuerst erstellen wir einen Ordner mit dem Namen jquery-client-app außerhalb des Projektordners.
Schritt 2 - Erstellen Sie eine HTML-Seite index.html für die jQuery-Integration
Wir werden eine Client-Anwendung in jquery erstellen und beide Methoden aufrufen. Es folgt der Code für index.html Datei. Das index.html Seite sendet Anfragen an den Server, wenn die Schaltflächen - Greet und SayHelloangeklickt werden. Wir werden eine asynchrone Anfrage mit der Funktion $ .ajax () stellen.
<!DOCTYPE html>
<html>
<head>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function() { $("#btnSayhello").click(function() {
const name = $("#txtName").val(); console.log(name); $("#SayhelloDiv").html('loading....');
$.ajax({url: "http://localhost:9000/graphql", contentType: "application/json",type:'POST', data: JSON.stringify({ query:`{ sayHello(name:"${name}")}`
}),
success: function(result) {
console.log(JSON.stringify(result))
$("#SayhelloDiv").html("<h1>"+result.data.sayHello +"</h1>"); } }); }); $("#btnGreet").click(function() {
$("#greetingDiv").html('loading....'); //https://kannan-first-graphql-app.herokuapp.com/graphql $.ajax({url: "http://localhost:9000/graphql",
contentType: "application/json",
type:'POST',
data: JSON.stringify({
query:`{greeting}`
}),
success: function(result) {
$("#greetingDiv").html("<h1>"+result.data.greeting+"</h1>");
}
});
});
});
</script>
</head>
<body>
<h1>Jquery Client </h1>
<hr/>
<section>
<button id = "btnGreet">Greet</button>
<br/> <br/>
<div id = "greetingDiv"> </div>
</section>
<br/> <br/> <br/>
<hr/>
<section>
Enter a name:<input id = "txtName" type = "text" value = "kannan"/>
<button id = "btnSayhello">SayHello</button>
<div id = "SayhelloDiv"> </div>
</section>
</body>
</html>
Öffnen Sie diese Datei im Browser und klicken Sie auf die Schaltfläche, um die Antwort anzuzeigen. Die Ausgabe erfolgt wie folgt:
React ist eine Javascript-Bibliothek zum Erstellen von Benutzeroberflächen. In diesem Kapitel wird erläutert, wie Sie GraphQL in eine React-Anwendung integrieren können.
Illustration
Der schnellste Weg, um ein Reaktionsprojekt einzurichten, ist die Verwendung des Tools " React App erstellen" . In den folgenden Abschnitten erfahren Sie, wie Sie sowohl den Server als auch den Client einrichten.
Server einrichten
Führen Sie zum Einrichten des Servers die folgenden Schritte aus:
Schritt 1 - Laden Sie die erforderlichen Abhängigkeiten für das Projekt herunter und installieren Sie sie
Erstellen Sie einen Ordner react-server-app. Ändern Sie Ihr Verzeichnis in react-server-app vom Terminal. Befolgen Sie die Schritte 3 bis 5, die im Kapitel Umgebungs-Setup erläutert werden.
Schritt 2 - Erstellen Sie ein Schema
Hinzufügen schema.graphql Datei im Projektordner react-server-app und fügen Sie den folgenden Code hinzu -
type Query
{
greeting: String
sayHello(name:String!):String
}
Die Datei hat zwei Abfragen definiert - Begrüßung und Hallo. Die sayHello-Abfrage akzeptiert einen Zeichenfolgenparameter und gibt eine weitere Zeichenfolge zurück. Der Parameter für die Funktion sayHello () ist nicht null.
Schritt 3 - Resolver erstellen
Erstellen Sie eine Datei resolvers.js im Projektordner und fügen Sie den folgenden Code hinzu -
const Query =
{
greeting: () => 'Hello GraphQL From TutorialsPoint !!' ,
sayHello:(root,args,context,info) => `Hi ${args.name} GraphQL server says Hello to you!!`
}
module.exports = {Query}
Hier sind Begrüßung und Hallo sagen zwei Resolver. Im sayHello-Resolver kann über args auf den an den name-Parameter übergebenen Wert zugegriffen werden. Um auf Resolver-Funktionen außerhalb des Moduls zugreifen zu können, muss das Abfrageobjekt mit module.exports exportiert werden.
Schritt 4 - Führen Sie die Anwendung aus
Erstellen Sie eine server.js-Datei. Siehe Schritt 8 im Kapitel Umgebungs-Setup. Führen Sie den Befehl npm start im Terminal aus. Der Server ist am 9000-Port betriebsbereit. Hier verwenden wir GraphiQL als Client, um die Anwendung zu testen.
Öffnen Sie den Browser und geben Sie die URL ein http://localhost:9000/graphiql. Geben Sie die folgende Abfrage in den Editor ein -
{
greeting,
sayHello(name:"Mohtashim")
}
Die Antwort vom Server ist unten angegeben -
{
"data": {
"greeting": "Hello GraphQL From TutorialsPoint !!",
"sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
}
}
Client einrichten
Öffnen Sie ein neues Terminal für den Client. Das Serverterminal sollte weiterhin ausgeführt werden, bevor die Clientanwendung ausgeführt wird. Die React-Anwendung wird auf Portnummer 3000 und die Serveranwendung auf Portnummer 9000 ausgeführt.
Schritt 1 - Erstellen Sie einen React Project Hallo-Welt-Client
Geben Sie im Client-Terminal den folgenden Befehl ein:
npx create-react-app hello-world-client
Dadurch wird alles installiert, was für eine typische Reaktionsanwendung erforderlich ist. Dasnpx Dienstprogramm und create-react-appTool erstellen Sie ein Projekt mit dem Namen Hallo-Welt-Client. Öffnen Sie nach Abschluss der Installation das Projekt in VSCode.
Schritt 2 - Starten Sie den Hallo-Welt-Client
Ändern Sie den aktuellen Ordnerpfad im Terminal in Hallo-Welt-Client. Geben Sie npm start ein, um das Projekt zu starten. Dadurch wird ein Entwicklungsserver an Port 3000 ausgeführt und der Browser automatisch geöffnet und die Indexseite geladen.
Dies wird im folgenden Screenshot gezeigt -
Schritt 3 - Ändern Sie die App-Komponente
Fügen Sie in der App.js im Ordner src zwei Funktionen hinzu, eine zum Laden der Begrüßung und eine zum Laden von sayHello-Nachrichten.
Es folgt die Funktion loadGreeting, die eine GraphQL-Abfrage zur Begrüßung sendet.
async function loadGreeting() {
const response = await fetch('http://localhost:9000/graphql', {
method:'POST',
headers:{'content-type':'application/json'},
body:JSON.stringify({query:'{greeting}'})
})
const rsponseBody = await response.json();
return rsponseBody.data.greeting;
console.log("end of function")
}
Es folgt die loadSayhello Funktion, die eine GraphQL-Abfrage für sayHello sendet -
async function loadSayhello(name) {
const response = await fetch('http://localhost:9000/graphql', {
method:'POST',
headers:{'content-type':'application/json'},
body:JSON.stringify({query:`{sayHello(name:"${name}")}`})
})
}
Das Ganze App.js Datei wird unten gezeigt -
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
async function loadGreeting() {
const response = await fetch('http://localhost:9000/graphql', {
method:'POST',
headers:{'content-type':'application/json'},
body:JSON.stringify({query:'{greeting}'})
})
const rsponseBody = await response.json();
return rsponseBody.data.greeting;
console.log("end of function")
}
async function loadSayhello(name) {
const response = await fetch('http://localhost:9000/graphql', {
method:'POST',
headers:{'content-type':'application/json'},
body:JSON.stringify({query:`{sayHello(name:"${name}")}`})
})
const rsponseBody = await response.json();
return rsponseBody.data.sayHello;
}
class App extends Component {
constructor(props) {
super(props);
this.state = {greetingMessage:'',sayHelloMessage:'',userName:''}
this.updateName = this.updateName.bind(this);
this.showSayHelloMessage = this.showSayHelloMessage.bind(this);
this.showGreeting = this.showGreeting.bind(this);
}
showGreeting() {
loadGreeting().then(g => this.setState({greetingMessage:g+" :-)"}))
}
showSayHelloMessage() {
const name = this.state.userName;
console.log(name)
loadSayhello(name).then(m => this.setState({sayHelloMessage:m}))
}
updateName(event) {
this.setState({userName:event.target.value})
}
render() {
return (
<div className = "App">
<header className = "App-header">
<img src = {logo} className = "App-logo" alt = "logo" />
<h1 className = "App-title">Welcome to React</h1>
</header>
<br/><br/>
<section>
<button id = "btnGreet" onClick = {this.showGreeting}>Greet</button>
<br/> <br/>
<div id = "greetingDiv">
<h1>{this.state.greetingMessage}</h1>
</div>
</section>
<hr/>
<section>
Enter a name:<input id = "txtName" type = "text" onChange = {this.updateName}
value = {this.state.userName}/>
<button id = "btnSayhello" onClick = {this.showSayHelloMessage}>SayHello</button>
<br/>
user name is:{this.state.userName} <br/>
<div id = "SayhelloDiv">
<h1>{this.state.sayHelloMessage}</h1>
</div>
</section>
</div>
);
}
}
export default App;
Sobald beide Anwendungen ausgeführt werden, klicken Sie auf die Begrüßungsschaltfläche. Geben Sie als Nächstes einen Namen in das Textfeld ein und klicken Sie auf die Schaltfläche "Hallo sagen". Die Ausgabe erfolgt wie folgt:
Wir haben Apollo Server verwendet, um die Graphql-Spezifikation auf der Serverseite zu erstellen. Es ist schnell und einfach, einen produktionsbereiten GraphQL-Server zu erstellen. Lassen Sie uns nun die Client-Seite verstehen.
Apollo Client ist der beste Weg, um mit GraphQL Client-Anwendungen zu erstellen. Der Client soll Entwicklern helfen, schnell eine Benutzeroberfläche zu erstellen, die Daten mit GraphQL abruft und mit jedem JavaScript-Frontend verwendet werden kann.
Apollo Client unterstützt die folgenden Plattformen:
Sr.Nr. | Plattform & Framework |
---|---|
1 | Javascript Reagieren, Winkel, Vue, Meteor, Glut |
2 | WebComponents Polymer, Lit-Apollo |
3 | Native Mobile Native Android mit Java, Native iOS mit Swift |
Caching ist eine der Hauptfunktionen von Apollo Client. apollo-boost ist ein Convenience-Paket, das eine Reihe weiterer Abhängigkeiten mit sich bringt.
Illustration
Lassen Sie uns anhand der folgenden Schritte sehen, wie Sie mit Apollo Client Clientanwendungen erstellen:
Server einrichten
Wir müssen die folgenden Schritte ausführen, um einen Server einzurichten -
Schritt 1 - Laden Sie die erforderlichen Abhängigkeiten für das Projekt herunter und installieren Sie sie
Erstellen Sie einen Ordner Apollo-Server-App. Ändern Sie Ihr Verzeichnis in apollo-server-app vom Terminal. Befolgen Sie dann die Schritte 3 bis 5, die im Kapitel Umgebungs-Setup erläutert werden.
Schritt 2 - Erstellen Sie ein Schema
Hinzufügen schema.graphql Datei im Projektordner apollo-server-app und fügen Sie den folgenden Code hinzu -
type Query
{
students:[Student]
}
type Student {
id:ID!
firstName:String
lastName:String
college:College
}
type College {
id:ID!
name:String
location:String
rating:Float
}
Schritt 3 - Resolver hinzufügen
Erstellen Sie eine Datei resolvers.js im Projektordner und fügen Sie den folgenden Code hinzu -
const db = require('./db')
const Query = {
//resolver function for students returns list
students:() => db.students.list(),
}
const Student = {
college:(root) => {
return db.colleges.get(root.collegeId);
}
}
module.exports = {Query,Student}
Schritt 4 - Führen Sie die Anwendung aus
Ein ... kreieren server.jsDatei. Siehe Schritt 8 im Kapitel Umgebungs-Setup. Führen Sie den Befehl npm start im Terminal aus. Der Server ist am 9000-Port betriebsbereit. Hier verwenden wir GraphiQL als Client, um die Anwendung zu testen.
Öffnen Sie den Browser und geben Sie die URL ein http://localhost:9000/graphiql. Geben Sie die folgende Abfrage in den Editor ein.
{
students{
id
firstName
college{
name
}
}
}
Die Antwort auf die Abfrage lautet wie folgt:
{
"data": {
"students": [
{
"id": "S1001",
"firstName": "Mohtashim",
"college": {
"name": "CUSAT"
}
},
{
"id": "S1002",
"firstName": "Kannan",
"college": {
"name": "AMU"
}
},
{
"id": "S1003",
"firstName": "Kiran",
"college": {
"name": "AMU"
}
}
]
}
}
Client einrichten
Öffnen Sie ein neues Terminal für den Client. Das Serverterminal sollte weiterhin ausgeführt werden, bevor die Clientanwendung ausgeführt wird. Die React-Anwendung wird auf Portnummer 3000 und die Serveranwendung auf Portnummer 9000 ausgeführt.
Schritt 1 - Erstellen Sie eine Reaktionsanwendung
Geben Sie im Client-Terminal den folgenden Befehl ein:
npx create-react-app hello-world-client
Dadurch wird alles installiert, was für eine typische Reaktionsanwendung erforderlich ist. Das Dienstprogramm npx und das Tool create-react-app erstellen ein Projekt mit Namenhello-world-client. Öffnen Sie nach Abschluss der Installation das Projekt in VSCode.
Schritt 2 - Starten Sie den Hallo-Welt-Client
Ändern Sie den aktuellen Ordnerpfad im Terminal in hello-world-client. Geben Sie npm start ein, um das Projekt zu starten. Dadurch wird ein Entwicklungsserver an Port 3000 ausgeführt und der Browser automatisch geöffnet und die Indexseite geladen.
Dies wird im folgenden Screenshot gezeigt -
Schritt 3 - Installieren Sie die Apollo Client-Bibliotheken
Öffnen Sie zum Installieren eines Apollo-Clients ein neues Terminal und befinden Sie sich im aktuellen Projektordnerpfad. Geben Sie den folgenden Befehl ein:
npm install apollo-boost graphql
Dadurch werden die graphql-Bibliotheken für die Clientseite sowie das Apollo Boost-Paket heruntergeladen. Wir können dies überprüfen, indem wir die npm-Ansicht in Apollo-Boost-Abhängigkeiten eingeben. Dies wird viele Abhängigkeiten haben, wie unten gezeigt -
{
'apollo-cache': '^1.1.15',
'apollo-cache-inmemory': '^1.2.8',
'apollo-client': '^2.4.0',
'apollo-link': '^1.0.6',
'apollo-link-error': '^1.0.3',
'apollo-link-http': '^1.3.1',
'apollo-link-state': '^0.4.0',
'graphql-tag': '^2.4.2'
}
Wir können deutlich sehen, dass die Apollo-Client-Bibliothek installiert ist.
Schritt 4 - Ändern Sie die App-Komponente in der Datei index.js.
Mit Apollo Client können wir den Server ohne die Verwendung der Abruf-API direkt aufrufen. Außerdem sollten die Abfragen und Mutationen nicht in eine Zeichenfolge mit Back-Tick-Notation eingebettet werden. Dies liegt daran, dass diegqlFunktion analysiert direkt die Abfragen. Dies bedeutet, dass ein Programmierer beim Schreiben von Abfragen im GraphiQL-Tool Abfragen direkt auf dieselbe Weise schreiben kann. gql ist eine Tag-Funktion, die die in der Back-Tick-Notation geschriebene Vorlagenzeichenfolge in das graphql-Abfrageobjekt analysiert. Die Apollo Client-Abfragemethode gibt ein Versprechen zurück.
Das folgende Code-Snippet zeigt, wie Apollo Client importiert wird:
import {ApolloClient, HttpLink, InMemoryCache} from 'apollo-boost'
const endPointUrl = 'http://localhost:9000/graphql'
const client = new ApolloClient({
link: new HttpLink({uri:endPointUrl}),
cache:new InMemoryCache()
});
Im vorherigen Kapitel haben wir die Verwendung der Abruf-API für HTTP-Anforderungen erläutert. Der folgende Code zeigt die VerwendunggqlFunktion. DasloadStudentsAsync Die Funktion verwendet den graphql-Client, um den Server abzufragen.
async function loadStudentsAsync() {
const query = gql`
{
students{
id
firstName
lastName
college{
name
}
}
}`
const {data} = await client.query({query}) ;
return data.students;
}
Sie müssen nur die behalten index.js im srcOrdner und index.html im öffentlichen Ordner; Alle anderen automatisch generierten Dateien können entfernt werden.
Die Verzeichnisstruktur ist unten angegeben -
hello-world-client /
-->node_modules
-->public
index.html
-->src
index.js
-->package.json
Es folgt die index.js in Reaktion Anwendung -
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
// apollo client
import {ApolloClient, HttpLink, InMemoryCache} from 'apollo-boost'
import gql from 'graphql-tag'
const endPointUrl = 'http://localhost:9000/graphql'
const client = new ApolloClient({
link: new HttpLink({uri:endPointUrl}),
cache:new InMemoryCache()
});
async function loadStudentsAsync() {
const query = gql`
{
students{
id
firstName
lastName
college{
name
}
}
}
`
const {data} = await client.query({query}) ;
return data.students;
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
students:[]
}
this.studentTemplate = [];
}
async loadStudents() {
const studentData = await loadStudentsAsync();
this.setState({
students: studentData
})
console.log("loadStudents")
}
render() {
return(
<div>
<input type = "button" value = "loadStudents" onClick = {this.loadStudents.bind(this)}/>
<div>
<br/>
<hr/>
<table border = "3">
<thead>
<tr>
<td>First Name</td>
<td>Last Name</td>
<td>college Name</td>
</tr>
</thead>
<tbody>
{
this.state.students.map(s => {
return (
<tr key = {s.id}>
<td>
{s.firstName}
</td>
<td>
{s.lastName}
</td>
<td>
{s.college.name}
</td>
</tr>
)
})
}
</tbody>
</table>
</div>
</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById('root'));
Die React-Anwendung lädt Schüler vom GraphQL-Server, sobald wir auf die Schaltfläche loadStudents klicken (siehe unten).
Authentifizierung ist der Prozess oder die Aktion zum Überprüfen der Identität eines Benutzers oder eines Prozesses. Es ist wichtig, dass eine Anwendung einen Benutzer authentifiziert, um sicherzustellen, dass die Daten einem anonymen Benutzer nicht zur Verfügung stehen. In diesem Abschnitt erfahren Sie, wie Sie einen GraphQL-Client authentifizieren.
Express JWT
In diesem Beispiel verwenden wir jQuery, um eine Clientanwendung zu erstellen. Zur Authentifizierung von Anfragen verwenden wir express-jwt Modul auf der Serverseite.
Das Express-JWT-Modul ist eine Middleware, mit der Sie HTTP-Anforderungen mithilfe von JWT-Token authentifizieren können. JSON Web Token (JWT) ist eine lange Zeichenfolge, die den angemeldeten Benutzer identifiziert.
Sobald sich der Benutzer erfolgreich angemeldet hat, generiert der Server ein JWT-Token. Dieses Token identifiziert ein Protokoll eindeutig. Mit anderen Worten, das Token ist eine Darstellung der Benutzeridentität. Wenn der Client das nächste Mal zum Server kommt, muss er dieses Token vorlegen, um die erforderlichen Ressourcen zu erhalten. Der Client kann entweder eine mobile Anwendung oder eine Webanwendung sein.
Illustration
Wir werden schrittweise vorgehen, um diese Abbildung zu verstehen.
Server einrichten
Im Folgenden finden Sie die Schritte zum Einrichten des Servers:
Schritt 1 - Laden Sie die erforderlichen Abhängigkeiten für das Projekt herunter und installieren Sie sie
Erstellen Sie einen Ordner auth-server-app. Ändern Sie Ihr Verzeichnis in auth-server-app vom Terminal. Befolgen Sie die Schritte 3 bis 5, die im Kapitel Umgebungs-Setup erläutert werden.
Schritt 2 - Erstellen Sie ein Schema
schema.graphql auth-server-apptype Query
{
greetingWithAuth:String
}
Schritt 3 - Resolver hinzufügen
Erstellen Sie eine Datei resolvers.js im Projektordner und fügen Sie den folgenden Code hinzu -
Der Resolver überprüft, ob ein authentifiziertes Benutzerobjekt im Kontextobjekt von GraphQL verfügbar ist. Es wird eine Ausnahme ausgelöst, wenn kein authentifizierter Benutzer verfügbar ist.
const db = require('./db')
const Query = {
greetingWithAuth:(root,args,context,info) => {
//check if the context.user is null
if (!context.user) {
throw new Error('Unauthorized');
}
return "Hello from TutorialsPoint, welcome back : "+context.user.firstName;
}
}
module.exports = {Query}
Schritt 4 - Erstellen Sie die Datei Server.js
Die Authentifizierungs-Middleware authentifiziert Anrufer mithilfe eines JSON-Web-Tokens. Die URL für die Authentifizierung lautet http://localhost:9000/login.
Dies ist eine Nachoperation. Der Benutzer muss seine E-Mail-Adresse und sein Passwort eingeben, die vom Backend bestätigt werden. Wenn ein gültiges Token mit der Methode jwt.sign generiert wird, muss der Client dieses für nachfolgende Anforderungen im Header senden.
Wenn das Token gültig ist, wird req.user mit dem JSON-Objekt festgelegt, das dekodiert wurde, um von der späteren Middleware für die Autorisierung und Zugriffskontrolle verwendet zu werden.
Der folgende Code verwendet zwei Module - jsonwebtoken und express-jwt zur Authentifizierung von Anforderungen -
Wenn der Benutzer auf klickt greetSchaltfläche wird eine Anforderung für die / graphql-Route ausgegeben. Wenn der Benutzer nicht authentifiziert ist, wird er aufgefordert, sich selbst zu authentifizieren.
Dem Benutzer wird ein Formular angezeigt, in dem die E-Mail-ID und das Kennwort akzeptiert werden. In unserem Beispiel ist die / login-Route für die Authentifizierung des Benutzers verantwortlich.
Die Route / login überprüft, ob in der Datenbank eine Übereinstimmung für die vom Benutzer bereitgestellten Anmeldeinformationen gefunden wurde.
Wenn die Anmeldeinformationen ungültig sind, wird eine HTTP 401-Ausnahme an den Benutzer zurückgegeben.
Wenn die Anmeldeinformationen gültig sind, wird vom Server ein Token generiert. Dieses Token wird als Teil der Antwort an den Benutzer gesendet. Dies erfolgt über die Funktion jwt.sign.
const expressJwt = require('express-jwt');
const jwt = require('jsonwebtoken');
//private key
const jwtSecret = Buffer.from('Zn8Q5tyZ/G1MHltc4F/gTkVJMlrbKiZt', 'base64');
app.post('/login', (req, res) => {
const {email, password} = req.body;
//check database
const user = db.students.list().find((user) => user.email === email);
if (!(user && user.password === password)) {
res.sendStatus(401);
return;
}
//generate a token based on private key, token doesn't have an expiry
const token = jwt.sign({sub: user.id}, jwtSecret);
res.send({token});
});
Für jede Anfrage wird die Funktion app.use () aufgerufen. Dies ruft wiederum die ExpressJWT-Middleware auf. Diese Middleware dekodiert das JSON-Web-Token. Die im Token gespeicherte Benutzer-ID wird abgerufen und als Eigenschaftsbenutzer im Anforderungsobjekt gespeichert.
//decodes the JWT and stores in request object
app.use(expressJwt({
secret: jwtSecret,
credentialsRequired: false
}));
Um die Benutzereigenschaft im GraphQL-Kontext verfügbar zu machen, wird diese Eigenschaft der zugewiesen context Objekt wie unten gezeigt -
//Make req.user available to GraphQL context
app.use('/graphql', graphqlExpress((req) => ({
schema,
context: {user: req.user &&apm; db.students.get(req.user.sub)}
})));
Erstellen server.js im aktuellen Ordnerpfad. Die vollständige Datei server.js lautet wie folgt:
const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const expressJwt = require('express-jwt'); //auth
const jwt = require('jsonwebtoken'); //auth
const db = require('./db');
var port = process.env.PORT || 9000
const jwtSecret = Buffer.from('Zn8Q5tyZ/G1MHltc4F/gTkVJMlrbKiZt', 'base64');
const app = express();
const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
const resolvers = require('./resolvers')
const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})
app.use(cors(), bodyParser.json(), expressJwt({
secret: jwtSecret,
credentialsRequired: false
}));
const {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql', graphqlExpress((req) => ({
schema,
context: {user: req.user && db.students.get(req.user.sub)}
})));
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))
//authenticate students
app.post('/login', (req, res) => {
const email = req.body.email;
const password = req.body.password;
const user = db.students.list().find((user) => user.email === email);
if (!(user && user.password === password)) {
res.sendStatus(401);
return;
}
const token = jwt.sign({sub: user.id}, jwtSecret);
res.send({token});
});
app.listen(port, () => console.info(`Server started on port ${port}`));
Schritt 5 - Führen Sie die Anwendung aus
Führen Sie den Befehl npm start im Terminal aus. Der Server ist am 9000-Port betriebsbereit. Hier verwenden wir GraphiQL als Client, um die Anwendung zu testen.
Öffnen Sie den Browser und geben Sie die URL ein http://localhost:9000/graphiql. Geben Sie die folgende Abfrage in den Editor ein -
{
greetingWithAuth
}
In der folgenden Antwort ist ein Fehler aufgetreten, da wir kein authentifizierter Benutzer sind.
{
"data": {
"greetingWithAuth": null
},
"errors": [
{
"message": "Unauthorized",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"greetingWithAuth"
]
}
]
}
Lassen Sie uns im nächsten Abschnitt eine Clientanwendung zur Authentifizierung erstellen.
Einrichten des JQuery-Clients
In der Clientanwendung wird eine Begrüßungsschaltfläche bereitgestellt, die das Schema aufruft greetingWithAuth. Wenn Sie auf die Schaltfläche ohne Anmeldung klicken, wird die folgende Fehlermeldung angezeigt:
Sobald Sie sich mit einem in der Datenbank verfügbaren Benutzer angemeldet haben, wird der folgende Bildschirm angezeigt:
Zugreifen greetingmüssen wir zuerst auf die URL zugreifen http://localhost:9000/login Route wie unten.
Die Antwort enthält das vom Server generierte Token.
$.ajax({
url:"http://localhost:9000/login",
contentType:"application/json",
type:"POST",
data:JSON.stringify({email,password}),
success:function(response) {
loginToken = response.token;
$('#authStatus') .html("authenticated successfully") .css({"color":"green",'font-weight':'bold'}); $("#greetingDiv").html('').css({'color':''});
},
error:(xhr,err) => alert('error')
})
Nach einer erfolgreichen Anmeldung können wir wie unten angegeben auf das Schema greetingWithAuth zugreifen . Für alle nachfolgenden Anfragen mit Inhaber-Token sollte ein Authorizationheader vorhanden sein.
{
url: "http://localhost:9000/graphql",
contentType: "application/json",
headers: {"Authorization": 'bearer '+loginToken}, type:'POST',
data: JSON.stringify({
query:`{greetingWithAuth}`
}
Das Folgende ist der Code für index.html -
<!DOCTYPE html>
<html>
<head>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function() { let loginToken = ""; $("#btnGreet").click(function() {
$.ajax({url: "http://localhost:9000/graphql", contentType: "application/json", headers: {"Authorization": 'bearer '+loginToken}, type:'POST', data: JSON.stringify({ query:`{greetingWithAuth}` }), success: function(result) { $("#greetingDiv").html("<h1>"+result.data.greetingWithAuth+"</h1>")
},
error:function(jQxhr,error) {
if(jQxhr.status == 401) {
$("#greetingDiv").html('please authenticate first!!') .css({"color":"red",'font-weight':'bold'}) return; } $("#greetingDiv").html('error').css("color","red");
}
});
});
$('#btnAuthenticate').click(function() { var email = $("#txtEmail").val();
var password = $("#txtPwd").val(); if(email && password) { $.ajax({
url:"http://localhost:9000/login",
contentType:"application/json",
type:"POST",
data:JSON.stringify({email,password}),
success:function(response) {
loginToken = response.token;
$('#authStatus') .html("authenticated successfully") .css({"color":"green",'font-weight':'bold'}); $("#greetingDiv").html('').css({'color':''});
},
error:(xhr,err) => alert('error')
})
}else alert("email and pwd empty")
})
});
</script>
</head>
<body>
<h1> GraphQL Authentication </h1>
<hr/>
<section>
<button id = "btnGreet">Greet</button>
<br/> <br/>
<div id = "greetingDiv"></div>
</section>
<br/> <br/> <br/>
<hr/>
<section id = "LoginSection">
<header>
<h2>*Login first to access greeting </h2>
</header>
<input type = "text" value = "[email protected]" placeholder = "enter email" id = "txtEmail"/>
<br/>
<input type = "password" value = "pass123" placeholder = "enter password" id = "txtPwd"/>
<br/>
<input type = "button" id = "btnAuthenticate" value = "Login"/>
<p id = "authStatus"></p>
</section>
</body>
</html>
Beim Caching werden Daten in einem temporären Speicherbereich namens aufgerufen cache. Wenn Sie zu einer Seite zurückkehren, die Sie kürzlich besucht haben, kann der Browser diese Dateien aus dem Cache und nicht vom ursprünglichen Server abrufen. Dies spart Zeit und Netzwerk vor der Belastung durch zusätzlichen Datenverkehr.
Clientanwendungen, die mit GraphQL interagieren, sind für das Zwischenspeichern von Daten am Ende verantwortlich. Ein mögliches Muster hierfür besteht darin, ein Feld wie id als global eindeutigen Bezeichner zu reservieren.
InMemory-Cache
InMemoryCache ist ein normalisierter Datenspeicher, der häufig in GraphQL-Clientanwendungen ohne Verwendung einer anderen Bibliothek wie Redux verwendet wird.
Der Beispielcode für die Verwendung von InMemoryCache mit ApolloClient ist unten angegeben:
import {ApolloClient, HttpLink, InMemoryCache} from 'apollo-boost'
const cache = new InMemoryCache();
const client = new ApolloClient({
link: new HttpLink(),
cache
});
Der InMemoryCache-Konstruktor verwendet ein optionales Konfigurationsobjekt mit Eigenschaften, um Ihren Cache anzupassen.
Sr.Nr. | Parameter & Beschreibung |
---|---|
1 | addTypename Ein Boolescher Wert, um zu bestimmen, ob dem Dokument __typename hinzugefügt werden soll (Standard: true). |
2 | dataIdFromObject Eine Funktion, die ein Datenobjekt verwendet und eine eindeutige Kennung zurückgibt, die beim Normalisieren der Daten im Speicher verwendet wird |
3 | fragmentMatcher Standardmäßig verwendet der InMemoryCache einen heuristischen Fragment-Matcher |
4 | cacheRedirects Eine Zuordnung von Funktionen zum Umleiten einer Abfrage zu einem anderen Eintrag im Cache, bevor eine Anforderung erfolgt. |
Illustration
Wir werden in ReactJS eine einseitige Anwendung mit zwei Registerkarten erstellen - eine für die Startregisterkarte und eine für Schüler. Auf der Registerkarte "Schüler" werden Daten von einer GraphQL-Server-API geladen. Die Anwendung fragt nach Schülerdaten ab , wenn der Benutzer von der Startregisterkarte zur Schülerregisterkarte navigiert. Die resultierenden Daten werden von der Anwendung zwischengespeichert.
Wir werden auch die Serverzeit mit abfragen getTimeFeld, um zu überprüfen, ob die Seite zwischengespeichert ist. Wenn Daten aus dem Cache zurückgegeben werden, wird auf der Seite der Zeitpunkt der allerersten an den Server gesendeten Anforderung angezeigt. Wenn die Daten das Ergebnis einer neuen Anforderung an den Server sind, wird immer die späteste Zeit vom Server angezeigt.
Server einrichten
Im Folgenden finden Sie die Schritte zum Einrichten des Servers:
Schritt 1 - Laden Sie die erforderlichen Abhängigkeiten für das Projekt herunter und installieren Sie sie
Erstellen Sie einen Ordner cache-server-app. Ändern Sie Ihr Verzeichnis in cache-server-app vom Terminal. Befolgen Sie die Schritte 3 bis 5, die im Kapitel Umgebungs-Setup erläutert werden.
Schritt 2 - Erstellen Sie ein Schema
Hinzufügen schema.graphql Datei im Projektordner cache-server-app und fügen Sie den folgenden Code hinzu -
type Query {
students:[Student]
getTime:String
}
type Student {
id:ID!
firstName:String
lastName:String
fullName:String
}
Schritt 3 - Resolver hinzufügen
Erstellen Sie eine Datei resolvers.js im Projektordner und fügen Sie den folgenden Code hinzu:
const db = require('./db')
const Query = {
students:() => db.students.list(),
getTime:() => {
const today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
return `${h}:${m}:${s}`;
}
}
module.exports = {Query}
Schritt 4 - Führen Sie die Anwendung aus
Erstellen Sie eine server.js-Datei. Siehe Schritt 8 im Kapitel Umgebungs-Setup. Führen Sie den Befehl npm start im Terminal aus. Der Server ist am 9000-Port betriebsbereit. Hier verwenden wir GraphiQL als Client, um die Anwendung zu testen.
Öffnen Sie den Browser und geben Sie die URL ein http://localhost:9000/graphiql. Geben Sie die folgende Abfrage in den Editor ein -
{
getTime
students {
id
firstName
}
}
Die Beispielantwort zeigt die Namen der Schüler und die Serverzeit.
{
"data": {
"getTime": "22:18:42",
"students": [
{
"id": "S1001",
"firstName": "Mohtashim"
},
{
"id": "S1002",
"firstName": "Kannan"
},
{
"id": "S1003",
"firstName": "Kiran"
}
]
}
}
Einrichten des ReactJS-Clients
Öffnen Sie ein neues Terminal für den Client. Das Serverterminal sollte weiterhin ausgeführt werden, bevor die Clientanwendung ausgeführt wird. Die React-Anwendung wird auf Portnummer 3000 und die Serveranwendung auf Portnummer 9000 ausgeführt.
Schritt 1 - Erstellen Sie eine Reaktionsanwendung
Geben Sie im Client-Terminal den folgenden Befehl ein:
npx create-react-app hello-world-client
Dadurch wird alles installiert, was für eine typische Reaktionsanwendung erforderlich ist. Dasnpx utility und create-react-appTools erstellen ein Projekt mit dem Namen Hallo-Welt-Client. Öffnen Sie nach Abschluss der Installation das Projekt in VSCode.
Installieren Sie Routermodule, um mit dem folgenden Befehl zu reagieren: npm install react-router-dom.
Schritt 2 - Starten Sie den Hallo-Welt-Client
Ändern Sie den aktuellen Ordnerpfad im Terminal in Hallo-Welt-Client. Geben Sie npm start ein, um das Projekt zu starten. Dadurch wird ein Entwicklungsserver an Port 3000 ausgeführt und der Browser automatisch geöffnet und die Indexseite geladen.
Dies wird im folgenden Screenshot gezeigt -
Schritt 3 - Installieren Sie die Apollo Client-Bibliotheken
Öffnen Sie zum Installieren eines Apollo-Clients ein neues Terminal und befinden Sie sich im aktuellen Projektordnerpfad. Geben Sie den folgenden Befehl ein:
npm install apollo-boost graphql
Dadurch werden die graphql-Bibliotheken für die Clientseite sowie das Apollo Boost-Paket heruntergeladen. Wir können dies überprüfen, indem wir die apo-boost-Abhängigkeiten von npm view eingeben. Dies wird viele Abhängigkeiten haben, wie unten gezeigt -
{
'apollo-cache': '^1.1.15',
'apollo-cache-inmemory': '^1.2.8',
'apollo-client': '^2.4.0',
'apollo-link': '^1.0.6',
'apollo-link-error': '^1.0.3',
'apollo-link-http': '^1.3.1',
'apollo-link-state': '^0.4.0',
'graphql-tag': '^2.4.2'
}
Wir können deutlich sehen, dass die Apollo-Client-Bibliothek installiert ist.
Schritt 4 - Ändern Sie die App-Komponente in der Datei index.js.
Für eine einfache Reaktionsanwendung müssen Sie nur die behalten index.js im src Ordner und index.htmlim öffentlichen Ordner; Alle anderen automatisch generierten Dateien können entfernt werden.
Die Verzeichnisstruktur ist unten angegeben -
hello-world-client /
-->node_modules
-->public
index.html
-->src
index.js
students.js
-->package.json
Fügen Sie eine zusätzliche Datei student.js hinzu, die die Schülerkomponente enthält. Schülerdetails werden über die Schülerkomponente abgerufen. In der App-Komponente verwenden wir einen HashRouter.
Es folgt die index.js in Reaktion Anwendung -
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {HashRouter, Route, Link} from 'react-router-dom'
//components
import Students from './students'
class App extends Component {
render() {
return(
<div><h1>Home !!</h1>
<h2>Welcome to React Application !! </h2>
</div>
)
}
}
function getTime() {
var d = new Date();
return d.getHours()+":"+d.getMinutes()+":"+d.getSeconds()
}
const routes = <HashRouter>
<div>
<h4>Time from react app:{getTime()}</h4>
<header>
<h1> <Link to="/">Home</Link>
<Link to = "/students">Students</Link> </h1>
</header>
<Route exact path = "/students" component = {Students}></Route>
<Route exact path = "/" component = {App}></Route>
</div>
</HashRouter>
ReactDOM.render(routes, document.querySelector("#root"))
Schritt 5 - Bearbeiten von Komponentenschülern in Students.js
In der Schülerkomponente verwenden wir die folgenden zwei Ansätze zum Laden von Daten:
Fetch API (loadStudents_noCache) - Dies löst jedes Mal eine neue Anfrage aus, wenn Sie auf die Registerkarte "Schüler" klicken.
Apollo Client (loadWithApolloclient) - Dadurch werden Daten aus dem Cache abgerufen.
Fügen Sie eine Funktion hinzu loadWithApolloclientwelche Abfragen für Schüler und Zeit vom Server. Diese Funktion aktiviert das Caching. Hier verwenden wir eine gql-Funktion, um die Abfrage zu analysieren.
async loadWithApolloclient() {
const query = gql`{
getTime
students {
id
firstName
}
}`;
const {data} = await client.query({query})
return data;
}
Das Fetch APIist eine einfache Schnittstelle zum Abrufen von Ressourcen. Mit Fetch ist es einfacher, Webanfragen zu stellen und Antworten zu verarbeiten als mit dem älteren XMLHttpRequest. Die folgende Methode zeigt das Laden von Daten direkt mit fetch api -
async loadStudents_noCache() {
const response = await fetch('http://localhost:9000/graphql', {
method:'POST',
headers:{'content-type':'application/json'},
body:JSON.stringify({query:`{
getTime
students {
id
firstName
}
}`})
})
const rsponseBody = await response.json();
return rsponseBody.data;
}
Rufen Sie im Konstruktor von StudentsComponent die auf loadWithApolloClientMethode. Das Ganze Student.js Datei ist unten -
import React, {Component} from 'react';
import { Link} from 'react-router-dom'
//Apollo Client
import {ApolloClient, HttpLink, InMemoryCache} from 'apollo-boost'
import gql from 'graphql-tag'
const client = new ApolloClient({
link: new HttpLink({uri:`http://localhost:9000/graphql`}),
cache:new InMemoryCache()
})
class Students extends Component {
constructor(props) {
super(props);
this.state = {
students:[{id:1,firstName:'test'}],
serverTime:''
}
this.loadWithApolloclient().then(data => {
this.setState({
students:data.students,
serverTime:data.getTime
})
})
}
async loadStudents_noCache() {
const response = await fetch('http://localhost:9000/graphql', {
method:'POST',
headers:{'content-type':'application/json'},
body:JSON.stringify({query:`{
getTime
students {
id
firstName
}
}`})
})
const rsponseBody = await response.json();
return rsponseBody.data;
}
async loadWithApolloclient() {
console.log("inside apollo client function")
const query = gql`{
getTime
students {
id
firstName
}
}`;
const {data} = await client.query({query})
return data;
}
render() {
return(
<div>
<h3>Time from GraphQL server :{this.state.serverTime}</h3>
<p>Following Students Found </p>
<div>
<ul>
{
this.state.students.map(s => {
return(
<li key = {s.id}>
{s.firstName}
</li>
)
})
}
</ul>
</div>
</div>
)
}
}
export default Students
Schritt 6 - Führen Sie die React-Anwendung mit npm start aus
Sie können die Reaktionsanwendung testen, indem Sie von der Registerkarte "Startseite" zur Registerkarte "Schüler" wechseln. Sobald die Registerkarte Schüler mit Daten vom Server geladen ist. Die Daten werden zwischengespeichert. Sie können es testen, indem Sie mehrmals von zu Hause auf die Registerkarte "Schüler" wechseln. Die Ausgabe erfolgt wie unten gezeigt -
Wenn Sie die Schülerseite zuerst durch Eingabe der URL geladen haben, http://localhost:3000/#/studentskönnen Sie sehen, dass die Ladezeit für React App und GraphQL ungefähr gleich wäre. Wenn Sie danach zur Startansicht wechseln und zum GraphQL-Server zurückkehren, ändert sich die Zeit nicht mehr. Dies zeigt, dass die Daten zwischengespeichert sind.
Schritt 7 - Ändern Sie loadWithApolloclient Call in loadStudents_noCache
Wenn Sie die Lademethode auf ändern loadStudents_noCacheIm Konstruktor von StudentComponent werden die Daten bei der Ausgabe nicht zwischengespeichert. Dies zeigt den Unterschied zwischen Caching und Nicht-Caching.
this.loadStudents_noCache().then(data => {
this.setState({
students:data.students,
serverTime:data.getTime
})
})
Aus der obigen Ausgabe geht hervor, dass beim Hin- und Herwechseln zwischen den Registerkarten die Zeit vom graphql-Server immer die neueste ist, was bedeutet, dass die Daten nicht zwischengespeichert werden.