Photo por Kevin Ku no Unsplash
Criar um backend simples não é uma tarefa tão simples assim... Ainda mais se quisermos que ele use tecnologias mais avançadas como o GraphQL.
Recentemente me encontrei em uma situação ao mesmo tempo simples, porém complexa. Eu estou precisando refazer o meu site pessoal, que hoje é apenas uma página template do GitHub websites, para meu novo site eu tenho certeza que gostaria de ter um arquivo de posts e atividades que participei, ou seja, quero ter uma lista de tudo que fiz e produzi para que possa colocar como um "portfolio" e também um guia para quem precisar acessar o site.
Como já estou planejando este desenvolvimento há um tempo, me inspirei no site do Erick Wendel para ter algumas ideias e decidi ter um backend em GraphQL por alguns motivos bem simples:
- Não vou precisar usar todos os campos no site, portanto quero poder filtrar o que eu vou trazer da API
- Quero ter a capacidade de descrever todo o Schema da minha API em um arquivo
Além disso, quero manter o site simples, não estou querendo nada super complicado ou evoluído, quanto menos tempo e menos código eu puder desprender nele, melhor!
A busca de ferramentas
Inicialmente me senti tentado a seguir para o Hasura, uma ferramenta excelente que provisiona backends em GraphQL instantaneamente, porém o problema é que o único banco suportado é o PostgreSQL, e eu realmente não queria utilizar um banco relacional para poder ter mais flexibilidade na hora de planejar o meu Schema.
Então, depois de alguma busca, acabei encontrando o Mongoke, uma ferramenta open-source que me permite fazer mais ou menos a mesma coisa, porém com o MongoDB.
Preparação
Para esse backend eu precisava de pelo menos um banco de dados já pronto. Então utilizei o Free Tier do MongoDB Atlas na Azure para poder ter um banco robusto sem precisar pagar nada.
Fora isso, todo o resto eu já tinha pronto:
- Website no Github Pages (link)
- Dados no banco de dados
- Mongoke
- Docker para poder testar tudo
- Conta na Azure para hospedar isso tudo
Desenvolvimento
O Mongoke funciona da seguinte maneira:
- Criamos um arquivo
mongoke.yml
com a descrição do nosso Schema GraphQL - Ao executar o Mongoke passando a string de conexão e o caminho do arquivo – ou a URL – teremos a criação de um webserver que servirá nossa API com queries prontas baseadas em nosso schema
Simples não? Vamos colocar em prática!
Criando o arquivo YML
A primeira coisa que precisamos fazer é criar o nosso arquivo de Schema do GraphQL. No meu banco de dados tenho uma collection chamada activities
e ela possui alguns campos que vamos descrever no Schema do Mongoke:
# https://github.com/khaosdoctor/site-backend/raw/master/mongoke.yml
schema: |
enum ActivityType {
talk
article
foss
other
host
book
event
podcast
video
}
type Activity {
_id: ObjectId
id: Int
date: Date
title: String
description: String
type: ActivityType
categories: String
videos: String
url: String
}
types:
Activity:
collection: activities
Primeiramente criamos um enum
para descrever todos os tipos de atividades que tenho em meu banco de dados, isto vai ser essencial para podermos filtrar e validar os inputs do site quando ele estiver no ar.
Em seguida criamos um tipo Activity
que será o registro propriamente dito. Este registro possui os campos descritos no schema anterior. Agora você deve estar se perguntando porque criamos apenas o registro único, não deveríamos ter criado um registro do tipo "lista de atividades"? Algo assim:
type ActivityList {
data: [Activity]
}
É ai que entra a mágica! O Mongoke automaticamente vai criar para nós um tipo <type>Nodes
– no nosso caso, ActivityNodes
– que segue a modelagem de nós e arestas tão comum do GraphQL, desta forma podemos ter a lista de atividades automaticamente.
Depois de definir o type
, vamos precisar dizer que ele é relativo a uma collection no nosso banco, e é para isto que a seção types
serve. Ela está basicamente dizendo que o tipo Activity
está relacionado à collection activities
no meu MongoDB.
Testando localmente
O Mongoke é completamente baseado em Docker, portanto vamos criar um arquivo docker-compose.yml
para poder testar nosso setup localmente antes de precisar fazer o deploy!
# https://github.com/khaosdoctor/site-backend/raw/master/docker-compose.yml
version: "3"
services:
backend:
ports:
- 80:80
image: mongoke/mongoke
environment:
DB_URL: mongodb://mongo/contributions
PORT: "80"
volumes:
- ./mongoke.yml:/conf.yml
mongo:
image: mvertes/alpine-mongo
ports:
- 27017:27017
Veja que estamos subindo uma instancia do mongo localmente para testar e estamos usando as variáveis DB_URL
e criando um volume local na raiz da imagem mongoke/mongoke
para passar o nosso arquivo de schema. Estamos também liberando a porta 80 para acessar o nosso ambiente de testes GraphiQL:
Dica: Sempre use imagens
alpine
como oalpine-mongo
porque elas tem um tamanho consideravelmente menor do que imagens normais
Colocando no ar
Para colocar o backend no ar eu também não queria nenhum tipo de trabalho extra, por isso eu utilizei as Azure Container Instances, que permitem que eu crie um container e rode ele de forma Serverless, ou seja, não tenho que me preocupar com escalabilidade e nem com máquinas, é só executar o meu container diretamente na nuvem!
E tudo fica muito mais simples porque já temos uma imagem pronta do mongoke/mongoke
, ou seja, não vamos precisar fazer absolutamente nada de novo, só usar o que já está providenciado!
Para começar, vamos criar um novo resource group usando o Azure CLI.
Se você ainda não instalou e configurou seu CLI da Azure veja este link
Para fazer isso vamos simplesmente executar o seguinte comando:
az group create --name personal-website --location brazilsouth
Dica: Você pode escolher outras regiões para colocar o seu grupo! Escolhi a região brasileira porque está geograficamente mais próxima da gente.
Depois disso, vamos criar a nossa instância do ACI através do comando:
az container create \
--resource-group personal-website \
--name personal-website-backend \
--image mongoke/mongoke \
--location brazilsouth \
--dns-name-label lsantos-api \
--ports 80 \
--environment-variables \
MONGOKE_CONFIG_URL="https://lsantos.me/site-backend/mongoke.yml" \
DB_URL="<sua URL de conexão com o Mongo Atlas>" \
DISABLE_GRAPHIQL="true"
Perceba o seguinte. Como estamos executando nosso container de forma remote, eu não gostaria de ter que criar e mandar um arquivo para dentro do container, felizmente o Mongoke tem a possibilidade de colocarmos uma URL para o nosso arquivo Schema lá no github! Então podemos hospedar o nosso arquivo no Github Pages ou então pegar o endereço do arquivo raw e colocar na variável MONGOKE_CONFIG_URL
.
Além disso também estou desativando o ambiente GraphiQL porque não queremos o ambiente de testes e sandbox funcionando em nosso ambiente de produção, não é mesmo?
Uma vez que executamos o comando, esperamos alguns instantes e poderemos ver nosso container criado no painel da Azure:
E poderemos acessar a instância, e até mesmo se conectar a ela e buscar seus logs através da aba Containers
:
Podemos então acessar o domínio FQDN gerado pela Azure para poder ver nosso backend completamente no ar!
Conclusão e próximos passos
Este artigo foi baseado na Live que fiz com o Igor Halfeld sobre como podemos criar um backend em GraphQL, então se você quiser assistir como fazemos o desenvolvimento completo é só ver o vídeo abaixo!
O repositório deste backend:
khaosdoctor / site-backend
GraphQL Backend for my website
Para os próximos passos podemos aplicar uma série de automações, por exemplo:
- Deploy automático via Github Actions diretamente para o ACI
- Inserir um novo artigo no banco sempre que eu criar um novo artigo aqui no Dev.to
- Inclusão do nosso FQDN direto em meu sub-domínio através do CloudFlare
E muitas outras ideias! O objetivo deste artigo é mostrar que não é necessário pagar horrores ou então ter um grande trabalho para criar um backend completo utilizando tecnologias de ponta como o GraphQL, você pode criar uma conta gratuitamente na Azure e usufruir dos créditos iniciais para fazer seus testes e até mesmo criar seu backend completo sem precisar pagar um centavo!
Não deixe de acompanhar mais do meu conteúdo no meu blog e se inscreva na newsletter para receber notícias semanais!