GraphQL - Consulta

Uma operação GraphQL pode ser uma operação de leitura ou gravação. Uma consulta GraphQL é usada para ler ou buscar valores, enquanto uma mutação é usada para escrever ou postar valores. Em ambos os casos, a operação é uma string simples que um servidor GraphQL pode analisar e responder com dados em um formato específico. O formato de resposta popular geralmente usado para aplicativos móveis e da web é JSON.

A sintaxe para definir uma consulta é a seguinte -

//syntax 1
query query_name{ someField }

//syntax 2
{ someField }

A seguir está um exemplo de uma consulta -

//query with name myQuery
query myQuery{
   greeting
}

// query without any name
{
   greeting
}

É claro a partir do exemplo acima que a palavra-chave da consulta é opcional.

As consultas GraphQL ajudam a reduzir a busca excessiva de dados. Ao contrário de uma API Restful, GraphQL permite que um usuário restrinja campos que devem ser buscados no servidor. Isso significa consultas menores e menos tráfego na rede; o que, por sua vez, reduz o tempo de resposta.

Ilustração 1 - Consultar o modelo do aluno com um campo personalizado

Neste exemplo, temos um conjunto de alunos armazenados em um arquivo json. Cada modelo de aluno possui campos como firstName, lastName e id, mas nenhum fullName. Aqui, vamos discutir como fazer uma consulta para recuperar fullName de todos os alunos. Para isso, precisamos criar o campo fullName em ambos os resolvedores de esquema.

Vamos ver como fazer esta ilustração usando as etapas abaixo -

Etapa 1 - Baixe e instale as dependências necessárias para o projeto

Crie uma pasta chamada query-app. Mude seu diretório paraquery-appdo terminal. Posteriormente, siga as etapas 3 a 5 explicadas no capítulo Configuração do ambiente.

Etapa 2 - Criar um esquema

Adicionar schema.graphql arquivo na pasta do projeto query-app e adicione o seguinte código -

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

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

Observe que não há campo fullName nostudents.jsonArquivo. No entanto, precisamos buscar o nome completo do aluno por meio de uma consulta. O fullName , neste caso, será um campo personalizado que não está disponível com a fonte de dados.

Etapa 3 - Criar resolvedor

Crie um arquivo resolvers.js na pasta do projeto e adicione o seguinte código -

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}

Etapa 4 - Executar o aplicativo

Criar uma server.jsArquivo. Consulte a etapa 8 no capítulo Configuração de ambiente. Execute o comando  npm start no terminal. O servidor estará instalado e funcionando na porta 9000. Aqui, usamos GraphiQL como um cliente para testar o aplicativo.

Abra o navegador e digite o URL http://localhost:9000/graphiql. Digite a seguinte consulta no editor -

{
   students{
      id
      fullName
   }
}

A resposta para a consulta é fornecida abaixo -

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

Criar uma server.js e adicione o seguinte código -

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

Execute o comando npm start no terminal. O servidor estará instalado e funcionando na porta 9000. Aqui, usamos GraphiQL como um cliente para testar o aplicativo.

Abra o navegador e digite o URL http://localhost:9000/graphiql. Digite a seguinte consulta no editor -

{
   students{
      id
      fullName
   }
}

A resposta para a consulta é fornecida abaixo -

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

Ilustração 2 - Consulta Aninhada

Vamos criar uma consulta aninhada para buscar os detalhes do aluno e os detalhes da faculdade. Trabalharemos com a mesma pasta de projeto.

Etapa 1 - Editar o Esquema

O arquivo de esquema já contém o campo do aluno . Vamos adicionar uma faculdade de campo e definir seu tipo.

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

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

Etapa 2 - Modificar o resolver.js

Precisamos adicionar uma função de resolução de faculdade conforme abaixo. A função de resolução de faculdade será executada para cada objeto de aluno retornado. O parâmetro raiz do resolvedor neste caso conterá aluno .

const Student = {
   fullName:(root,args,context,info) => {
      return root.firstName+":"+root.lastName
   },
   college:(root) => {
      return db.colleges.get(root.collegeId);
   }
}
module.exports = {Query,Student}

O resolvedor retorna a faculdade de cada aluno chamando o método get de coleta de faculdade e passando o collegeId . Temos relação de associação entre Student e College por meio do collegeId .

Etapa 3 - Teste o aplicativo

Abra a janela do terminal e navegue até a pasta do projeto. Digite o comando -npm start. Abra o navegador e digite o URLhttp://localhost:9000/graphiql.

Insira a seguinte consulta na janela GraphiQL -

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

A resposta para a consulta é a seguinte -

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

O que é uma variável de consulta?

Se uma consulta tiver alguns valores dinâmicos a serem transmitidos, represente esses valores dinâmicos usando variáveis. Portanto, a consulta pode ser reutilizada pelos aplicativos cliente.

Ilustração

Vamos criar um aplicativo simples para entender a variável de consulta.

Etapa 1 - Editar Arquivo de Esquema

Adicione um campo sayHello que recebe um parâmetro de string e retorna uma string. Os valores de nome serão dinâmicos no aplicativo cliente.

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

Etapa 2 - Editar o arquivo resolver.js

Adicione um resolvedor sayHello que usa o parâmetro abaixo -

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

Etapa 3 - Declare a variável de consulta no GraphiQL

Uma variável é declarada com $ seguido do nome da variável. Por exemplo: $ myname_Variable.

Uma vez que $ myname_Variable é declarado, ele deve ser usado com uma sintaxe de consulta nomeada. A consulta, myQuery pega o valor da string e o passa para dizer Olá, conforme mostrado abaixo -

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

Defina o valor de $ myname_Variable como um objeto JSON na seção Variáveis ​​de consulta do cliente GraphiQL.

{
   "myname_Variable": "Mohtashim"
}

A saída do código acima é a seguinte -

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

Como usar a variável de consulta com Enum

Vamos ver como usar uma variável de consulta quando o parâmetro de campo é enum type.

Etapa 1 - Editar o arquivo schema.graphql

enum ColorType {
   RED
   BLUE
   GREEN
}

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

A função setFavouriteColor leva enum como entrada e retorna um valor de string.

Etapa 2 - Editar o arquivo resolvers.js

A função de resolução setFavouriteColor obtém raiz e args . O valor enum passado para a função em tempo de execução pode ser acessado por meio do parâmetro args.

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

Etapa 3 - Declare uma variável de consulta no GraphiQL

A consulta é nomeada query_to_setColorque recebe uma variável de nome color_variable de ColorType. Essa variável é passada para o método setFavouriteColor.

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

Na seção de variável de consulta do GraphiQL, digite o seguinte código -

{
   "color_variable":"RED"
}

A resposta é mostrada abaixo -

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