GraphQL é a nova palavra-chave no desenvolvimento de API. Enquanto as APIs RESTful continuam sendo a forma mais popular de expor dados de aplicativos, elas vêm com muitas limitações que o GraphQL planeja resolver.

GraphQL é uma linguagem de consulta criada pelo Facebook, transformada em um projeto de código aberto em 2015. Ele oferece uma sintaxe intuitiva e flexível para descrever e acessar dados em uma API.Pronto para construir seu primeiro projeto GraphQL Node.js? 👀 Comece aqui ✅Clique para Tweetar

Este guia irá explorar como construir um projeto GraphQL Node.js. Usaremos o GraphQL para construir um aplicativo Todo no framework web do Express.js para Node.

O que é GraphQL?

A partir da documentação oficial: “GraphQL é uma linguagem de consulta para APIs e um tempo de execução para preencher essas consultas com seus dados existentes. GraphQL fornece uma descrição completa e compreensível dos dados em sua API, dá aos clientes o poder de pedir exatamente o que eles precisam e nada mais, facilita a evolução das APIs ao longo do tempo e permite poderosas ferramentas de desenvolvimento”

GraphQL é um tempo de execução do lado do servidor para executar consultas usando o tipo de sistema que você definiu para seus dados. Além disso, o GraphQL não está ligado a nenhum banco de dados ou mecanismo de armazenamento específico. Ao invés disso, ele é apoiado pelo seu código e armazenamento de dados existentes. Você pode obter uma comparação detalhada dessas tecnologias com o guia GraphQL vs RESTful API.

Para criar um serviço GraphQL, você começa definindo tipos de schemas e criando campos usando esses tipos. Em seguida, você fornece um resolvedor de função a ser executado em cada campo e digita sempre que os dados são solicitados pelo lado do cliente.

Terminologia do GraphQL

O sistema do tipo GraphQL é usado para descrever quais dados podem ser consultados e quais dados você pode manipular. É o núcleo do GraphQL. Discutiremos diferentes maneiras de descrever e manipular os dados no GraphQ.

Tipos de objetos

Os tipos de objetos GraphQL são modelos de dados contendo campos fortemente digitados. Deve haver um mapeamento de 1 para 1 entre seus modelos e os tipos de GraphQL. Abaixo está um exemplo de tipos de GraphQL:

type User {
  id: ID! # The "!" means required
  firstname: String
  lastname: String
  email: String
  username: String
  todos: [Todo] # Todo is another GraphQL type
}

Query

GraphQL Query define todas as consultas que um cliente pode executar na API GraphQL. Você deve definir um RootQuery que conterá todas as consultas existentes por convenção.

Abaixo, definimos e mapeamos as consultas para a API RESTful correspondente:

type RootQuery {
  user(id: ID): User           # Corresponds to GET /api/users/:id
  users: [User]                # Corresponds to GET /api/users
  todo(id: ID!): Todo    # Corresponds to GET /api/todos/:id
  todos: [Todo]          # Corresponds to GET /api/todos
}

Mutações

Se as consultas do GraphQL são pedidos GET, as mutações são POST, PUT, PATCH, e DELETE pedidos que manipulam a API do GraphQL.

Colocaremos todas as mutações em um único RootMutation para demonstrar:

type RootMutation {
  createUser(input: UserInput!): User             # Corresponds to POST /api/users
  updateUser(id: ID!, input: UserInput!): User    # Corresponds to PATCH /api/users
  removeUser(id: ID!): User                       # Corresponds to DELETE /api/users
  createTodo(input: TodoInput!): Todo
  updateTodo(id: ID!, input: TodoInput!): Todo
  removeTodo(id: ID!): Todo
}

Você notou o uso de -input tipos para as mutações como UserInput, TodoInput. É sempre a melhor prática definir sempre os tipos de entrada para criar e atualizar seus recursos.

Um tipo de entrada pode ser definido como:

input UserInput {
  firstname: String!
  lastname: String
  email: String!
  username: String!
}

Resolvers

Os resolvers dizem ao GraphQL o que fazer quando cada consulta ou mutação é solicitada. É uma função básica que faz o trabalho duro de acertar a camada do banco de dados para fazer as operações CRUD (criar, ler, atualizar, excluir), acertar um endpoint interno RESTful API, ou chamar um microsserviço para atender a solicitação do cliente.

Você pode criar um novo arquivo resolvers.js e adicionar o seguinte código:

import sequelize from '../models';
export default function resolvers () {
  const models = sequelize.models;
  return {
    // Resolvers for Queries
    RootQuery: {
      user (root, { id }, context) {
        return models.User.findById(id, context);
      },
      users (root, args, context) {
        return models.User.findAll({}, context);
      }
    },
    User: {
      todos (user) {
        return user.getTodos();
      }
    },
  }
  // Resolvers for Mutations
  RootMutation: {
    createUser (root, { input }, context) {
      return models.User.create(input, context);    
    },
    updateUser (root, { id, input }, context) {
      return models.User.update(input, { ...context, where: { id } });
    },
    removeUser (root, { id }, context) {
      return models.User.destroy(input, { ...context, where: { id } });
    },
    // ... Resolvers for Todos go here
  }
}

Schema

Um Schema GraphQL é o que expõe o GraphQL ao mundo. Portanto, tipos, consultas e mutações estão contidos em schemas e expostos ao mundo.

Abaixo está como expor tipos, consultas e mutações para o mundo:

schema {
  query: RootQuery
  mutation: RootMutation
}

No script acima, incluímos o RootQuery e RootMutation que criamos anteriormente para ser exposto ao mundo.

Como o GraphQL funciona com o Node.js e Express.js?

GraphQL fornece uma implementação para todas as principais linguagens de programação, e o Node.js não está isento. No site oficial do GraphQL, há uma seção para suporte ao JavaScript, e também, há outras implementações do GraphQL para tornar simples a escrita e a codificação.

GraphQL Apollo fornece uma implementação para Node.js e Express.js e facilita começar a usar o GraphQL.

Você aprenderá como criar e desenvolver seu primeiro aplicativo GraphQL no Node.js e Express.js backend framework usando o GraphQL Apollo na próxima seção.

Configurando o GraphQL com o Express.js

A construção de um servidor GraphQL API com o Express.js é simples para começar. Nesta seção, vamos explorar como construir um servidor GraphQL.

Inicialize o projeto com o Express.js

Primeiro, você precisa instalar e configurar um novo projeto Express.js. Crie uma pasta para o seu projeto e instale o Express.js usando este comando:

cd <project-name> && npm init -y
npm install express

O comando acima cria um novo arquivo package.json e instala a biblioteca Express.js em seu projeto.

A seguir, estruturaremos nosso projeto como mostrado na imagem abaixo. Ele conterá diferentes módulos para as funcionalidades do projeto, tais como usuários, todos, etc.

Arquivos para o graphql-todo
Arquivos para o graphql-todo.

Inicialize o GraphQL

Vamos começar instalando as dependências do GraphQL Express.js. Execute o seguinte comando para instalar:

npm install apollo-server-express graphql @graphql-tools/schema --save

Criando schemas e Types

A seguir, vamos criar um arquivo index.js na pasta de módulos e adicionar o seguinte snippet de código:

const { gql } = require('apollo-server-express');
const users = require('./users');
const todos = require('./todos');
const { GraphQLScalarType } = require('graphql');
const { makeExecutableSchema } = require('@graphql-tools/schema');
const typeDefs = gql`
  scalar Time
  type Query {
    getVersion: String!
  }
  type Mutation {
    version: String!
  }
`;
const timeScalar = new GraphQLScalarType({
  name: 'Time',
  description: 'Time custom scalar type',
 serialize: (value) => value,
});
const resolvers = {
  Time: timeScalar,
  Query: {
    getVersion: () => `v1`,
  },
};
const schema = makeExecutableSchema({
  typeDefs: [typeDefs, users.typeDefs, todos.typeDefs],
  resolvers: [resolvers, users.resolvers, todos.resolvers],
});
module.exports = schema;

Análise do código

Vamos rever o snippet de código passo a passo:

Passo 1

Primeiro, importamos as bibliotecas necessárias e criamos os tipos de consulta e mutação padrão. A consulta e a mutação definiram apenas a versão da API GraphQL por enquanto. Entretanto, estendamos a consulta e a mutação para incluir outros schemas conforme prosseguimos.

Importação de GraphQL e extensões
Importação de GraphQL e extensões.
Passo 2:

Criamos um novo tipo de escalar por tempo e nosso primeiro resolvedor para a consulta e mutação criada acima. Além disso, também geramos um schema usando a função makeExecutableSchema.

O schema gerado incluirá todos os outros schemas que você importou e ainda mais após criá-los e importá-los.

Criando um tipo escalar para o tempo, bem como nosso primeiro resolver.
Criando um tipo escalar para o tempo, bem como nosso primeiro resolver.

O snippet de código acima mostra que importamos diferentes schemas para a função makeExecutableSchema. Esta abordagem nos ajuda na estruturação do aplicativo por complexidade. Em seguida, criaremos os schemas Todo e Usuário que importamos.

Criando o schema Todo

O Schema Todo mostra operações simples de CRUD que os usuários do aplicativo podem realizar. Abaixo está o schema que implementa a operação de Todo CRUD.

const { gql } = require('apollo-server-express');
const createTodo = require('./mutations/create-todo');
const updateTodo = require('./mutations/update-todo');
const removeTodo = require('./mutations/delete-todo');
const todo = require('./queries/todo');
const todos = require('./queries/todos');
const typeDefs = gql`
  type Todo {
    id: ID!
    title: String
    description: String
    user: User
  }
  input CreateTodoInput {
    title: String!
    description: String
    isCompleted: Boolean
  }
  input UpdateTodoInput {
    title: String
    description: String
    isCompleted: Boolean
  }  extend type Query {
    todo(id: ID): Todo!
    todos: [Todo!]
  }
  extend type Mutation {
    createTodo(input: CreateTodoInput!): Todo
    updateTodo(id: ID!, input: UpdateTodoInput!): Todo
    removeTodo(id: ID!): Todo
  }
`;
// Provide resolver functions for your schema fields
const resolvers = {
  // Resolvers for Queries
  Query: {
    todo,
    todos,
  },
  // Resolvers for Mutations
  Mutation: {
    createTodo,
    updateTodo,
    removeTodo,
  },
};
module.exports = { typeDefs, resolvers };

Análise do código

Vamos rever o snippet de código passo a passo:

Passo 1:

Primeiro, criamos um Schema Todo usando GraphQL type, input, e extend. A palavra-chave extend é usada para herdar e adicionar novas consultas e mutações à consulta raiz existente e à mutação que criamos acima.

Criando o Schema Todo
Criando o Schema Todo.
Passo 2:

Em seguida, criamos um resolvedor, usado para recuperar os dados corretos quando uma determinada consulta ou mutação é chamada.

Criando um resolver
Criando um resolver.

Com a função resolver implementada, podemos criar métodos individuais para a lógica de negócios e manipulação do banco de dados, como mostrado no exemplo do create-todo.js.

Crie um arquivo create-user.js na pasta ./mutations/ e adicione a lógica do negócio para criar um novo Todo em seu banco de dados.

const models = require('../../../models');
module.exports = async (root, { input }, context) => {
  return models.todos.push({ ...input });
};

O snippet de código acima é uma forma simplificada de criar um novo Todo em nosso banco de dados usando o ORM Sequelize. Você pode aprender mais sobre o Sequelize e como configurá-lo com o Node.js.

Você pode seguir o mesmo passo para criar muitos schemas dependendo do seu aplicativo ou você pode clonar o projeto completo do GitHub.

Em seguida, configuraremos o servidor com o Express.js e executar o aplicativo Todo recém-criada com GraphQL e Node.js.

Configurando e executando o servidor

Finalmente, configuraremos nosso servidor usando a biblioteca apollo-server-express que instalamos anteriormente.

O apollo-server-express é um pacote simples do Apollo Server para Express.js, é recomendado porque foi desenvolvido para se encaixar no desenvolvimento do Express.js.

Usando os exemplos que discutimos acima, vamos configurar o servidor Express.js para trabalhar com o recém-instalado apollo-server-express.

Crie um arquivo server.js no diretório raiz e cole no seguinte código:


const express = require('express');
const { ApolloServer } = require('apollo-server-express');
const schema = require('./modules');
const app = express();
async function startServer() {
  const server = new ApolloServer({ schema });
  await server.start();
  server.applyMiddleware({ app });
}
startServer();
app.listen({ port: 3000 }, () =>
  console.log(`Server ready at http://localhost:3000`)
);

O código acima criou com sucesso o primeiro servidor GraphQL CRUD para Todos e Usuários. Você pode iniciar o servidor de desenvolvimento e acessar o playground via http://localhost:3000/graphql. Se tudo der certo, você verá a seguinte tela:

A tela de verificação
A tela de verificação.

Resumo

GraphQL é uma tecnologia moderna suportada pelo Facebook que simplifica o tedioso trabalho envolvido na criação de APIs de larga escala com padrões arquitetônicos RESTful.Já se perguntou como o GraphQL funciona com o Node.js e Express.js? 🤔 A resposta está neste guia! ⬇️Clique para Tweetar

Este guia se aprofundou no GraphQL e mostrou como criar sua primeira API GraphQL usando Express.js.

Deixe-nos saber o que você constrói com GraphQL nos comentários abaixo.


Obtenha todos os seus aplicativos, banco de dados e Sites WordPress on-line e sob o mesmo teto. Nossa plataforma de nuvens de alto desempenho e repleta de recursos inclui:

  • Fácil configuração e gerenciamento no painel MyKinsta
  • Suporte especializado 24/7
  • O melhor hardware e rede do Google Cloud Platform, alimentado por Kubernetes para a máxima escalabilidade
  • Integração Cloudflare de nível empresarial para velocidade e segurança
  • Audiência global com centros de dados de até 35 e 275 PoPs no mundo todo

Comece agora com uma avaliação gratuita do nosso Hospedagem de Aplicativos ou Hospedagem de Banco de Dados. Explore nossos planos ou entre em contato com as vendas para encontrar o que melhor se adapta às suas necessidades.