Una introducció a GraphQL: com funciona i com utilitzar-la

Foto de Matt Duncan a Unsplash

GraphQL és un llenguatge de consulta per a les API. Es mostren els diversos tipus de dades proporcionats pel servidor i el client pot triar exactament el que vol.

A GraphQL, també podeu obtenir diversos recursos del servidor en una trucada en lloc de fer diverses trucades a l'API REST.

La llista completa dels avantatges es troba a https://graphql.org/.

La cosa és que, fins que no veieu GraphQL en acció, és difícil entendre els avantatges. Comencem, doncs, a utilitzar GraphQL.

En aquest article utilitzarem GraphQL juntament amb NodeJS.

Requisits

Instal·leu NodeJS des d’aquí: https://nodejs.org/ca/.

Com utilitzar GraphQL amb NodeJs

GraphQL es pot utilitzar amb diversos idiomes. Aquí ens centrem en com podem utilitzar GraphQL amb JavaScript mitjançant NodeJS.

Creeu una carpeta anomenada graphql-with-nodejs. Vés a la carpeta del projecte i executa npm init per crear el projecte NodeJS. La comanda per a això es dóna a continuació.

cd graphql-amb-nodejs npm init

Instal·leu les dependències

Instal·leu Express amb la següent comanda:

npm install express

Instal·leu GraphQL amb la següent comanda. Instal·larem GraphQL i GraphQL per a Express.

npm instal·leu express-graphql graphql

Codi NodeJS

Creeu un fitxer anomenat server.js al projecte i copieu el codi següent:

const express = exigir ('express'); port port = 5000; const app = express (); app.get ('/ hola', (req, res) => {res.send ("hola");}); app.listen (port); console.log (`El servidor s'està executant en localhost: $ {port}`);

El codi anterior té un sol punt final HTTP GET anomenat / hola.

L’endpoint es crea amb Express.

Ara canviem aquest codi per habilitar GraphQL.

Habilita GraphQL en codi

GraphQL té un únic extrem URL anomenat / graphql que gestiona totes les sol·licituds.

Copieu el codi següent a server.js:

// obtenir totes les biblioteques necessàries const express = require ("express"); const graphqlHTTP = requerir ('express-graphql'); const {GraphQLSchema} = require ('graphql'); const {queryType} = require ('./ query.js'); // configureu el número de port i el port de const aplicació express = 5000; const app = express (); // Defineix el esquema const schema = nou GraphQLSchema ({query: queryType}); // Configura el servidor GraphQL del node app.use ('/ graphql', graphqlHTTP ({schema: schema, graphiql: true,})); app.listen (port); console.log (`El servidor GraphQL s'està executant en localhost: $ {port}`);

Ara passem per aquest codi.

Amb graphqlHTTP podem configurar un servidor GraphQL sota / graphql url. Sap fer front a la sol·licitud entrant.

Aquesta configuració es porta a terme a les línies de codi següents:

app.use ('/ graphql', graphqlHTTP ({schema: schema, graphiql: true,}));

Ara examinem els paràmetres a graphqlHTTP.

graphiql

graphiql és una interfície d’usuari web que podeu utilitzar per provar els endpoints de GraphQL. Hem establert això en veritable per facilitar la prova dels diferents punts finals que hem creat GraphQL.

Esquema

GraphQL només té un endpoint extern / graphql. Aquest extrem pot tenir diversos altres punts finals que realitzen tasques diferents. Aquests punts finals s'especificaran a l'esquema.

L'esquema farà les següents accions:

  • Proporcioneu els punts finals
  • Introduïu els camps d’entrada i sortida del punt final
  • Especifiqueu quines accions heu de dur a terme quan s'arriba a un punt final, etc.

L'esquema es defineix al codi de la següent manera:

const schema = nou GraphQLSchema ({query: queryType});

L’esquema pot contenir tant tipus de consulta com mutació. Aquest article es centra només en el tipus de consulta.

Consulta

Podeu veure a l’esquema que la consulta s’ha establert a queryType.

Importem queryType des del fitxer query.js amb la següent comanda:

const {queryType} = require ('./ query.js');

query.js és un fitxer personalitzat que crearem en breu.

A la consulta especifiquem els extrems de només lectura en un esquema.

Creeu un fitxer anomenat query.js al projecte i copieu el següent codi.

const {GraphQLObjectType, GraphQLString} = require ('graphql'); // Defineix la const query queryType = new GraphQLObjectType ({name: 'Query', camps: {Hello: {Type: GraphQLString, resol: function () {return "Hello World";}}}}); export.queryType = queryType;

Consulta explicada

queryType es crea com GraphQLObjectType i es diu Query.

Als camps definim els diferents punts finals.

A continuació, hi afegim un endpoint anomenat "Hola".

Hola té un tipus de GraphQLString, el que significa que aquest punt final té un tipus de cadena de retorn. El tipus és GraphQLString en lloc de String perquè és un esquema GraphQL. Així que directament amb una cadena no funcionarà.

El resolvent especifica l'acció que cal dur a terme quan es crida l'endpoint. L’acció aquí és retornar una cadena "Hola món".

Finalment, exportem el tipus de consulta amb export.queryType = queryType. Això és per assegurar-nos que podem importar-lo a server.js.

Executa l'aplicació

Executeu l'aplicació amb la següent comanda:

Node Server.js

L’aplicació funciona amb localhost: 5000 / graphql.

Podeu provar l'aplicació anant a localhost: 5000 / graphql.

Aquest URL executa la interfície d’usuari web de Graphiql com es mostra a la pantalla següent.

L’entrada és a l’esquerra i la sortida a la dreta.

Introduïu la següent entrada

{Hola}

Això es tradueix en la sortida següent

{"Dates": {"Hello": "Hello World"}}

Enhorabona

Heu creat el primer endpoint de GraphQL.

Afegiu més punts finals

Crearem dos nous punts finals:

  • pel·lícula: aquest extrem retorna una pel·lícula amb l'identificador de pel·lícula especificat
  • Director: aquest punt final retorna un director amb l'identificador de director. Totes les pel·lícules d’aquest director també són retornades.

Afegiu dades

Normalment, una aplicació llegeix dades d'una base de dades. En aquest tutorial, per senzillesa, codificarem les dades al codi mateix.

Creeu un fitxer anomenat data.js i afegiu el codi següent.

// Codifiqueu algunes dades per a pel·lícules i directors Let Films = [{id: 1, Nom: "Film 1", Any: 2018, directorId: 1}, {id: 2, Nom: "Pel·lícula 2", Any: 2017 , directorId: 1}, {id: 3, Nom: "Pel·lícula 3", Any: 2016, directorId: 3}]; let directors = [{id: 1, Nom: "Director 1", Edat: 20}, {id: 2, Nom: "Director 2", Edat: 30}, {id: 3, Nom: "Director 3", Edat: 40}]; exportacions.movies = pel·lícules; export.directors = directors;

Aquest fitxer conté les dades de la pel·lícula i el director. Utilitzarem les dades d’aquest fitxer per a les nostres finalitats.

Afegir el final de la pel·lícula a la consulta

Els nous punts finals s’afegeixen a queryType al fitxer query.js.

A continuació, es mostra el codi per al final de la pel·lícula:

Pel·lícula: {type: movieType, arguments: {id: {type: GraphQLInt}}, decisió: funció (font, arguments) {return _.find (pel·lícules, {id: args.id}); }}

El tipus de retorn d’aquest extrem és movieType, que es definirà en breu.

El paràmetre args especifica l'entrada del punt final de la pel·lícula. L’entrada d’aquest extrem és id del tipus GraphQLInt.

La funció de resolució retorna la pel·lícula corresponent a l'ID de la llista de pel·lícules. find és una funció de la biblioteca de lodash que s'utilitza per trobar un element en una llista.

A continuació es mostra el codi complet per a query.js:

const {GraphQLObjectType, GraphQLString, GraphQLInt} = require ('graphql'); const _ = requerir ('lodash'); const {movieType} = require ('./ types.js'); let {films} = require ('./ data.js'); // Defineix la const query queryType = new GraphQLObjectType ({name: 'Query', camps: {Hello: {Type: GraphQLString, resol: function () {return "Hello World";}}, Film: {Type: movieType, Arguments: {id: {type: GraphQLInt}}, decision: function (font, arguments) {return _.find (pel·lícules, {id: args.id});}}}}); export.queryType = queryType;

Des del codi anterior podem veure que movieType està realment definit en types.js.

Afegiu el tipus de pel·lícula personalitzat

Creeu un fitxer anomenat types.js.

Afegiu el codi següent a types.js

const {GraphQLObjectType, GraphQLID, GraphQLString, GraphQLInt} = require ('graphql'); // Defineix el tipus de pel·lícula movieType = nou GraphQLObjectType ({name: "Film", camps: {id: {type: GraphQLID}, nom: {type: GraphQLString}, any: {type: GraphQLInt}, directorId: {type: GraphQLID} }}); exportacions.movieType = movieType;

Es pot veure que movieType es crea com GraphQLObjectType.

Té quatre camps: id, nom, any i directorId. Els tipus per a cadascun d'aquests camps també s'especifiquen quan els afegiu.

Aquests camps provenen directament de les dades. En aquest cas serà de la llista de pel·lícules.

Afegiu la consulta i el tipus per a l’endpoint del director

Igual que amb la pel·lícula, es pot afegir l’endpoint del director.

A query.js, l’endpoint del director es pot afegir de la següent manera:

Director: {type: directorType, arguments: {id: {type: GraphQLInt}}, decisió: funció (font, arguments) {return _.find (directors, {id: args.id}); }}

directorType es pot afegir a types.js de la següent manera:

// Definiu el tipus de director directorType = nou GraphQLObjectType ({Nom: "Director", Camps: {id: {type: GraphQLID}, nom: {type: GraphQLString}, Edat: {Type: GraphQLInt}, Pel·lícules: {Tipus: nova GraphQLList (movieType), decisió (font, arguments) {return _.filter (pel·lícules, {directorId: source.id});}}}});

Espereu un minut El directorType difereix lleugerament de FilmType. Per què és això?

Per què hi ha una funció de resolució a directorType? Fins ara hem vist que les funcions de resolució només estaven disponibles a la consulta ...

L’especialitat de directorTip

Quan es truca al final del director, hem de retornar els detalls del director i les pel·lícules que el director hagi dirigit.

Els tres primers camps d’identificació, nom, edat en directorType són senzills i provenen directament de les dades (Llista de directors).

El quart camp, pel·lícules, ha de contenir la llista de pel·lícules d’aquest director.

Per aquest motiu esmentem que el camp del tipus de pel·lícula és un GraphQLList de movieType (Llista de pel·lícules).

Però, com exactament trobarem totes les pel·lícules realitzades per aquest director?

Per això tenim una funció de resolució en el camp de les pel·lícules. Les entrades per a aquesta funció de resolució són font i arg.

L’origen conté els detalls de l’objecte pare.

Diguem els camps id = 1, nom = "aleatori" i edat = 20 per a un director. A continuació, source.id = 1, source.name = "Aleatori" i source.age = 20

En aquest exemple, la funció de resolució troba totes les pel·lícules en les quals el directorId coincideix amb la identificació del director necessari.

Codi

Tot el codi d'aquesta aplicació està disponible en aquest dipòsit de GitHub

Prova de l’aplicació

Ara posem a prova l'aplicació per a diferents escenaris.

Executeu l'aplicació amb el node server.js.

Vés a localhost: 5000 / graphql i prova les entrades següents.

Pel·lícula

Entrada:

{Pel·lícula (ID: 1) {nom}}

Edició:

{"Dates": {"movie": {"name": "Film 1"}}}

A partir de la informació anterior, podem veure que el client pot sol·licitar exactament el que vol i GraphQL garanteix que només es retornen aquests paràmetres. Aquí només es consulta el camp del nom i només el servidor el torna a enviar.

A la pel·lícula (ID: 1), ID és el paràmetre d’entrada. Demanem al servidor que retorni la pel·lícula amb l'ID 1.

Entrada:

{Film (ID: 3) {name I would year}}

Edició:

{"Dates": {"movie": {"name": "Pel·lícula 3", "id": "3", "Any": 2016}}}

A l'exemple anterior, es sol·liciten els camps Nom, identificador i any. El servidor envia tots aquests camps.

Director

Entrada:

{Director (id: 1) {name I would, age}}

Edició:

{"Dates": {"Director": {"Nom": "Director 1", "id": "1", "Edat": 20}}}

Entrada:

{Director (id: 1) {name I would, edat, films {nom, any}}}

Edició:

{"Dates": {"Director": {"Nom": "Director 1", "id": "1", "Edat": 20, "Pel·lícules": [{"nom": "Pel·lícula 1", " Any ": 2018}, {" nom ":" Pel·lícula 2 "," any ": 2017}]}}}

A l'exemple anterior veiem el rendiment de GraphQL. Afirmem que volem un director amb la identificació 1. També afirmem que volem totes les pel·lícules d’aquest director. Tant la direcció com el camp de la pel·lícula es poden personalitzar i el client pot sol·licitar exactament el que desitgi.

També es pot estendre a altres camps i tipus. Per exemple, podríem executar una consulta com Cerqueu un director amb ID 1. Esteu buscant totes les pel·lícules d’aquest director. Busqueu els actors de cada pel·lícula. Obteniu les 5 millors pel·lícules per a cada actor, etc. Per a aquesta consulta, cal que especifiqueu la relació entre els tipus. El client pot consultar qualsevol relació que desitgi.

Enhorabona

Ja coneixeu els conceptes bàsics de GraphQL.

Consulteu la documentació per obtenir més informació sobre GraphQL

Sobre l’autor

M'encanta la tecnologia i segueixo els avenços en aquest àmbit. També m’agrada ajudar els altres amb els meus coneixements tecnològics.

Podeu contactar amb mi mitjançant el meu compte de LinkedIn https://www.linkedin.com/in/aditya1811/

També podeu seguir-me a Twitter https://twitter.com/adityasridhar18

El meu lloc web: https://adityasridhar.com/

Publicat originalment a adityasridhar.com.