Détails GraphQL: quoi, comment et pourquoi

GraphQL est maintenant, sans exagĂ©ration, c'est le dernier coup d'oeil du mode informatique. Et si vous ne savez pas encore de quel type de technologie il s'agit, comment l'utiliser et pourquoi elle peut vous ĂȘtre utile, l'article que nous publions aujourd'hui est Ă©crit pour vous. Nous allons ici passer en revue les bases de GraphQL en utilisant un exemple d'implĂ©mentation d'un schĂ©ma de donnĂ©es pour l'API d'une entreprise de pop-corn. Parlons en particulier des types de donnĂ©es, des requĂȘtes et des mutations.



Qu'est-ce que GraphQL?


GraphQL est un langage de requĂȘte utilisĂ© par les applications clientes pour travailler avec les donnĂ©es. GraphQL est associĂ© Ă  un concept tel que «schĂ©ma» - c'est ce qui vous permet d'organiser la crĂ©ation, la lecture, la mise Ă  jour et la suppression de donnĂ©es dans votre application (c'est-Ă -dire que nous avons quatre fonctions de base utilisĂ©es lorsque nous travaillons avec des entrepĂŽts de donnĂ©es, qui sont gĂ©nĂ©ralement dĂ©signĂ©s par l'acronyme CRUD - crĂ©er, lire, mettre Ă  jour, supprimer).

Il a Ă©tĂ© dit plus haut que GraphQL est utilisĂ© pour travailler avec des donnĂ©es dans «votre application», et non «dans votre base de donnĂ©es». Le fait est que GraphQL est un systĂšme indĂ©pendant des sources de donnĂ©es, c'est-Ă -dire qu'il importe peu oĂč il est organisĂ© pour organiser son travail.

Si vous regardez, sans rien savoir de GraphQL, sur le nom de cette technologie, il peut sembler que nous sommes confrontĂ©s Ă  quelque chose de trĂšs compliquĂ© et dĂ©routant. Le nom de la technologie a le mot «graphique». Est-ce Ă  dire que pour le maĂźtriser, il faut apprendre Ă  travailler avec des bases de donnĂ©es graphiques? Et le fait que le nom contienne «QL» (qui peut signifier «langage de requĂȘte», c'est-Ă -dire «langage de requĂȘte»), cela signifie-t-il que ceux qui veulent utiliser GraphQL devront apprendre un tout nouveau langage de programmation?

Ces craintes ne sont pas entiĂšrement justifiĂ©es. Afin de vous rassurer - c'est la cruelle vĂ©ritĂ© sur cette technologie: il s'agit simplement d'embellir des requĂȘtes GET ou POST . Alors que GraphQL, en gĂ©nĂ©ral, introduit de nouveaux concepts liĂ©s Ă  l'organisation des donnĂ©es et Ă  leur interaction, les mĂ©canismes internes de cette technologie reposent sur les bonnes vieilles requĂȘtes HTTP.

Repenser la technologie REST


La flexibilité est ce qui distingue la technologie GraphQL de la technologie REST bien connue. Lorsque vous utilisez REST, si tout est fait correctement, les noeuds finaux sont généralement créés en tenant compte des caractéristiques d'un certain type de données de ressource ou d'application.

Par exemple, lors de l'exécution d'une demande GET vers le point de terminaison /api/v1/flavors il est prévu qu'il envoie une réponse qui ressemble à ceci:

 [ {  "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."} ] 

Il n'y a rien de catastrophique dans cette réponse, mais réfléchissons à l'interface utilisateur, ou plutÎt à la façon dont nous avons l'intention de consommer ces données.

Si nous voulons afficher une simple liste dans l'interface qui ne contient que les noms des types de pop-corn disponibles (et rien d'autre), cette liste peut ressembler à celle illustrée ci-dessous.


Liste des types de pop-corn

On peut voir que nous sommes ici dans une situation difficile. Nous pouvons bien décider de ne pas utiliser le champ de description , mais allons-nous nous asseoir et prétendre que nous n'avons pas envoyé ce champ au client? Que pouvons-nous faire d'autre? Et quand, au bout de quelques mois, ils nous demanderont pourquoi l'application est si lente pour les utilisateurs, il suffit de laisser le gars et de ne plus rencontrer la direction de l'entreprise pour laquelle nous avons fait cette application.

En fait, le fait que le serveur envoie des donnĂ©es inutiles en rĂ©ponse Ă  une demande client n'est pas entiĂšrement de notre faute. REST est un mĂ©canisme d'acquisition de donnĂ©es qui peut ĂȘtre comparĂ© Ă  un restaurant dans lequel le serveur demande au visiteur: "Qu'est-ce que tu veux?" .

Si nous mettons de cĂŽtĂ© les blagues, dans les applications rĂ©elles, cela peut conduire Ă  des situations problĂ©matiques. Par exemple, nous pouvons afficher diverses informations supplĂ©mentaires sur chaque type de pop-corn, telles que des informations sur les prix, des informations sur le fabricant ou des informations nutritionnelles («Popcorn vĂ©gĂ©talien!»). Dans le mĂȘme temps, les points de terminaison REST rigides rendent trĂšs difficile l'obtention de donnĂ©es spĂ©cifiques sur des types spĂ©cifiques de pop-corn, ce qui conduit Ă  une charge dĂ©raisonnablement Ă©levĂ©e sur les systĂšmes et au fait que les solutions qui en rĂ©sultent sont loin de celles dont les dĂ©veloppeurs pourraient ĂȘtre fiers.

Comment la technologie GraphQL améliore l'utilisation de la technologie REST


Une analyse superficielle de la situation dĂ©crite ci-dessus peut sembler que nous ne sommes qu'un problĂšme mineur. "Quel est le problĂšme avec l'envoi au client de donnĂ©es inutiles?" Afin de comprendre dans quelle mesure les «donnĂ©es inutiles» peuvent ĂȘtre un gros problĂšme, n'oubliez pas que GraphQL a Ă©tĂ© dĂ©veloppĂ© par Facebook. Cette entreprise doit rĂ©pondre Ă  des millions de demandes par seconde.

Qu'est-ce que cela signifie? Et le fait qu'avec de tels volumes, chaque petite chose compte.

GraphQL, si nous continuons l'analogie avec un restaurant, au lieu de «porter» au visiteur «ce qui est», apporte exactement ce que le visiteur commande.

Nous pouvons obtenir une réponse de GraphQL qui se concentre sur le contexte dans lequel les données sont utilisées. Dans ce cas, nous n'avons pas besoin d'ajouter des points d'accÚs «uniques» au systÚme, d'effectuer de nombreuses demandes ou d'écrire des structures conditionnelles à plusieurs étages.

Comment fonctionne GraphQL?


Comme nous l'avons dĂ©jĂ  dit, GraphQL s'appuie sur de simples requĂȘtes GET ou POST pour transmettre des donnĂ©es au client et les recevoir de lui. Si nous considĂ©rons cette idĂ©e plus en dĂ©tail, il s'avĂšre qu'il existe deux types de requĂȘtes dans GraphQL. Le premier type comprend les demandes de lecture de donnĂ©es, qui dans la terminologie GraphQL sont simplement appelĂ©es requĂȘtes et font rĂ©fĂ©rence Ă  la lettre R (lecture, lecture) de l'acronyme CRUD. Les requĂȘtes du deuxiĂšme type sont des demandes de modification de donnĂ©es, appelĂ©es mutations dans GraphQL. Ils concernent les boĂźtes d'essieux C, U et D de l'acronyme CRUD, c'est-Ă -dire qu'ils les utilisent pour crĂ©er, crĂ©er, mettre Ă  jour et supprimer des enregistrements.

Toutes ces requĂȘtes et mutations sont envoyĂ©es Ă  l'URL du serveur GraphQL, qui peut par exemple ressembler Ă  https://myapp.com/graphql , sous forme de requĂȘtes GET ou POST . Nous en parlerons plus loin ci-dessous.

RequĂȘtes GraphQL


Les requĂȘtes GraphQL sont des entitĂ©s reprĂ©sentant une demande au serveur de recevoir certaines donnĂ©es. Par exemple, nous avons une certaine interface utilisateur que nous voulons remplir de donnĂ©es. Pour ces donnĂ©es, nous nous tournons vers le serveur, exĂ©cutant la demande. Lorsque vous utilisez des API REST traditionnelles, notre demande prend la forme d'une demande GET. Lorsque vous travaillez avec GraphQL, une nouvelle syntaxe de requĂȘte est utilisĂ©e:

 { flavors {   name } } 

Est-ce JSON? Ou un objet JavaScript? Ni l'un ni l'autre. Comme nous l'avons dĂ©jĂ  dit, au nom de la technologie GraphQL, les deux derniĂšres lettres, QL, signifient «langage de requĂȘte», c'est-Ă -dire le langage de requĂȘte. C'est, littĂ©ralement, un nouveau langage pour Ă©crire des demandes de donnĂ©es. Tout cela ressemble Ă  une description de quelque chose de plutĂŽt compliquĂ©, mais en fait il n'y a rien de compliquĂ© ici. Analysons la requĂȘte ci-dessus:

 { //    ,   . } 

Toutes les demandes commencent par une «demande racine» et ce que vous devez obtenir lors de l'exĂ©cution de la demande s'appelle un champ. Afin de vous Ă©viter la confusion, il est prĂ©fĂ©rable d'appeler ces entitĂ©s «champs de requĂȘte dans le schĂ©ma». Si un tel nom vous semble incomprĂ©hensible - attendez un peu - ci-dessous, nous parlerons davantage du schĂ©ma. Ici, dans la requĂȘte racine, nous demandons le champ des flavors .

 { flavors {   //  ,        flavor. } } 

Lors de la demande d'un certain champ, nous devons Ă©galement indiquer les champs imbriquĂ©s qui doivent ĂȘtre reçus pour chaque objet qui vient en rĂ©ponse Ă  la demande (mĂȘme s'il est prĂ©vu qu'un seul objet viendra en rĂ©ponse Ă  la demande).

 { flavors {   name } } 

Quel sera le résultat? AprÚs avoir envoyé une telle demande au serveur GraphQL, nous obtiendrons une réponse nette et bien formée, comme la suivante:

 { "data": {   "flavors": [     { "name": "The Lazy Person's Movie Theater" },     { "name": "What's Wrong With You Caramel" },     { "name": "Gnarly Chili Lime" }   ] } } 

Veuillez noter qu'il n'y a rien de superflu. Afin de le rendre plus clair, voici une autre requĂȘte qui est exĂ©cutĂ©e pour obtenir des donnĂ©es sur une autre page de l'application:

 { flavors {   id   name   description } } 

En réponse à cette demande, nous obtenons ce qui suit:

 { "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." }   ] } } 

Comme vous pouvez le voir, GraphQL est une technologie trĂšs puissante. Nous nous tournons vers le mĂȘme point de terminaison, et les rĂ©ponses aux demandes correspondent exactement Ă  ce qui est nĂ©cessaire pour remplir la page Ă  partir de laquelle ces demandes sont exĂ©cutĂ©es.

Si nous devons obtenir un seul objet de flavor , nous pouvons profiter du fait que GraphQL peut fonctionner avec des arguments:

 { flavors(id: "1") {   id   name   description } } 

Ici, nous définissons de maniÚre rigide l'identifiant spécifique ( id ) de l'objet dans le code, les informations dont nous avons besoin, mais dans de tels cas, nous pouvons utiliser des identifiants dynamiques:

 query getFlavor($id: ID) { flavors(id: $id) {   id   name   description } } 

Ici, dans la premiĂšre ligne, nous donnons un nom Ă  la demande (le nom est choisi arbitrairement, getFlavor peut ĂȘtre remplacĂ© par quelque chose comme pizza , et la demande restera opĂ©rationnelle) et dĂ©clarons les variables que la demande attend. Dans ce cas, on suppose que l'identifiant ( id ) de l' ID type scalaire sera transmis Ă  la requĂȘte (nous parlerons des types ci-dessous).

Peu importe si un id statique ou dynamique id utilisé lors de l'exécution d'une demande, voici à quoi ressemblera la réponse à une demande similaire:

 { "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!" }   ] } } 

Comme vous pouvez le voir, tout est arrangĂ© de maniĂšre trĂšs pratique. Vous commencez probablement Ă  penser Ă  utiliser GraphQL dans votre propre projet. Et, bien que ce dont nous avons dĂ©jĂ  parlĂ© soit magnifique, la beautĂ© de GraphQL se manifeste vraiment lĂ  oĂč il fonctionne avec des champs imbriquĂ©s. Supposons que dans notre schĂ©ma, il existe un autre domaine appelĂ© nutrition qui contient des informations sur la valeur nutritionnelle de diffĂ©rents types de pop-corn:

 { flavors {   id   name   nutrition {     calories     fat     sodium   } } } 

Il peut sembler que dans notre entrepĂŽt de donnĂ©es, chaque objet de flavor contiendra un objet nutrition imbriquĂ©. Mais ce n'est pas tout Ă  fait vrai. À l'aide de GraphQL, vous pouvez combiner des appels Ă  des sources de donnĂ©es indĂ©pendantes mais liĂ©es dans une seule requĂȘte, ce qui vous permet de recevoir des rĂ©ponses qui offrent la commoditĂ© de travailler avec des donnĂ©es incorporĂ©es sans avoir besoin de dĂ©normaliser la base de donnĂ©es:

 { "data": {   "flavors": [     {       "id": 1,       "name": "The Lazy Person's Movie Theater",       "nutrition": {         "calories": 500,         "fat": 12,         "sodium": 1000       }     },     ...   ] } } 

Cela peut augmenter considérablement la productivité du programmeur et la vitesse du systÚme.

Jusqu'Ă  prĂ©sent, nous avons parlĂ© des demandes de lecture. Qu'en est-il des demandes de mise Ă  jour des donnĂ©es? Les utiliser nous donne-t-il la mĂȘme commoditĂ©?

Mutations GraphQL


Tandis que les requĂȘtes GraphQL chargent des donnĂ©es, les mutations sont responsables d'apporter des modifications aux donnĂ©es. Les mutations peuvent ĂȘtre utilisĂ©es sous la forme du mĂ©canisme de base RPC (Remote Procedure Call) pour rĂ©soudre diverses tĂąches, telles que l'envoi de donnĂ©es utilisateur Ă  une API tierce.

Lors de la description des mutations, une syntaxe similaire Ă  celle utilisĂ©e lors de la gĂ©nĂ©ration des requĂȘtes est utilisĂ©e:

 mutation updateFlavor($id: ID!, $name: String, $description: String) { updateFlavor(id: $id, name: $name, description: $description) {   id   name   description } } 

Ici, nous dĂ©clarons la mutation updateFlavor , en spĂ©cifiant certaines variables - id , name et description . En agissant selon le mĂȘme schĂ©ma que celui utilisĂ© pour dĂ©crire les requĂȘtes, nous «établissons» des champs de variables (mutation racine) Ă  l'aide du mot-clĂ© mutation , suivis d'un nom dĂ©crivant la mutation et d'un ensemble de variables nĂ©cessaires pour former la demande de changement de donnĂ©es correspondante.

Ces variables incluent ce que nous essayons de changer ou quelle mutation nous voulons provoquer. Veuillez également noter qu'aprÚs la mutation, nous pouvons demander le retour de certains champs.

Dans ce cas, nous devons obtenir, aprĂšs avoir modifiĂ© l'enregistrement, les champs id , name et description . Cela peut ĂȘtre utile lors du dĂ©veloppement de quelque chose comme des interfaces optimistes, Ă©liminant ainsi la nĂ©cessitĂ© de rĂ©pondre Ă  une demande de rĂ©ception de donnĂ©es modifiĂ©es aprĂšs les avoir modifiĂ©es.

Concevoir un schéma et le connecter à un serveur GraphQL


Jusqu'Ă  prĂ©sent, nous avons parlĂ© du fonctionnement de GraphQL sur le client et de la façon dont ils exĂ©cutent les requĂȘtes. Voyons maintenant comment rĂ©pondre Ă  ces demandes.

Server Serveur GraphQL


Pour exĂ©cuter une requĂȘte GraphQL, vous avez besoin d'un serveur GraphQL auquel vous pouvez envoyer une telle requĂȘte. Un serveur GraphQL est un serveur HTTP standard (si vous Ă©crivez en JavaScript, il peut s'agir d'un serveur créé en utilisant Express ou Hapi), auquel un diagramme GraphQL est attachĂ©.

 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) 

Par «rejoindre» un schéma, nous entendons un mécanisme qui transmet les demandes reçues du client via le schéma et y renvoie des réponses. C'est comme un filtre à air à travers lequel l'air pénÚtre dans la piÚce.

Le processus de "filtrage" est associĂ© aux requĂȘtes ou mutations envoyĂ©es par le client au serveur. Les requĂȘtes et les mutations sont rĂ©solues Ă  l'aide de fonctions liĂ©es aux champs dĂ©finis dans la requĂȘte racine ou dans la mutation racine du schĂ©ma.

Ce qui prĂ©cĂšde est un exemple d'infrastructure de serveur HTTP créé Ă  l'aide de la bibliothĂšque JavaScript Express. En utilisant la fonction express-graphql de Facebook, nous «attachons» le schĂ©ma (on suppose qu'il est dĂ©crit dans un fichier sĂ©parĂ©) et exĂ©cutons le serveur sur le port 4000. Autrement dit, les clients, parlant de l'utilisation locale de ce serveur, pourront envoyer des requĂȘtes via adresse http://localhost:4000/graphql .

▍ Types de donnĂ©es et rĂ©solveurs


Afin d'assurer le fonctionnement du serveur GraphQL, vous devez préparer le schéma et le joindre à celui-ci.

Rappelons que nous avons parlĂ© de dĂ©clarer des champs dans une requĂȘte racine ou dans une mutation racine ci-dessus.

 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 

La définition des champs dans un schéma GraphQL se compose de deux parties - à partir des déclarations de type ( typeDefs ) et des resolver . L' typeDefs contient des déclarations de type pour les données utilisées dans l'application. Par exemple, plus tÎt, nous avons parlé d'une demande pour obtenir une liste d'objets de flavor du serveur. Afin de faire une demande similaire à notre serveur, vous devez effectuer les trois étapes suivantes:

  1. Indiquez au schéma à quoi ressemblent les données de l'objet de flavor (dans l'exemple ci-dessus, elles ressemblent à une annonce de type Flavor ).
  2. Déclarez le champ dans le champ racine de type Query (il s'agit de la propriété flavors de la valeur de type Query ).
  3. Déclarez une fonction de reconnaissance d'objet resolvers.Query écrite conformément aux champs déclarés dans le champ racine de type Query .

typeDefs maintenant attention Ă  typeDefs . Ici, nous donnons les informations de schĂ©ma sur la forme de nos donnĂ©es. En d'autres termes, nous informons GraphQL des diffĂ©rentes propriĂ©tĂ©s qui peuvent ĂȘtre contenues dans des entitĂ©s du type correspondant.

 type Flavor { id: ID name: String description: String nutrition: Nutrition } 

Une déclaration de type Flavor indique qu'un objet type Flavor peut contenir un champ id de type ID , un champ de name de type String , un champ de description de type String et un champ de nutrition de type Nutrition .

Dans le cas de la nutrition nous utilisons ici le nom d'un type différent déclaré dans typeDefs . Ici, le type Nutrition construction type Nutrition décrit la forme de données nutritionnelles du pop-corn.

Faites attention au fait qu'ici, comme au tout dĂ©but de ce document, nous parlons d'une «application» et non d'une «base de donnĂ©es». Dans l'exemple ci-dessus, on suppose que nous avons une base de donnĂ©es, mais les donnĂ©es de l'application peuvent provenir de n'importe quelle source. Il peut mĂȘme s'agir d'une API tierce ou d'un fichier statique.

Tout comme nous l'avons fait dans la déclaration de type Flavor , nous indiquons ici les noms des champs qui seront contenus dans les objets de nutrition , en utilisant, comme types de données de ces champs (propriétés), ce qui dans GraphQL est appelé types de données scalaires. Au moment d'écrire ces lignes, GraphQL supportait 5 types de données scalaires intégrés :

  • Int : entier 32 bits signĂ©.
  • Float : un nombre Ă  virgule flottante double prĂ©cision avec un signe.
  • String : une sĂ©quence de caractĂšres encodĂ©s en UTF-8.
  • Boolean : Boolean true or false .
  • ID : identifiant unique souvent utilisĂ© pour charger Ă  plusieurs reprises des objets ou comme clĂ© dans le cache. Les valeurs de type ID sĂ©rialisĂ©es de la mĂȘme maniĂšre que les chaĂźnes, cependant, une indication qu'un type d' ID a une valeur est soulignĂ©e par le fait que cette valeur n'est pas destinĂ©e Ă  ĂȘtre affichĂ©e aux gens, mais Ă  ĂȘtre utilisĂ©e dans des programmes.

En plus de ces types scalaires, nous pouvons Ă©galement attribuer des propriĂ©tĂ©s aux types que nous dĂ©finissons nous-mĂȘmes. C'est exactement ce que nous avons fait en attribuant la propriĂ©tĂ© nutrition dĂ©crite dans le type Flavor , type Nutrition .

 type Query { flavors(id: ID): [Flavor] } 

Dans la construction de type Query , qui dĂ©crit le type racine de Query (la «requĂȘte racine» dont nous avons parlĂ© plus tĂŽt), nous dĂ©clarons le nom du champ qui peut ĂȘtre demandĂ©. En dĂ©clarant ce champ, nous spĂ©cifions, en plus du type de donnĂ©es que nous attendons, les arguments qui peuvent venir dans la demande.

Dans cet exemple, nous attendons une réception possible de l'argument id d'un ID type scalaire. En réponse à une telle demande, un tableau d'objets est attendu dont le périphérique ressemble à un périphérique de type Flavor .

▍Connexion du module de reconnaissance des requĂȘtes


, type Query field , , -.

— , 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 ? , . , , , 100% , . , , , , , .

GraphQL?


, , , , , GraphQL-API.

, GraphQL , . , . , . , , , GraphQL REST . , , , GraphQL.

▍ ,


, HTTP-, , , , — . GraphQL , , , , ( ).

, , ( — ), GraphQL .

▍ , ,


, , « ». , , , . . GraphQL .

▍ ,


REST API, : , . , -, iOS Android, API . , , , , « » .

, , , HTTP, API (, , ).

▍ GraphQL — ? REST API GraphQL?


, . . , , GraphQL . GraphQL, . , , , . , , .

, GraphQL , , , . GraphQL , Apollo Relay, .

GraphQL — , , . graphql ( express-graphql , ) — . , GraphQL - . , -, , , , .

Résumé


, GraphQL , . GraphQL , , , . , , , , GraphQL.

, : GraphQL . GraphQL . , GraphQL, , , , , , , .

— , GraphQL — , , . GraphQL , . , GraphQL — , , , . . , , , , , , GraphQL.

Chers lecteurs! GraphQL — , .

Source: https://habr.com/ru/post/fr445268/


All Articles