Como montar Uma API com GraphQl em Node.js com Apollo Server e MongoDB
Ikaro-silva
Posted on February 9, 2023
Sobre o tutorial
A proposta é fazer um API que possa gerenciar Usuários fazendo operações CRUD com os dados.
No servidor usaremos Node.js, vamos começar a desenvolver a nossa API em GraphQl?
Tecnologias
- Node.js(plataforma usada)
- Apollo-Server(usado para montar o servidor)
- MongoBD(banco de dados)
Estrutura do projeto:
-API_GraphQL
- src
-config
-DBconfig.js
-model
-user.model.js
-resolvers
-index.js
-userResolver.js
-typeDefs
-index.js
-mutation.js
-query.js
-types.js
-.gitignore
-package-lock.json
-package.json
-server.js
Iniciando com o Node.Js
npm
npm init -y
Abra o terminal no local da pasta do projeto API_GraphQ execute o comando acima
Instalando dependências
Apollo-Server,GraphQL, mongoose, dotenv
npm install graphql apollo-server mongoose dotenv
Na pasta do projeto API_GraphQ execute o comando acima.
- graphql: Montar schemas e executar queries GraphQL
- apollo-server: Montar servidor GraphQL(tem ferramenta de suporte para teste da api)
- mongoose: Montar o model para o banco de dados e estabelecer conexão com o MongoDB
- dotenv: Montar variáveis de ambiente
GraphQL/Apollo-Server/MongoDB
Precisamos definir algumas necessidades do servidor GraphQL, seriam o typeDefs e o resorvers, além disso ainda existe o model
3 Principais itens
- TypeDefs(Definição de tipo):Modelar dados com base nos Schemas
- Resolvers: Definir como será feita cada ação dentro do banco de dados
- Model: Definir campos usados no banco de dados Configurando servidor/conexão com banco de dados Na pasta API_GraphQL, crie uma pasta src
Em API_GraphQL/src crie um arquivo server.js
Caminho:API_GraphQL/src/server.js
const { ApolloServer }=require("apollo-server")
const mongose=require('mongoose')
const typeDefs=require('./src/typeDefs/index')
const resolvers=require('./src/resolvers/index')
const DBconfig=require('./src/config/DBconfig')
//BANCO DE DADOS
mongose.set('strictQuery', false)
mongose.connect(DBconfig.URI)
.then(()=>{
console.log('Banco de dados conectado')
})
.catch(err=>{
console.log('Falha ao conectar ao banco de dados',err)
})
//SERVIDOR
const server = new ApolloServer({ typeDefs, resolvers });
server.listen()
.then(({url})=>{
console.log('servidor conectado na url',url)
}).catch(err=>{
console.log('falha ao se conectar ao servidor',err)
})
Na conexão do servidor temos chamadas para os arquivos resolvers e typeDefs,vamos cria-los?
Criando definições de tipo (typeDefs)
O typeDefs é uma junção de 3 itens:
Types: Definir dados com base nos tipos de schemas
Query: Definir comando de consultas da api
Mutation: Definir comandos que mudam os dados da api
Para criarmos as definições de tipo crie uma pasta typeDefs em API_GraphQL/src
Caminho: API_GraphQL/src/typeDefs
Crie os seguinte arquivos:
-typeDefs
-index.js
-mutation.js
-query.js
-types.js
Types
vamos começar com criando os typos (type), dentro da API GraphQl ele é responsável por modelar os dados, sempre em concordância com os schemas do model definido pelo mongoose e o mongoDB.
Em typeDefs/types.js escreva o seguinte código:
Caminho: API_GraphQL/src/typeDefs/types.js
const{ gql }=require('apollo-server')
const types = gql`
type User {
id: ID
nome: String!
email: String!
senha: String!
}
`;
module.exports=types
Query
Agora vamos montar a query. Vamos montar 2 queries : uma que retorna um array de usuários e o outro vai retornar somente um usuário a partir de um id informado.
Em typeDefs/types.js escreva o seguinte código:
Caminho: API_GraphQL/src/typeDefs/query.js
const{gql}=require ('apollo-server')
const query=gql`
type Query{
users:[User]!
user(id:ID!):User!
}
`;
module.exports=query
Pronto as queries estão definidas. No trecho de código acima dissemos ao servidor que a query chamada useres deve retornar um array com dados do tipo User (definido no passo anterior) e a query chamada user deve ter um parâmetro chamado id com um dado do tipo ID (já existente em GraphQL) e retornar um ítem do tipo User. A exclamação (!) define o campo como obrigatório.
Mutation
Agora vamos definir a mutation, essa parte é parecida com as queries. Mutations são queries responsáveis por alteração de dados.
Em typeDefs/types.js escreva o seguinte código:
Caminho: API_GraphQL/src/typeDefs/mutation.js
const {gql}=require('apollo-server')
const mutation=gql`
type Mutation {
createUser(user: CreateUserInput!): User!
updateUser(id: ID!, user: UpdateUserInput!): User!
deleteUser(id: ID!):User
}
input CreateUserInput {
nome: String!
email: String!
senha: String!
}
input UpdateUserInput {
nome: String
email: String
senha: String
}
type User {
id: ID!
nome: String!
email: String!
senha: String!
}
`;
module.exports=mutation
Além do tipo Mutation estão definidos alguns tipos input, esses inputs são para separar os parâmetros passados a mutation a fim de deixar as assinaturas mais limpas e de fácil manutenção.
Conclusão de typeDefs
Para concluir essa parte. Em typeDefs/types.js escreva o seguinte código:
Caminho: API_GraphQL/src/typeDefs/query.js
const query= require('./query')
const mutation= require('./mutation')
const types = require('./types')
const typeDefs=[query,mutation,types]
module.exports=typeDefs
Criando models
Vamos definir o model User para que possamos modelar os dados do banco de dados usando os resolvers.
Em model/-user.model.js escreva o seguinte código:
Caminho: API_GraphQL/src/model/-user.model.js
const mongoose=require('mongoose')
const userSchema=new mongoose.Schema({
nome:{
type:String
},
email:{
type:String
},
senha:{
type:String
},
})
const User=mongoose.model('User',userSchema)
module.exports=User
Criando Resolvers
Resolvers é aonde associamos quais ações queries e mutations devem tomar e lá também é aonde é definido as chamadas feitas no banco de dados. Então usamos o model apara implementar essas ações no banco de dados.
Em resolvers/userResolver.js escreva o seguinte código:
Caminho: API_GraphQL/src/resolvers/userResolver.js
const User= require('../model/user.model')
const useResolver={
Query:{
async users(){
const useres =await User.find({})
if(useres==null){
console.log("falha na consulta")
return
}
else{
return useres
}
},
async user(_, {id}){
const userid=await User.findById(id)
return userid
},
},
Mutation:{
createUser(_,{user}){
const newUser=new User(user)
return newUser.save()
},
async updateUser(_,{id,user}){
const userUpda=await User.findByIdAndUpdate(id,user)
return userUpda
},
async deleteUser(_, { id }) {
const deteUser=await User.findByIdAndRemove(id);
return deteUser
},
}
}
module.exports=useResolver
Neste arquivo usamos métodos expostos pela biblioteca Mongoose onde criamos a model no passo anterior. Dessa forma associamos as queries e mutations criadas nas definições de tipos à ações no banco de dados MongoDB.
Conectando banco de dados
Para conectar ao banco usaremos DotEnv para armazenar as credenciais do banco. Essa biblioteca permite criar variáveis de ambiente onde podemos ter as credenciais do banco ao invés de tê-las no código o que comprometeria as informações deixando disponíveis a qualquer pessoas com acesso ao código, por exemplo, num repositório git.
Em API_GraphQL/.env escreva o seguinte código:
Caminho: API_GraphQL/.env
URI=mongodb://localhost:27017/GraphQL
Configurando variáveis
Arquivo responsável por configurar as variáveis de ambiente.
Em config/DBconfig.js escreva o seguinte código:
Caminho: API_GraphQL/src/config/DBconfig.js
const dotenv =require('dotenv')
dotenv.config()
// variavel de ambiente "URI" do mongodb
module.exports={
URI:process.env.URI
}
Pronto,nossa API-GraphQL está pronta!
Testando a API
Iniciando API
node .server.js
Criar usuários:
mutation createUser{
createUser(user:{
nome:"ikaro silva",
email:"ikaro@gmail.com",
senha:"123654987"})
{
id
nome
email
senha
}
}
Consultar todos usuários:
query users{
users {
id
nome
email
senha
}
}
Consultar por id:
query userID{
user(id:"63e29267d39499c37d9496e2") {
id
nome
email
senha
}
}
Editar por id:
mutation editar{
updateUser(id:"63e29267d39499c37d9496e2", user:{
nome: "ikaro silva",
email:"ikaro@gmail.com",
senha:"123654987"
}){
id
nome
email
senha
}
}
Deletar por Id:
mutation deleteID{
deleteUser(id:"63e29267d39499c37d9496e2") {
id
nome
email
senha
}
}
Para mais informações de como usar queries e mutations acesse:
GraphQlTodos os testes foram executado na ferramenta que o apollo-server disponibilizar:
Ferramenta do Apollo
Posted on February 9, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.