- 1. Prefácio
- 2. Resumo do projeto
- 3. Objetivos de aprendizagem
- 4. Considerações gerais
- 5. Critérios de aceitação mínimos do projeto
- 6. Hacker (Devops) Edition con Docker
- 7. Pistas, tips e leituras complementares
Um pequeno restaurante de hamburgueres, que está crescendo, necessita de um sistema para realizar pedidos usando um tablet, e que os enviem à cozinha para que sejam preparados de forma ordenada e eficiente.
Este projeto tem duas áreas: interface (cliente) e API (servidor). Nosso cliente nos solicitou que desenvolvêssemos uma API que pode integrar com a interface, que outra equipe de desenvolvedores está trabalhando simultaneamente
Como API, nesse caso nos referimos a um servidor web, que é basicamente um programa que ouve o que acontece na aplicação através de uma porta de rede, pela qual podemos enviar requisições (requests) e obter respostas (responses) usando o protocolo HTTP (o HTTPS).
Um servidor web deve lidar com as requisições que chegam e devolver respostas, que serão enviadas de volta ao cliente. Quando falamos de aplicações de servidor, isso implica uma arquitetura de cliente/servidor, onde o cliente é um programa que faz requisições através de uma rede (por exemplo o navegador, o cURL, etc) e o servidor é o programa que recebe essas requisições e as responde.
O Node.js nos permite criar servidores web super eficientes de maneira relativamente simples, tudo isso usando JavaScript!
Neste projeto partimos de um boilerplate que já contém uma série de endpoints (pontos de conexão ou URLs) e nos pedem para completar a aplicação. Isso implica que teremos que começar lendo a implementação existente e nos familiarizar com o stack escolhido (Node.js e Express), além de complementá-lo com um motor de banco de dados. Recomendamos o uso do MongoDB e temos um guia para começar com o MongoDB.
MongoDB, PostgreSQL e MySQL.
O cliente nos deu um link para a documentação que especifica o comportamento esperado da API que iremos expor por HTTP. Lá podemos encontrar todos os detalhes que os endpoints deve implementar na aplicação, que parâmetros esperam, o que devem responder, etc.
O objetivo de aprendizagem principal é adquirir experiência com o Node.js como ferramenta para desenvolvimento de aplicações de servidor, junto com uma série de outras ferramentas comumente utilizadas nesse contexto (Express como framework, MongoDB como base de dados, etc.).
Neste projeto, você desenvolverá um servidor web que deverá servir JSON
através de uma conexão HTTP
, e implantá-lo em um servidor na nuvem.
Ao final do projeto, você deverá estar familiarizada com conceitos como rotas
(routes), URLs, HTTP (verbos, request, response, headers, body, status
codes, etc), JSON, JWT (JSON Web Tokens), conexão com uma base de dados
(MongoDB
), variables de ambiente, deployment, etc.
Reflita e depois enumere os objetivos que quer alcançar e aplique no seu projeto. Pense nisso para decidir sua estratégia de trabalho.
-
Instalar e usar módulos com npm
-
Configuração do package.json
-
Configuração do npm-scripts
-
Uso de linter (ESLINT)
-
Uso de identificadores descritivos (Nomenclatura e Semântica)
-
Testes unitários (unit tests)
-
Testes assíncronos
-
Uso de mocks e espiões
- Testes de integração (end-to-end)
-
Módulos de ECMAScript (ES modules)
-
Módulos de CommonJS
-
Git: Instalação e configuração
-
Git: Controle de versão com git (init, clone, add, commit, status, push, pull, remote)
-
Git: Integração de mudanças entre ramos (branch, checkout, fetch, merge, reset, rebase, tag)
-
GitHub: Criação de contas e repositórios, configuração de chave SSH
-
GitHub: Implantação com GitHub Pages
-
GitHub: Colaboração pelo Github (branches | forks | pull requests | code review | tags)
-
GitHub: Organização pelo Github (projects | issues | labels | milestones | releases)
-
Gerenciamento de rotas
-
Uso e criação de middleware
-
Consulta ou solicitação (request) e resposta (response).
-
Cabeçalhos (headers)
-
Corpo (body)
-
Verbos HTTP
-
Códigos de status de HTTP
-
Encodings e JSON
-
CORS (Cross-Origin Resource Sharing)
-
JWT (JSON Web Token)
-
Armazenamento e acesso de senhas
-
Variáveis de ambiente
-
Containers (Docker)
-
Docker compose
-
Cloud Functions
-
Operações CRUD (Create-Read-Update-Delete)
-
Modelos e esquemas de dados
-
Recuperação e restauração (backup/restore)
-
Cliente de terminal psql
-
Tipos de dados
-
Backup e restauração (backup/restore)
-
Cliente de terminal mysql
-
Tipos de dados
-
Backup e restauração (backup/restore)
-
Modelagem de dados
-
Conexão
-
Criação e modificação de tabelas
-
Operações CRUD (Create-Read-Update-Delete)
-
Exclusão de tabelas ou bancos de dados inteiros com DROP
Este projeto será realizado em duplas e pode estar integrado com o projeto Burger Queen API client que a equipe de Frontend developers do seu squad desenvolve simultaneamente.
A lógica do projeto deve estar implementada totalmente em JavaScript (ES6).
Neste projeto está permitido usar bibliotecas ou frameworks, assim como
extensões para a linguagem com babel
(neste caso você incluir um
comando npm build
).
Os testes deven cobrir um mínimo de 90% de statements, functions, lines e branches. Embora o boilerplate não inclua as configurações para testes unitários, estes são obrigatórios.
Outro requisito da equipe de QA do nosso cliente é realizar testes end-to-end, que usaremos para verificar o comportamento desde o ponto de vista de HTTP, desde fora do servidor. Estes testes, diferente dos testes unitarios, não testam cada parte separadamente, mas testam a aplicação completa, do princípio ao fim. Esses testes, por não fazerem uso direto do código-fonte da aplicação, podem ser executados diretamente em uma URL remota, pois a interface em teste é HTTP.
O boilerplate já contém o setup e configuração
necessária para executar todos os tests end-to-end com o comando npm run test:e2e
.
# Execute testes e2e na instância local. Isso levanta a aplicação com npm
# start e execute os tests na URL desta instancia (por padrão
# http://127.0.0.1:8080).
npm run test:e2e
# Execute testes e2e em URL remoto
REMOTE_URL=<TODO: colocar URL> npm run test:e2e
Os testes end-to-end já estão concluidos no boilerplate, então pode usá-los como um guia de implementação e lista de verificação de integridade.
A API deve expor os serviços da documentação fornecida pela nossa cliente.
O cliente solicitou que a aplicação tenha um comando npm start
que deve ser responsável por executar nossa aplicação node e que também possa
receber informações de configuração, como a porta a ser escutada, qual
banco de dados conectar, etc. Esses dados de configuração serão distintos entre os
diferentes ambientes (desenvolvimento, produção, ...). O boilerplate já implementa
o código necessário para ler esta informação dos
argumentos de invocação
e o
ambiente.
Podemos especificar a porta onde a aplicação deve iniciar, passando um argumento ao invocar nosso programa:
# Inicia a aplicação na porta 8888 usando npm
npm start 8888
Nossa aplicação usa as seguintes variáveis de ambiente:
PORT
: Se nenhuma porta for especificada como argumento da linha de comando podemos usar a variable de ambientePORT
para especificar a porta. Valor por padrão8080
.DB_URL
: A string de conexão de MongoDB, PostgreSQL ou MySQL. Quando executemos a aplicação em nosso computador (em ambiente de desenvolvimento), podemos usar um banco de dados local, mas em produção deveremos usar as instâncias configuradas comdocker-compose
(mais sobre isso na seção de Deployment).JWT_SECRET
: Nossa aplicação implementa autenticação usando JWT (JSON Web Tokens). Para assinar (criptografar) e verificar (descriptografar) os tokens, nossa aplicação precisa de um segredo. Localmente, pode usar o valor padrão (xxxxxxxx
), mas é muito importante usar um segredo real na producção.ADMIN_EMAIL
: Opcionalmente podemos especificar um email e password para o usuario admin (root). Se esses detalhes estiverem presentes, a aplicação se certificará que exista o usuário e que tenha permissões de administrador. Valor por padrãoadmin@localhost
.ADMIN_PASSWORD
: Se for especificado umADMIN_EMAIL
, devemos passar também uma senha para o usuário admin. Valor por padrão:changeme
.
Você pode escolher o provedor (ou provedores) que preferir, juntamente com o mecanismo de implantação e estratégia de hospedagem. Recomendamos que você explore as seguintes opções:
- Vercel é uma opção focada em aplicativos da web estáticos (como os construídos com React). No entanto, o Vercel também nos permite implantar aplicativos node usando Serverless Functions MongoDB Atlas é uma ótima opção para hospedar nosso banco de dados de produção, que pode ser usado em conjunto com qualquer uma das opções mencionadas acima.
Se tiver dúvidas sobre as diferentes opções de implantação (que são várias), não hesite em consultar seus colegas e seus coaches.
Nossa cliente nos informou que sua equipe de DevOps está sempre
ocupada com muitas tarefas, portanto, ela nos pede como requisito que
o aplicativo seja configurado com docker-compose
para que possa ser
implantado facilmente em qualquer ambiente.
O boilerplate já possui uma configuração inicial de docker-compose
para o aplicativo Node.js, sua tarefa será estender essa configuração para
incluir a configuração do banco de dados. Tenha em mente que,
como você terá dois servidores sendo executados na mesma configuração,
você precisará expor os serviços em portas diferentes.
Leia o guia para docker incluído no projeto para mais informações.
Para testar sua configuração do Docker, recomendamos que você use o
docker-compose
localmente (em seu computador) para executar o
aplicativo junto com o banco de dados.
Quanto à implantação, você pode escolher o provedor (ou provedores) que preferir, juntamente com o mecanismo de implantação e estratégia de hospedagem. Recomendamos que você explore as seguintes opções:
- Se quiser explorar opções mais personalizadas e ver o docker do lado do servidor, pode considerar provedores como AWS (Amazon Web Services) ou GCP (Google Cloud Platform), ambos possuem algum tipo de serviço experimental gratuito (free tier) assim como instâncias de servidores virtuais (VPS), onde configuramos nosso próprio Docker ou serviços para implantar aplicações em contêineres (por exemplo Compute Engine de GCP ou Elastic Container Service de AWS).
ℹ️ Antes de começar a programar, recomendamos que você leia e siga cuidadosamente o guia de primeiros passos para ajudá-lo com o stack recomendado e configurar seu ambiente de desenvolvimento.