GraphQL ist jetzt ohne Übertreibung der letzte Blick in den IT-Modus. Und wenn Sie noch nicht wissen, um welche Art von Technologie es sich handelt, wie Sie sie verwenden und warum sie für Sie nützlich sein kann, ist der Artikel, den wir heute veröffentlichen, für Sie geschrieben. Hier werden die Grundlagen von GraphQL anhand eines Beispiels einer Datenschema-Implementierung für die API eines Popcorn-Unternehmens erläutert. Lassen Sie uns insbesondere über Datentypen, Abfragen und Mutationen sprechen.

Was ist GraphQL?
GraphQL ist eine Abfragesprache, die von Clientanwendungen zum Arbeiten mit Daten verwendet wird. GraphQL ist mit einem solchen Konzept wie einem „Schema“ verbunden. Auf diese Weise können Sie das Erstellen, Lesen, Aktualisieren und Löschen von Daten in Ihrer Anwendung organisieren (dh wir haben vier Grundfunktionen, die bei der Arbeit mit Data Warehouses verwendet werden, die normalerweise mit dem Akronym CRUD bezeichnet werden - erstellen, lesen, aktualisieren, löschen).
Es wurde oben gesagt, dass GraphQL verwendet wird, um mit Daten in "Ihrer Anwendung" und nicht "in Ihrer Datenbank" zu arbeiten. Tatsache ist, dass GraphQL ein von Datenquellen unabhängiges System ist, dh es spielt keine Rolle, wo es organisiert ist, um seine Arbeit zu organisieren.
Wenn Sie den Namen dieser Technologie betrachten, ohne etwas über GraphQL zu wissen, scheint es, als stünden wir vor etwas sehr Kompliziertem und Verwirrendem. Der Name der Technologie hat das Wort "Graph". Bedeutet dies, dass Sie lernen müssen, mit Graphendatenbanken zu arbeiten, um es zu beherrschen? Und die Tatsache, dass der Name "QL" enthält (was "Abfragesprache", dh "Abfragesprache" bedeuten kann), bedeutet, dass diejenigen, die GraphQL verwenden möchten, eine völlig neue Programmiersprache lernen müssen?
Diese Befürchtungen sind nicht ganz berechtigt. Um Sie zu beruhigen - das ist die grausame Wahrheit über diese Technologie: Es handelt sich nur um verschönerte
GET
oder
POST
Anfragen. Während GraphQL im Allgemeinen einige neue Konzepte in Bezug auf die Datenorganisation und die Interaktion mit GraphQL einführt, stützen sich die internen Mechanismen dieser Technologie auf die guten alten HTTP-Anforderungen.
REST-Technologie neu denken
Flexibilität unterscheidet die GraphQL-Technologie von der bekannten REST-Technologie. Wenn bei Verwendung von REST alles korrekt ausgeführt wird, werden Endpunkte normalerweise unter Berücksichtigung der Merkmale eines bestimmten Ressourcen- oder Anwendungsdatentyps erstellt.
Wenn Sie beispielsweise eine
GET
Anforderung an den Endpunkt
/api/v1/flavors
ausführen
/api/v1/flavors
wird erwartet, dass eine Antwort gesendet wird, die ungefähr so aussieht:
[ { "id": 1, "name": "The Lazy Person's Movie Theater", "description": "That elusive flavor that you begrudgingly carted yourself to the theater for, now in the comfort of your own home, you slob!" }, { "id": 2, "name": "What's Wrong With You Caramel", "description": "You're a crazy person that likes sweet popcorn. Congratulations." }, { "id": 3, "name": "Gnarly Chili Lime", "description": "The kind of popcorn you make when you need a good smack in the face."} ]
An dieser Antwort ist nichts Katastrophales auszusetzen, aber lassen Sie uns über die Benutzeroberfläche nachdenken, oder vielmehr darüber, wie wir diese Daten nutzen wollen.
Wenn wir eine einfache Liste in der Benutzeroberfläche anzeigen möchten, die nur die Namen der verfügbaren Popcornsorten (und sonst nichts) enthält, sieht diese Liste möglicherweise wie die unten gezeigte aus.
Liste der Popcorn-TypenEs ist zu sehen, dass wir uns hier in einer schwierigen Situation befinden. Wir werden uns vielleicht entscheiden, das
description
nicht zu verwenden, aber werden wir uns zurücklehnen und so tun, als hätten wir dieses Feld nicht an den Kunden gesendet? Was können wir noch tun? Und wenn sie uns nach einigen Monaten fragen, warum die Anwendung für Benutzer so langsam ist, müssen wir nur den Typen lassen und uns nicht mehr mit dem Management des Unternehmens treffen, für das wir diese Anwendung erstellt haben.
Tatsächlich ist die Tatsache, dass der Server unnötige Daten als Antwort auf eine Clientanforderung sendet, nicht ganz unsere Schuld. REST ist ein Datenerfassungsmechanismus, der mit einem Restaurant verglichen werden kann, in dem der Kellner den Besucher fragt: „Was wollen Sie?“ Und ohne seine Wünsche besonders zu berücksichtigen, sagt er ihm: „Ich werde Ihnen bringen, was wir haben.“ .
Wenn wir Witze beiseite werfen, kann dies in realen Anwendungen zu Problemsituationen führen. Beispielsweise können wir verschiedene zusätzliche Informationen zu jeder Popcornsorte anzeigen, z. B. Preisinformationen, Informationen zum Hersteller oder Nährwertangaben („Veganes Popcorn!“). Gleichzeitig machen es unflexible REST-Endpunkte sehr schwierig, spezifische Daten zu bestimmten Popcornsorten zu erhalten, was zu einer unangemessen hohen Systembelastung und zu der Tatsache führt, dass die daraus resultierenden Lösungen weit von denen entfernt sind, auf die Entwickler stolz sein könnten.
Wie die GraphQL-Technologie verbessert, wofür die REST-Technologie verwendet wurde
Eine oberflächliche Analyse der oben beschriebenen Situation scheint, dass wir nur ein kleines Problem sind. "Was ist falsch daran, dem Client unnötige Daten zu senden?" Denken Sie daran, dass GraphQL von Facebook entwickelt wurde, um zu verstehen, inwieweit „unnötige Daten“ ein großes Problem darstellen können. Dieses Unternehmen muss Millionen von Anfragen pro Sekunde bearbeiten.
Was bedeutet das? Und die Tatsache, dass bei solchen Bänden alles zählt.
GraphQL bringt genau das, was der Besucher bestellt, wenn wir die Analogie mit einem Restaurant fortsetzen, anstatt dem Besucher „was ist“ zu „tragen“.
Wir können eine Antwort von GraphQL erhalten, die sich auf den Kontext konzentriert, in dem die Daten verwendet werden. In diesem Fall müssen wir dem System keine einmaligen Zugriffspunkte hinzufügen, viele Anforderungen ausführen oder mehrstöckige bedingte Strukturen schreiben.
Wie funktioniert GraphQL?
Wie bereits erwähnt, stützt sich GraphQL auf einfache
GET
oder
POST
Anforderungen, um Daten an den Client zu senden und von diesem zu empfangen. Wenn wir diese Idee genauer betrachten, stellt sich heraus, dass es in GraphQL zwei Arten von Abfragen gibt. Der erste Typ enthält Anforderungen zum Lesen von Daten, die in der GraphQL-Terminologie einfach als Abfragen bezeichnet werden und sich auf den Buchstaben R (Lesen, Lesen) des Akronyms CRUD beziehen. Abfragen der zweiten Art sind Datenänderungsanforderungen, die in GraphQL als Mutationen bezeichnet werden. Sie beziehen sich auf die Achskästen C, U und D des Akronyms CRUD, dh sie verwenden sie zum Erstellen, Erstellen, Aktualisieren und Löschen von Datensätzen.
Alle diese Abfragen und Mutationen werden in Form von
GET
oder
POST
Anforderungen an die URL des GraphQL-Servers gesendet, die beispielsweise wie
https://myapp.com/graphql
aussehen kann. Wir werden weiter unten mehr darüber sprechen.
GraphQL-Abfragen
GraphQL-Abfragen sind Entitäten, die eine Anforderung an den Server darstellen, bestimmte Daten zu empfangen. Zum Beispiel haben wir eine bestimmte Benutzeroberfläche, die wir mit Daten füllen möchten. Für diese Daten wenden wir uns an den Server und führen die Anforderung aus. Bei Verwendung herkömmlicher REST-APIs erfolgt unsere Anfrage in Form einer GET-Anfrage. Bei der Arbeit mit GraphQL wird eine neue Abfragesyntax verwendet:
{ flavors { name } }
Ist das JSON? Oder ein JavaScript-Objekt? Weder der eine noch der andere. Wie bereits erwähnt, bedeuten die letzten beiden Buchstaben QL im Namen der GraphQL-Technologie „Abfragesprache“, dh die Abfragesprache. Dies ist buchstäblich eine neue Sprache zum Schreiben von Datenanforderungen. All dies klingt nach einer Beschreibung von etwas ziemlich Kompliziertem, aber tatsächlich gibt es hier nichts Kompliziertes. Lassen Sie uns die obige Abfrage analysieren:
{ // , . }
Alle Anforderungen beginnen mit einer „Stammanforderung“. Was Sie während der Ausführung der Anforderung benötigen, wird als Feld bezeichnet. Um sich vor Verwirrung zu schützen, ist es am besten, diese Entitäten "Abfragefelder im Schema" zu nennen. Wenn Ihnen ein solcher Name unverständlich erscheint - warten Sie ein bisschen -, werden wir weiter unten mehr über das Schema sprechen. Hier fordern wir in der Stammabfrage das Feld
flavors
.
{ flavors { // , flavor. } }
Wenn Sie ein bestimmtes Feld anfordern, müssen Sie auch die verschachtelten Felder angeben, die für jedes Objekt empfangen werden müssen, das als Antwort auf die Anforderung eingeht (auch wenn erwartet wird, dass nur ein Objekt als Antwort auf die Anforderung eingeht).
{ flavors { name } }
Was wird das Ergebnis sein? Nachdem wir eine solche Anfrage an den GraphQL-Server gesendet haben, erhalten wir eine wohlgeformte Antwort wie die folgende:
{ "data": { "flavors": [ { "name": "The Lazy Person's Movie Theater" }, { "name": "What's Wrong With You Caramel" }, { "name": "Gnarly Chili Lime" } ] } }
Bitte beachten Sie, dass nichts überflüssig ist. Um dies klarer zu machen, wird hier eine weitere Anforderung ausgeführt, um Daten auf einer anderen Seite der Anwendung abzurufen:
{ flavors { id name description } }
Als Antwort auf diese Anfrage erhalten wir Folgendes:
{ "data": { "flavors": [ { "id": 1, "name": "The Lazy Person's Movie Theater", description: "That elusive flavor that you begrudgingly carted yourself to the theater for, now in the comfort of your own home, you slob!" }, { "id": 2, "name": "What's Wrong With You Caramel", description: "You're a crazy person that likes sweet popcorn. Congratulations." }, { "id": 3, "name": "Gnarly Chili Lime", description: "A friend told me this would taste good. It didn't. It burned my kernels. I haven't had the heart to tell him." } ] } }
Wie Sie sehen können, ist GraphQL eine sehr leistungsfähige Technologie. Wir wenden uns demselben Endpunkt zu, und die Antworten auf die Anforderungen entsprechen genau dem, was zum Ausfüllen der Seite erforderlich ist, von der aus diese Anforderungen ausgeführt werden.
Wenn wir nur ein
flavor
Objekt benötigen, können wir die Tatsache nutzen, dass GraphQL mit Argumenten arbeiten kann:
{ flavors(id: "1") { id name description } }
Hier setzen wir den spezifischen Bezeichner (
id
) des Objekts im Code fest, die Informationen, die wir benötigen, aber in solchen Fällen können wir dynamische Bezeichner verwenden:
query getFlavor($id: ID) { flavors(id: $id) { id name description } }
Hier geben wir in der ersten Zeile der Anfrage einen Namen (der Name wird willkürlich gewählt,
getFlavor
kann durch etwas wie
pizza
werden und die Anfrage bleibt betriebsbereit) und deklarieren die Variablen, die die Anfrage erwartet. In diesem Fall wird davon ausgegangen, dass der Bezeichner (
id
) der skalaren Typ-
ID
an die Anforderung übergeben wird (wir werden im Folgenden auf Typen eingehen).
Unabhängig davon, ob beim Ausführen einer Anforderung eine statische oder eine dynamische
id
verwendet wird, sieht die Antwort auf eine ähnliche Anforderung folgendermaßen aus:
{ "data": { "flavors": [ { "id": 1, "name": "The Lazy Person's Movie Theater", description: "That elusive flavor that you begrudgingly carted yourself to the theater for, now in the comfort of your own home, you slob!" } ] } }
Wie Sie sehen können, ist alles sehr bequem angeordnet. Sie fangen wahrscheinlich an, über die Verwendung von GraphQL in Ihrem eigenen Projekt nachzudenken. Und obwohl das, worüber wir bereits gesprochen haben, wunderbar aussieht, manifestiert sich die Schönheit von GraphQL wirklich dort, wo es mit verschachtelten Feldern funktioniert. Angenommen, in unserem Schema gibt es ein anderes Feld namens
nutrition
, das Informationen über den Nährwert verschiedener Popcornsorten enthält:
{ flavors { id name nutrition { calories fat sodium } } }
Es scheint, dass in unserem Data Warehouse jedes
flavor
ein verschachteltes
nutrition
. Dies ist jedoch nicht ganz richtig. Mit GraphQL können Sie Aufrufe unabhängiger, aber verwandter Datenquellen in einer einzigen Abfrage kombinieren. Auf diese Weise erhalten Sie Antworten, mit denen Sie bequem mit eingebetteten Daten arbeiten können, ohne die Datenbank denormalisieren zu müssen:
{ "data": { "flavors": [ { "id": 1, "name": "The Lazy Person's Movie Theater", "nutrition": { "calories": 500, "fat": 12, "sodium": 1000 } }, ... ] } }
Dies kann die Produktivität des Programmiergeräts und die Geschwindigkeit des Systems erheblich steigern.
Bisher haben wir über Leseanfragen gesprochen. Was ist mit Datenaktualisierungsanfragen? Geben wir ihnen den gleichen Komfort?
GraphQL-Mutationen
Während GraphQL-Abfragen Daten laden, sind Mutationen dafür verantwortlich, Änderungen an den Daten vorzunehmen. Mutationen können in Form des grundlegenden RPC-Mechanismus (Remote Procedure Call) zum Lösen verschiedener Aufgaben verwendet werden, z. B. zum Senden von Benutzerdaten an eine Drittanbieter-API.
Bei der Beschreibung von Mutationen wird eine Syntax verwendet, die der beim Generieren von Abfragen verwendeten ähnelt:
mutation updateFlavor($id: ID!, $name: String, $description: String) { updateFlavor(id: $id, name: $name, description: $description) { id name description } }
Hier deklarieren wir die
updateFlavor
Mutation und geben einige Variablen an -
id
,
name
und
description
. Nach dem gleichen Schema, das zur Beschreibung von Abfragen verwendet wird, erstellen wir Variablenfelder (Root-Mutation) mit dem Schlüsselwort
mutation
, gefolgt von einem Namen, der die Mutation beschreibt, und einer Reihe von Variablen, die zur Bildung der entsprechenden Datenänderungsanforderung erforderlich sind.
Zu diesen Variablen gehört, was wir ändern möchten oder welche Mutation wir verursachen möchten. Bitte beachten Sie auch, dass wir nach der Mutation die Rückgabe einiger Felder beantragen können.
In diesem Fall müssen wir nach dem Ändern des Datensatzes die Felder
id
,
name
und
description
abrufen. Dies kann nützlich sein, wenn Sie so etwas wie optimistische Schnittstellen entwickeln, sodass Sie keine Anforderung mehr erfüllen müssen, um geänderte Daten nach dem Ändern zu erhalten.
Entwerfen eines Schemas und Verbinden mit einem GraphQL-Server
Bisher haben wir darüber gesprochen, wie GraphQL auf dem Client funktioniert und wie sie Abfragen ausführen. Lassen Sie uns nun darüber sprechen, wie Sie auf diese Anfragen reagieren können.
▍GraphQL-Server
Um eine GraphQL-Abfrage auszuführen, benötigen Sie einen GraphQL-Server, an den Sie eine solche Abfrage senden können. Ein GraphQL-Server ist ein normaler HTTP-Server (wenn Sie in JavaScript schreiben, kann es sich um einen mit Express oder Hapi erstellten Server handeln), an den ein GraphQL-Diagramm angehängt ist.
import express from 'express' import graphqlHTTP from 'express-graphql' import schema from './schema' const app = express() app.use('/graphql', graphqlHTTP({ schema: schema, graphiql: true })) app.listen(4000)
Mit "Beitreten" zu einem Schema meinen wir einen Mechanismus, der vom Client empfangene Anforderungen über das Schema weiterleitet und Antworten darauf zurückgibt. Es ist wie ein Luftfilter, durch den Luft in den Raum gelangt.
Der Prozess des "Filterns" ist mit Anforderungen oder Mutationen verbunden, die vom Client an den Server gesendet werden. Sowohl Abfragen als auch Mutationen werden mithilfe von Funktionen aufgelöst, die sich auf die in der Stammabfrage oder in der Stammmutation des Schemas definierten Felder beziehen.
Das obige Beispiel zeigt ein HTTP-Server-Framework, das mit der Express-JavaScript-Bibliothek erstellt wurde. Mit der
graphqlHTTP
Funktion aus dem
express-graphql
von Facebook „hängen“ wir das Schema an (es wird angenommen, dass es in einer separaten Datei beschrieben wird) und führen den Server auf Port 4000 aus. Das heißt, Clients, die über die lokale Verwendung dieses Servers sprechen, können Anfragen über senden Adresse
http://localhost:4000/graphql
.
▍ Datentypen und Resolver
Um den Betrieb des GraphQL-Servers sicherzustellen, müssen Sie das Schema vorbereiten und daran anhängen.
Denken Sie daran, dass wir oben über das Deklarieren von Feldern in einer Root-Abfrage oder in einer Root-Mutation gesprochen haben.
import gql from 'graphql-tag' import mongodb from '/path/to/mongodb' // - . , `mongodb` MongoDB. const schema = { typeDefs: gql` type Nutrition { flavorId: ID calories: Int fat: Int sodium: Int } type Flavor { id: ID name: String description: String nutrition: Nutrition } type Query { flavors(id: ID): [Flavor] } type Mutation { updateFlavor(id: ID!, name: String, description: String): Flavor } `, resolvers: { Query: { flavors: (parent, args) => { // , args , { id: '1' } return mongodb.collection('flavors').find(args).toArray() }, }, Mutation: { updateFlavor: (parent, args) => { // , args { id: '1', name: 'Movie Theater Clone', description: 'Bring the movie theater taste home!' } // . mongodb.collection('flavors').update(args) // flavor . return mongodb.collection('flavors').findOne(args.id) }, }, Flavor: { nutrition: (parent) => { return mongodb.collection('nutrition').findOne({ flavorId: parent.id, }) } }, }, } export default schema
Die Definition von Feldern in einem GraphQL-Schema besteht aus zwei Teilen - aus Typdeklarationen (
typeDefs
) und
resolver
. Die
typeDefs
enthält Typdeklarationen für die in der Anwendung verwendeten Daten. Zum Beispiel haben wir früher über eine Anfrage gesprochen, eine Liste von
flavor
Objekten vom Server zu erhalten. Um eine ähnliche Anfrage an unseren Server zu stellen, müssen Sie die folgenden drei Schritte ausführen:
- Teilen Sie dem Schema mit, wie die
flavor
Objektdaten aussehen (im obigen Beispiel sieht es aus wie eine Anzeige vom type Flavor
). - Deklarieren Sie das Feld im Stammfeld vom
type Query
(dies ist die flavors
Eigenschaft des type Query
). - Deklarieren Sie eine
resolvers.Query
Objekterkennungsfunktion, die gemäß den im Stammfeld vom type Query
deklarierten Feldern geschrieben wurde.
Lassen Sie uns nun auf
typeDefs
. Hier geben wir dem Schema Informationen über die Form unserer Daten. Mit anderen Worten, wir informieren GraphQL über die verschiedenen Eigenschaften, die in Entitäten des entsprechenden Typs enthalten sein können.
type Flavor { id: ID name: String description: String nutrition: Nutrition }
Eine
type Flavor
Deklaration gibt an, dass ein
flavor
Objekt ein
id
Feld vom Typ
ID
, ein Namensfeld vom Typ
String
, ein
description
vom Typ
String
und ein
nutrition
vom Typ
Nutrition
.
Im Falle der
nutrition
wir hier den Namen eines anderen Typs, der in
typeDefs
deklariert
typeDefs
. Hier beschreibt der
type Nutrition
Konstrukt die Nährwertform von Popcorn.
Beachten Sie, dass es sich hier wie ganz am Anfang dieses Materials um eine „Anwendung“ und nicht um eine „Datenbank“ handelt. Im obigen Beispiel wird davon ausgegangen, dass wir eine Datenbank haben, die Daten in der Anwendung können jedoch aus einer beliebigen Quelle stammen. Es kann sich sogar um eine API eines Drittanbieters oder eine statische Datei handeln.
Genau wie in der
type Flavor
geben wir hier die Namen der Felder an, die in
nutrition
werden, wobei wir als Datentypen dieser Felder (Eigenschaften) das verwenden, was in GraphQL als skalare Datentypen bezeichnet wird. Zum Zeitpunkt dieses Schreibens unterstützte GraphQL
5 integrierte skalare Datentypen :
Int
: vorzeichenbehaftete 32-Bit-Ganzzahl.Float
: Eine Gleitkommazahl mit doppelter Genauigkeit und einem Vorzeichen.- Zeichenfolge: Eine in UTF-8 codierte Folge von Zeichen.
Boolean
: Boolean true
oder false
.ID
: Eine eindeutige Kennung, die häufig zum wiederholten Laden von Objekten oder als Schlüssel im Cache verwendet wird. Werte der Typ- ID
wie Zeichenfolgen serialisiert. Ein Hinweis darauf, dass ein ID
Typ einen Wert hat, wird jedoch dadurch hervorgehoben, dass dieser Wert nicht für Personen angezeigt werden soll, sondern für die Verwendung in Programmen.
Zusätzlich zu diesen Skalartypen können wir Typen, die wir selbst definieren, Eigenschaften zuweisen. Dies ist genau das, was wir getan haben, indem wir die
nutrition
zugewiesen haben, die im
type Flavor
, Typ
Nutrition
.
type Query { flavors(id: ID): [Flavor] }
Im Konstrukt vom Typ "Abfrage", das den Stammtyp der
Query
(die "Stammabfrage", über die wir zuvor gesprochen haben), deklarieren wir den Namen des Felds, das angefordert werden kann. Durch Deklarieren dieses Felds geben wir zusätzlich zusammen mit dem Datentyp, den wir voraussichtlich zurückgeben, die Argumente an, die in der Anforderung enthalten sein können.
In diesem Beispiel erwarten wir einen möglichen Empfang des
id
Arguments einer skalaren Typ-
ID
. Als Antwort auf eine solche Anfrage wird ein Array von Objekten erwartet, deren Gerät einem Gerät vom Typ
Flavor
ähnelt.
▍Verbinden des Abfrageerkenners
Nachdem wir nun eine Feldtypdefinition in der
type Query
, müssen wir beschreiben, was als Resolverfunktion bezeichnet wird.
— , GraphQL, , «».
resolvers
,
Query
, ,
flavors
, .
flavors
,
type Query
.
typeDefs: gql`…`, resolvers: { Query: { flavors: (parent, args) => { // , args { id: '1' } return mongodb.collection('flavors').find(args).toArray() }, }, … },
- .
parent
— , ,
args
, .
context
, . «» ( — , ).
, , . GraphQL « » . , , .
GraphQL , , . JSON-, JSON-, ( GraphQL ).
-
flavors
MongoDB,
args
( )
.find()
, , .
▍
-, GraphQL, , , ,
nutrition
. , ,
Nutrition
, , , ,
flavor
. , / .
GraphQL ,
type Flavor
nutrition
type Nutrition
, . , ,
flavor
.
typeDefs: gql` type Nutrition { flavorId: ID calories: Int fat: Int sodium: Int } type Flavor { […] nutrition: Nutrition } type Query {…} type Mutation {…} `, resolvers: { Query: { flavors: (parent, args) => {…}, }, Mutation: {…}, Flavor: { nutrition: (parent) => { return mongodb.collection('nutrition').findOne({ flavorId: parent.id, }) } }, },
resolvers
, ,
Query
,
Mutation
Flavor
. ,
typeDefs
.
Flavors
, ,
nutrition
-. ,
Flavor
. , : « ,
nutrition
,
type Flavor
».
MongoDB, ,
parent
, -. ,
parent
, , ,
flavors
. ,
flavor
, :
{ flavors { id name nutrition { calories } } }
flavor
,
flavors
,
nutrition
,
parent
. , , , MongoDB,
parent.id
,
id
flavor
, .
parent.id
,
nutrition
flavorId
,
flavor
.
▍
, , . , .
type Mutation
, ,
updateFlavor
, , .
type Mutation { updateFlavor(id: ID!, name: String, description: String): Flavor }
: « ,
updateFlavor
id
ID
( ,
!
, GraphQL , ),
name
String
description
String
». , ,
Flavor
( — ,
id
,
name
,
description
, , ,
nutrition
).
{ typeDefs: gql`…`, resolvers: { Mutation: { updateFlavor: (parent, args) => { // , args { id: '1', name: 'Movie Theater Clone', description: 'Bring the movie theater taste home!' } // . mongodb.collection('flavors').update( { id: args.id }, { $set: { ...args, }, }, ) // flavor . return mongodb.collection('flavors').findOne(args.id) }, }, }, }
-
updateFlavor
, : , , — ,
flavor
.
, ,
flavor
. ?
, , . ,
flavor
, .
args
? Ja, das kannst du. , , , 100% , . , , , , , .
GraphQL?
, , , , , GraphQL-API.
, GraphQL , . , . , . , , , GraphQL REST . , , , GraphQL.
▍ ,
, HTTP-, , , , — . GraphQL , , , , ( ).
, , ( — ), GraphQL .
▍ , ,
, , « ». , , , . . GraphQL .
▍ ,
REST API, : , . , -, iOS Android, API . , , , , « » .
, , , HTTP, API (, , ).
▍ GraphQL — ? REST API GraphQL?
Nein, natürlich. . , , GraphQL . GraphQL, . , , , . , , .
, GraphQL , , , . GraphQL , Apollo Relay, .
GraphQL — , , .
graphql
(
express-graphql
, ) — . , GraphQL - . , -, , , , .
Zusammenfassung
, GraphQL , . GraphQL , , , . , , , , GraphQL.
, : GraphQL . GraphQL . , GraphQL, , , , , , , .
— , GraphQL — , , . GraphQL , . , GraphQL — , , , . . , , , , , , GraphQL.
Liebe Leser! GraphQL — , .
