GraphQL - Query

Un'operazione GraphQL può essere un'operazione di lettura o di scrittura. Una query GraphQL viene utilizzata per leggere o recuperare valori mentre una mutazione viene utilizzata per scrivere o inviare valori. In entrambi i casi, l'operazione è una semplice stringa che un server GraphQL può analizzare e a cui può rispondere con dati in un formato specifico. Il formato di risposta popolare che viene solitamente utilizzato per le applicazioni mobili e web è JSON.

La sintassi per definire una query è la seguente:

//syntax 1
query query_name{ someField }

//syntax 2
{ someField }

Di seguito è riportato un esempio di query:

//query with name myQuery
query myQuery{
   greeting
}

// query without any name
{
   greeting
}

È chiaro dall'esempio precedente che la parola chiave query è facoltativa.

Le query GraphQL aiutano a ridurre il recupero eccessivo dei dati. A differenza di un'API riposante, GraphQL consente a un utente di limitare i campi che dovrebbero essere recuperati dal server. Ciò significa query più piccole e minor traffico sulla rete; che a sua volta riduce il tempo di risposta.

Illustrazione 1 - Eseguire una query sul modello di studente con un campo personalizzato

In questo esempio, abbiamo una serie di studenti archiviati in un file json. Ogni modello di studente ha campi come firstName, lastName e id ma non fullName. Qui discuteremo come eseguire una query per recuperare fullName di tutti gli studenti. Per questo, dobbiamo creare il campo fullName in entrambi i risolutori di schemi.

Vediamo come eseguire questa illustrazione utilizzando i passaggi seguenti:

Passaggio 1: scaricare e installare le dipendenze richieste per il progetto

Crea una cartella denominata query-app. Cambia la tua directory inquery-appdal terminale. Successivamente, seguire i passaggi da 3 a 5 spiegati nel capitolo Configurazione dell'ambiente.

Passaggio 2: creare uno schema

Inserisci schema.graphql file nella cartella del progetto query-app e aggiungi il seguente codice:

type Query {
   greeting:String
   students:[Student]
   studentById(id:ID!):Student
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   fullName:String 
}

Tieni presente che non è presente alcun campo fullName nel filestudents.jsonfile. Tuttavia, dobbiamo recuperare il nome completo dello studente tramite una query. Il fullName , in questo caso sarà un campo personalizzato che non è disponibile con l'origine dati.

Passaggio 3: creazione del risolutore

Crea un file resolvers.js nella cartella del progetto e aggiungi il seguente codice -

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}

Passaggio 4: eseguire l'applicazione

Creare un server.jsfile. Fare riferimento al passaggio 8 nel capitolo Configurazione dell'ambiente. Esegui il comando  npm start nel terminale. Il server sarà attivo e funzionante sulla porta 9000. Qui, usiamo GraphiQL come client per testare l'applicazione.

Apri il browser e digita l'URL http://localhost:9000/graphiql. Digita la seguente query nell'editor:

{
   students{
      id
      fullName
   }
}

La risposta per la query è fornita di seguito:

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "fullName": "Mohtashim:Mohammad"
         },
         
         {
            "id": "S1002",
            "fullName": "Kannan:Sudhakaran"
         },
         
         {
            "id": "S1003",
            "fullName": "Kiran:Panigrahi"
         }
      ]
   }
}

Creare un server.js e aggiungi il seguente codice -

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}`));

Esegui il comando npm start nel terminale. Il server sarà attivo e funzionante sulla porta 9000. Qui, usiamo GraphiQL come client per testare l'applicazione.

Apri il browser e digita l'URL http://localhost:9000/graphiql. Digita la seguente query nell'editor:

{
   students{
      id
      fullName
   }
}

La risposta per la query è fornita di seguito:

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "fullName": "Mohtashim:Mohammad"
         },
         {
            "id": "S1002",
            "fullName": "Kannan:Sudhakaran"
         },
         {
            "id": "S1003",
            "fullName": "Kiran:Panigrahi"
         }
      ]
   }
}

Illustrazione 2 - Query annidata

Creiamo una query annidata per recuperare i dettagli dello studente e i dettagli del college. Lavoreremo con la stessa cartella del progetto.

Passaggio 1: modifica dello schema

Il file schema ha già il campo studente . Aggiungiamo un campo universitario e definiamo il suo tipo.

type College {
   id:ID!
   name:String
   location:String
   rating:Float
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   fullName:String
   college:College
}

Passaggio 2: modifica il file resolver.js

Dobbiamo aggiungere una funzione di risoluzione del college come di seguito. La funzione di risoluzione del college verrà eseguita per ogni oggetto studente restituito. Il parametro radice del resolver in questo caso conterrà 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}

Il resolver restituisce il college di ogni studente chiamando il metodo get della raccolta college e passando il collegeId . Abbiamo una relazione di associazione tra studente e college tramite collegeId .

Passaggio 3: testare l'applicazione

Apri la finestra del terminale e vai alla cartella del progetto. Digita il comando -npm start. Avvia il browser e inserisci l'URLhttp://localhost:9000/graphiql.

Immettere la seguente query nella finestra GraphiQL:

{
   students{
      id
      firstName
      college {
         id
         name
         location
         rating
      }
   }
}

La risposta per la query è la seguente:

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

Che cos'è una variabile di query?

Se una query ha alcuni valori dinamici da trasmettere, rappresenta questi valori dinamici utilizzando le variabili. Pertanto, la query può essere riutilizzata dalle applicazioni client.

Illustrazione

Creiamo una semplice applicazione per comprendere la variabile di query.

Passaggio 1: modifica del file dello schema

Aggiungi un campo sayHello che accetta un parametro stringa e restituisce una stringa. I valori del nome saranno dinamici nell'applicazione client.

type Query {
   sayHello(name:String!):String
}

Passaggio 2: modifica il file resolver.js

Aggiungi un resolver sayHello che accetta parametri come di seguito -

sayHello:(root,args,context,info) => `Hi ${args.name} GraphQL server says Hello to you!!`

Passaggio 3: dichiarare la variabile di query in GraphiQL

Una variabile viene dichiarata con $ seguito dal nome della variabile. Ad esempio: $ myname_Variable.

Una volta dichiarata $ myname_Variable, deve essere utilizzata con una sintassi di query con nome. La query, myQuery, prende il valore stringa e lo passa a sayHello come mostrato di seguito -

query myQuery($myname_Variable:String!) {
   sayHello(name:$myname_Variable)
}

Impostare il valore per $ myname_Variable come oggetto JSON nella sezione Variabili di query del client GraphiQL.

{
   "myname_Variable": "Mohtashim"
}

L'output del codice sopra è il seguente:

{
   "data": {
      "sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
   }
}

Come utilizzare la variabile di query con Enum

Vediamo come utilizzare una variabile di query quando il parametro di campo è enum type.

Passaggio 1: modifica il file schema.graphql

enum ColorType {
   RED
   BLUE
   GREEN
}

type Query {
   setFavouriteColor(color:ColorType):String
}

La funzione setFavouriteColor accetta enum come input e restituisce un valore stringa.

Passaggio 2: modifica il file resolvers.js

La funzione resolver setFavouriteColor prende radice e args . È possibile accedere al valore enum passato alla funzione in fase di esecuzione tramite il parametro args.

setFavouriteColor:(root,args) => {
   return  "Your Fav Color is :"+args.color;
}

Passaggio 3: dichiarare una variabile di query in GraphiQL

La query è denominata query_to_setColorche accetta una variabile del nome color_variable di ColorType. Questa variabile viene passata al metodo setFavouriteColor.

query query_to_setColor($color_variable:ColorType) {
   setFavouriteColor(color:$color_variable)
}

Nella sezione della variabile di query di GraphiQL, digita il codice seguente:

{
   "color_variable":"RED"
}

La risposta è mostrata di seguito:

{
   "data": {
      "setFavouriteColor": "Your Fav Color is: RED"
   }
}