Essa é uma implementação de uma API RESTful, com uso de Node.js, Express.js do banco de dados MySQL. É um sistema de gerenciamento de uma loja, que possibilita o usuário a criar, visualizar, deletar e atualizar produtos e vendas. A aplicação foi construída com a arquitetura MSC (model-service-controller) e foi Dockerizada. Tudo isso com validações e testes pensados para os casos de uso da aplicação, garantindo a qualidade e integridade do código.
O foco dessa projeto foi praticar a construção de um sistema CRUD completo, assim como explorar a arquitetura MSC para construção de uma API robusta, escalável e de fácil manutenção.
Para rodar esta aplicação é necessário ter o Docker e o Docker Compose (v1.29 ou superior) instalados em sua máquina.
- Clone o repositório e entre no diretório
git clone git@github.com:lzaghi/crud-basics.git
cd crud-basics
- Instale as dependências
npm install
- Suba os containeres do Node e do MySQL
docker-compose up -d --build
- Rode o comando para abrir o terminal do container Node
docker exec -it store_manager bash
- Rode o comandos para criar e popular as tabelas
npm run migration
npm run seed
Essa etapa também pode ser feita diretamente a partir de um cliente MySQL de sua preferência, como o MySQL Workbench.
Conecte-se na porta 3006
com as credenciais de user root
e senha password
, e execute os scripts que estão nos arquivos migration.sql
e seed.sql
.
- Inicie a aplicação
npm start
A aplicação estará rodando em http://localhost:3000
Para rodar os testes
npm run test:mocha
A documentação completa da API pode ser consultada na rota http://localhost:3000/swagger
, após a aplicação estar rodando.
Segue um resumo do que é documentado na rota citada acima:
Especificações das requisições
Cadastrar produto
POST /products
Exemplo de Entrada:
{
"name": "ProdutoX"
}
Exemplo de retorno:
Em caso de sucesso - status 201:
{
"id": "4",
"name": "ProdutoX"
}
Em caso de erro - status 400:
{
"message": "'name' is required"
}
Ou status 422:
{
"message": "'name' length must be at least 5 characters long"
}
Consultar produtos
GET /products
Exemplo de retorno:
Status 200:
[
{
"id": 1,
"name": "Martelo de Thor"
},
{
"id": 2,
"name": "Traje de encolhimento"
},
{
"id": 3,
"name": "Escudo do Capitão América"
}
]
Consultar produto por nome
GET /products/search
Exemplo de Pesquisa:
URL http://localhost:3000/products/search?q=martelo
Exemplo de retorno:
Sucesso - status 200:
[
{
"id": 1,
"name": "Martelo de Thor"
}
]
Consultar produto por id
GET /products/{id}
Exemplo de Pesquisa:
URL http://localhost:3000/products/3
Exemplo de retorno:
Em caso de sucesso - status 200:
{
"id": 3,
"name": "Escudo do Capitão América"
}
Em caso de erro - status 404:
{
"message": "Product not found"
}
Atualizar produto
PUT /products/{id}
Exemplo de Entrada:
URL http://localhost:3000/products/3
{
"name": "ProdutoX"
}
Exemplo de retorno:
Em caso de sucesso - status 200:
{
"id": 3,
"name": "ProdutoX"
}
Em caso de erro - status 400:
{
"message": "'name' is required"
}
Ou status 404:
{
"message": "Product not found"
}
Ou status 422:
{
"message": "'name' length must be at least 5 characters long"
}
Deletar produto
DELETE /products/{id}
Exemplo de retorno:
Em caso de sucesso - status 204:
no content
Em caso de erro - status 404:
{
"message": "Product not found"
}
Cadastrar venda
POST /sales
Exemplo de Entrada:
[
{
"productId": 2,
"quantity": 5
}
]
Exemplo de retorno:
Em caso de sucesso - status 201:
{
"id": 3,
"itemsSold": [
{
"productId": 2,
"quantity": 5
}
]
}
Em caso de erro - status 400:
{
"message": "'productId'/'quantity' are required"
}
Ou status 404:
{
"message": "Product not found"
}
Ou status 422:
{
"message": "'quantity' must be greater than or equal to 1"
}
Consultar vendas
GET /sales
Exemplo de retorno:
Status 200:
[
{
"saleId": 1,
"date": "2023-08-15T20:30:31.000Z",
"productId": 1,
"quantity": 5
},
{
"saleId": 1,
"date": "2023-08-15T20:30:31.000Z",
"productId": 2,
"quantity": 10
},
{
"saleId": 2,
"date": "2023-08-15T20:30:31.000Z",
"productId": 3,
"quantity": 15
}
]
Consultar venda por id
GET /sales/{id}
Exemplo de Pesquisa:
URL http://localhost:3000/sales/2
Exemplo de retorno:
Em caso de sucesso - status 200:
[
{
"date": "2023-08-15T20:30:31.000Z",
"productId": 3,
"quantity": 15
}
]
Em caso de erro - status 404:
{
"message": "Sale not found"
}
Atualizar venda
PUT /sales/{id}
Exemplo de Entrada:
URL http://localhost:3000/sales/2
[
{
"productId": 2,
"quantity": 50
}
]
Exemplo de retorno:
Em caso de sucesso - status 200:
{
"saleId": 2,
"itemsUpdated": [
{
"productId": 2,
"quantity": 50
}
]
}
Em caso de erro - status 400:
{
"message": "'productId'/'quantity' are required"
}
Ou status 404:
{
"message": "Product not found"
}
Ou status 422:
{
"message": "'quantity' must be greater than or equal to 1"
}
Deletar venda
DELETE /sales/{id}
Exemplo de retorno:
Em caso de sucesso - status 204:
no content
Em caso de erro - status 404:
{
"message": "Sale not found"
}
Node.js, Express.js, MySQL, Docker, Joi, Mocha, Chai, Sinon, Arquitetura MSC, API RESTful
Análise SonarCloud