Construindo uma API GraphQL com Node.js

Paulo César Queiroz Rodrigues
How Kovi Work
Published in
8 min readOct 15, 2019

Hoje mostraremos como construir uma api utilizando GraphQL, Mongo e Hapi

Mas espere.. Hapi? 🧐
Sim, utilizaremos o hapiJS, esse framework foi criado pelo time do Walmart Labs — liderado por Eran Hammer, que também criou o OAuth — e é focado no desenvolvimento com qualidade corporativa e entre vários times, de fácil manutenção e escalabilidade, e prefere configuração do que código.

O mesmo também conta com alguns pacotes interessantes que são desenvolvidos pela Walmart Labs

  • Boom: Esse é usado para enviar erros HTTP corretamente para o cliente, usando o código correto no envio com um objeto estruturado e mensagem personalizada. A principal vantagem é a facilidade de leitura do código durante o desenvolvimento, usando palavras para descrever o erro corretamente e não o código diretamente (Boom.badRequest ao invés de Status 400). Link para o repositório: https://github.com/hapijs/boom
  • Joi: Esse é usado para validar e retornar erros de validação de forma automatizada. Ele facilita muito o desenvolvimento e garante um sistema fechado contra usuários mal intencionados. Link para o repositório : https://github.com/hapijs/joi

Caso queira se aventurar na documentação do mesmo o link está aqui

Vamos ao código! 👨‍💻

Para! Para! Para! Para!

Antes precisamos conhecer nossas dependências e o que precisaremos para iniciar nosso projeto:

  • NodeJS (Utilizarei a versão 10.16.3 e Yarn)
  • Editor de texto (Utilizarei o VsCode)
  • MongoDb (link)

Agora sim iniciaremos! 👨‍💻

Para iniciarmos nossa API utilizaremos o comando yarn init

Resultado do comando

Após a inicialização do nosso projeto instalaremos as dependências com o comando yarn add hapi nodemon

Criaremos um novo arquivo index.js na raiz do projeto com o seguinte conteúdo :

  • Importar o hapi
  • Declarar uma constante chamada api que criará uma nova instância do Hapi — como argumentos, passaremos um objeto com a porta e o host.
  • Criaremos uma expressão assíncrona chamada start. Dentro desse método teremos um outro método assíncrono que inicia a aplicação.
Conteúdo do arquivo index.js

Caso esteja em dúvida relacionado ao uso de async await recomendo a seguinte leitura.

Iniciando a api

Ao acessar pelo navegador o endereço http://localhost:3000 teremos o seguinte resultado:

404 ?! 😡

Isso é normal meu caro, visto que, o hapi espera uma rota e um handler. Faremos isso logo mais, pois antes iremos adicionar o seguinte script dentro de nosso arquivo package.json

Nodemon 😍

Rotas

As rotas com o hapi são relativamente mais simples. Supondo que ao bater na rota / — o que é esperado que aconteça ? Mas antes disso necessitamos de três informações:

  • Qual é o caminho? — path
  • Qual é o método HTTP ? É umGETPOST ou algo parecido? — method
  • O que acontecerá caso a rota seja encontrada? — handler

Agora para rodarmos nossa api utilizaremos o comando yarn start pois utilizaremos o nodemon para fazer o restart automático após salvarmos nossas alterações:

Conectando nossa API ao MongoDB

Tudo certo até aqui, iremos conectar nossa API ao MongoDB utilizando o Mongoose.

Primeiramente instalaremos o mongoose via yarn:

Para que possamos dar mais agilidade ao desenvolvimento, utilizaremos o mongo na nuvem através do MongoDB Atlas, não se preocupe, pois existe o plano gratuito e que atenderá muito bem esse tutorial.

Após criar sua conta e criar seu primeiro cluster o mesmo deverá estar parecido com a imagem:

Para que façamos a conexão basta ir na opção "Connect" > "Connect Your Application" e copiar a string de conexão :

Após copiarmos a string faremos as seguintes alterações dentro do arquivo index.js :

  • Importar o mongoose
  • Realizar a chamada da conexão com o string ID que acabamos de copiar
  • Definir que uma vez conectado informar no console que a conexão foi bem sucedida.

Caso tudo tenha ocorrido de acordo com o planejado, deveremos ver ‘conectado ao mongoDB’

Criando nosso model

Com o MongoDB utilizaremos a convenção de models. Caso tenha interesse em aprofundar o conhecimento o link está aqui.

Vamos criar um diretório chamado Models e nessa pasta criaremos o arquivo User.js

  • Inserimos a dependência do mongoose
  • Declaramos nosso userSchema chamando o construtor do schema do mongoose e passando as informações e os tipos.
  • Exportamos o model criado e nomeamos o mesmo de User

Consultando e inserindo usuários na base de dados!

Primeiramente importaremos o model que acabamos de criar no arquivo index.js

Mas para que possamos realizar as requisições de consulta e inserção precisaremos definir as rotas das mesmas. Então vamos lá :

Vamos iniciar com as rotas de GET e POST. Onde GET lista todos os usuários e POST inclui um novo usuário .

  • Inserimos as rotas em um array de objetos, e também utilizaremos arrow functions.
  • Criamos um GET em/v1/users . Dentro do handler estamos chamando o schema do mongoose. Chamamos o metodo find() que retorna todos os usuários
  • Também criamos um POST no mesmo caminho. A razão para tal é que estamos seguindo as convenções REST. A partir disso desestruturamos o handler da requisição, após obtermos os campos que precisamos e queremos, passamos os mesmos para o schema do mongoose. Após a passagem de argumentos, chamamos o método save() que salva nosso novo documento no MongoDB .

Estarei utilizando o Insomnia para testarmos as requisições criadas. Mas essa parte fica a seu critério, caso tenha preferência pelo Postman ou alguma outra ferramenta 😄

Realizamos a chamada da rota informando os campos e valores a serem inseridos
  • Realizamos a requisição de post de usuário passando as informações que queremos ser inseridas. Devemos lembrar que os sitesPreferidos se trata de um array.
    Após realizarmos a requisição teremos o seguinte resultado:

Ao realizar a consulta dos usuários pelo insomnia teremos o seguinte resultado:

Listagem de usuários

Tudo certo, mas cadê o GraphQL??

Sim, meu consagrado , deixei a melhor parte para o final. Mas antes, afinal de contas o que é o GraphQL?

Uma forma de compreender é entendendo que ele é uma abstração ao protocolo HTTP, ou seja, você estará utilizando um endpoint na sua aplicação que estará subindo um server GraphQL nela e este server receberá requests do tipo POST e GET e responderá usando um formato JSON.

Para começarmos iremos adicionar o grapghql e o apollo-server-hapi:

GrapghQL é o pacote core do mesmo e o apollo-server-hapi é responsável pela comunicação do hapi com o graphql

Vamos criar um novo diretório chamado graphql e dentro do mesmo o arquivo UserType.js

UserType.js

Importamos o graphQL
Após isso desestruturamos os seguintes objetos do graphql
const { GraphQLObjectType, GraphQLString } = graphql
Que é o mesmo que:
const GraphQLObjectType = graphql.GraphQLObjectType
const GraphQLString = graphql.GraphQLString

Após isso definimos os tipos dos campos, utilizamos os campos do tipo string e numérico, GraphQLString e GraphQLEnumType

Agora que temos nossa query de usuários corretamente criada, precisamos criar o schema da mesma.

Vamos criar um arquivo chamado schema.js dentro da nossa pasta graphql.

Essa será a query que utilizaremos, vamos aos detalhes:

Veja que estamos informando o tipo da query apontando para o arquivo UserType.js e também estamos utilizando o args pois utilizaremos a busca da partir de ID

No final do arquivo exportamos a query criada e a mesma estará pronta para que o hapi utilize a mesma.

Voltando para nosso index.js — Nos importamos: graphqlHapi, graphiqlHapi e o schema.js

Agora iremos realizar a configuração do nosso GraphQL:

Configuração graphiQL

Primeiramente realizarmos a configuração do graphiql, responsável por uma interface que irá facilitar nossas requisições futuras.

Agora que temos a configuração do graphQL devidamente realizada, se formos em http://localhost:3000/graphiql teremos a seguinte interface:

Ao fazer a chamada de nossa query teremos o seguinte resultado:

null? 🤨

Temos nulo por dois motivos:

  • Não estamos buscando as informações do MongoDB
  • Provavelmente não temos um usuário com ID = 20

Vamos implementar a consulta ao MongoDB:

Veja que dentro do arquivo schema.js incluímos as linhas 3 e 14, importando o model e após isso fazendo a busca por ID na linha 14.

Mas como vamos obter o ID do usuário ? Basta fazer a requisição via insomnia conforme tratado anteriormente ou até mesmo acessando a url http://localhost:3000/v1/users

Ao colocar as informações corretas dentro do GraphiQL teremos:

Work's fine

E é isso meu caro padawan, espero que tenha gostado desse guia, ficou um pouco extenso, porém, dando bastante informação para seus primeiros passos com essa stack. Ela também abre portas, para por exemplo, realizar mutations, para inclusão e exclusão de usuários, utilização do hapi-swagger, para gerar documentação do swagger e etc.

segue link do projeto no github:

Espero que tenha se divertido ❤

--

--

Paulo César Queiroz Rodrigues
How Kovi Work

Apaixonado por desenvolvimento web e fazer a diferença na vida das pessoas. Desenvolvedor Web