This is a backend of a store. It was developed with Node.js
Go to file
2023-01-25 18:22:01 -03:00
controllers FIX: comment in controllers/products.js 2023-01-25 15:10:44 -03:00
models FIX: connection.js and db-import-for-host in models/ 2023-01-04 17:04:42 -03:00
services feat: Add 'getAllFiltered' in SERVICES and fix it in MODEL 2021-12-27 10:49:09 -03:00
utils chore: Deleta utils/validMidds 2021-11-18 02:28:23 -03:00
.dockerignore FEAT: Implemets PORT variable 2023-01-03 00:17:47 -03:00
.editorconfig Initial commit 2021-10-15 17:58:04 -03:00
.env.model FEAT: Add .env.model file 2023-01-03 00:42:08 -03:00
.eslintignore Initial commit 2021-10-15 17:58:04 -03:00
.eslintrc.json Initial commit 2021-10-15 17:58:04 -03:00
.gitignore chore: Update ALL dependencies 2021-12-16 09:28:53 -03:00
compose-dev-with-front.yml FEAT: compose-dev-with-front uses Dockerfile-dev and another front Dockerfile 2023-01-25 18:22:01 -03:00
compose-dev.yml FEAT: compose-dev uses Dockerfile-dev 2023-01-25 18:20:27 -03:00
compose-with-front.yml FEAT: Better adapt compose-with-front.yml to frontend 2023-01-25 14:30:37 -03:00
compose.yml CHORE: remove unecessary things from compose.yml 2023-01-24 11:40:59 -03:00
Dockerfile CHORE: update Dockerfile for performace 2023-01-24 11:42:44 -03:00
Functional-Requirements.md chore: Add 'functional-Requirements' file 2021-12-16 08:01:44 -03:00
index.js CHORE: remove unecessary asterisk from cors in index 2023-01-24 11:44:26 -03:00
package-lock.json FIX: .dockerignore 2023-01-01 09:41:59 -03:00
package.json FIX: project name in package.json 2023-01-01 08:01:46 -03:00
README.md DOC: Update "Como executar > Opção 1 - Via Docker" 2023-01-04 16:42:44 -03:00

Boas vindas ao repositório Games Store (Backend)

Esse projeto é Uma API RESTfull de um sistema de gerenciamento de uma loja de games, onde é possível criar, visualizar, deletar e atualizar os produtos e as vendas. Usado Node.js, Express e MongoDB. Ainda em fase de desenvolvimento, porém é possível já utilizar.


Tem FRONT ?

Aqui está o link do repositório frontend que também fiz para usar com essa API. Desenvolvi algumas interfaces para interagir com essa API.

Então, corre lá pra dá uma olhada e aproveite para sentar aquele dedo nos botões de Code Review pra ajudar o projeto.

Sumário

Habilidades

Esse projeto teve como objetivo praticar as seguintes hardskills:

  • Estruturação de uma aplicação em camadas (Arquitetura MSC);
  • Delegação de responsabilidades específicas para cada parte do app;
  • Melhora da manutenibilidade e reusabilidade do código;
  • Aplicação dos padrões REST;
  • Implementação de uma API intuitiva e facilmente entendível.

Descrição

Se trata de uma API de gerenciamento de vendas que manipula produtos e vendas. Basicamente é um modesto controle de estoque em forma de CRUD para lidar tanto com produtos como com as vendas .

Seguindo os princípios REST foi desenvolvido alguns ENDPOINTS que se conectam a um banco de dados NÃO relacional (NoSQL), MongoDB.

Há uma Collection para produtos (products) serem cadastrados na aplicação, afim de ser possível fazer vendas com esses produtos. Da mesma forma, uma Collection para vendas (sales) também foi criada. Essas vendas são realizadas conforme a quantidade de produtos disponíveis em estoque.

Requisitos de Usuário

  • Deve ser possível que a pessoa usuária, independente de cadastramento ou login, possa adicionar, ler, deletar e atualizar produtos no seu estoque. (Mas irei implantar Login e autorizações de usuários também brevemente)
  • O usuário deve poder também enviar vendas para o sistema. Essas vendas devem validar se o produto em questão existe.
  • Deve, também, ser possível ler, deletar e atualizar vendas.

Arquitetura e Padrões

Sumário

  • Arquitetura MSC
  • API RESTfull

Tecnologias utilizadas

Sumário

  • Node.js
  • Express
  • MongoDB
  • ESLinter (Para auxiliar na análise de erros no código e também para ajudar manter algumas boas práticas)

Futuras implementações

Sumário

  • Autenticação de Usuários (Login)
  • Autorizações de usuários com uso de tokens (JWT).
  • Implantar a aplicação via Cloud ou VPS, para que possa ser consumida e testada externamente.
  • Implantar o Banco de Dados em nuvem do MongoDB Atlas ou algo do tipo.

Requisitos para execução da API

Sumário

Você pode rodar esse projeto de duas maneiras: 1 - Via Docker 🐳 ou 2 - Manualmente 🖐️

Opção 1 - Via Docker

  Se não tiver, baixe-o no [site oficial](https://docs.docker.com/engine/install/)

Opção 2 - Manualmente (Via Host)

  1. Node.js

    Nodejs é um framework que tem um engine do Chrome modificada o qual permite que exista, no lado servidor, uma aplicação Web desenvolvida em JavaScript. Portanto é o primeiro sofware que permite esse projeto acontecer.

    Já testei com Node nas versões 14 à 18. Acredito que funcione nas outras versões. Para instalar , configurar e gerenciar Nodejs de forma produtiva, recomendo uso da ferramenta NVM. Com NVM você consegue, "com um dedo", instalar várias versões do Nodejs e escolher qual usá-las quando precisar. Mas, se quiser ter mais trabalho, baixe o Nodejs do site oficial.

  2. MongoDB

    Essa API se comunica com um banco de dados não relacional (noSQL) implementado em MongoDB. Então precisa ter em algum lugar (local ou remotamente) o software gerenciador de servidor de banco dados, MongoDB, que se possa usar aqui.

    Caso não o tenha, faça download e instale-o.

    Site oficial para download do MongoDB Comunnity Edition.

  3. Software cliente para requição de API (ex.: Postman, Insomnia e etc)

    Para testar todos os métodos de requição à essa API, se faz necessário um Software específico para isso. Dentre os mais conhecidos até o momento são Postman e Insomnia.

    Se for apenas testar o método GET no endpoint, apenas com um browser comum é possível.

    Por exemplo. Fazendo uma requisição GET a partir de um Browser (Firefox, Chrome e etc) para a URL http://localhost:3000 , funciona.

Como Executar

Sumário

Opção 1 - Via Docker

1. Verifique o arquivo compose.yml

Pode ser que tenha algo a ser mudado nesse aqruivo que atenda as tuas especificidades. Acredito que as únicas coisas relevantes que possa ter alguma possiblidade de mudança seria: 1 - Porta exposta e 2 - Nome da rede

  • Se porta padrão exposta (3000) já esteja em uso por outra aplicação, então mude isso, se for o caso. Quanto ao nome da rede, acho pouquíssimo provável que já exista outra como o mesmo nome. Todavia, mude se julgar necessário.
  • Se mudar valor da variável DB_NAME no arquivo _compose.yml_ , tambem terá que mudar nos arquivos Dockerfile e models/Dockerfile, E VICE-VERSA.

Referente as outras opções, acredito não haver muita necessidade de alteração mesmo.

Mas, se for alterar algo nesses arquivos, LEIA os comentários ali para não ficar batendo cabeça à toa, uma vez que alterações incorretas inviabilizam o correto funcionamento da aplicação.

2. Execute o docker compose

Basta usar o arquivo compose.yml e ajustar o que achar necessário antes Estando na pasta do arquivo, via CLI, basta digitar:

  ` docker compose up -d `

Opção 2 - Manualmente (Via Host)

Instalado os requisitos e as dependências necessárias, basta seguir as seguintes etapas:

1. Variáveis de ambiente

Existe um arquivo na raiz do projeto chamado .env.model. Apesar de já explicado no tópico "Requisitos para execução da API", não custa ratificar aqui. As configurações do projeto também podem ser alteradas nesse arquivo, adicionando o valor desejado após o sinal de igual (=) em cada variável. Lógico que não é obrigado essa alteração, desde que não exista problemas com as configurações padrões do projeto. Se for usar o arquivo, terá que renomea-lo parar .env.

As variáveis do arquivo .env.model são as seguintes: PORT, DB_NAME, DB_HOST e DB_PORT.

PORT diz respeito a porta em que o servidor irá rodar. Se nada for atribuido a essa variável, o servidor rodará na porta 3000.

DB_NAME refere-se ao nome do banco de dados que será criado. Se nada for atribuido, o nome do banco será GamesStore.

DB_HOST refere-se ao local (hostname ou IP) do Banco de Dados. Se nada for atribuído, será considerado localhost.

DB_PORT poderá receber a porta onde se encontra o Banco de Dados. Se nada for atribuído, será considerado a porta 27017.

2. Banco de Dados MongoDB Coloque em execução o software servidor de banco de dados MongoDB.

3. Execute o script para importar dados para o banco de dados Para que essa API retorne dados na rota products, precisa, obviamente, ter dados no banco chamado GamesStore (ou no banco com nome que você definiu na variável DB_NAME no arquivo .env) na coleção ("tabela") products. Por isso criei um shell script models/db-import-for-host.sh para automatizar a importação de dados, o qual cria o banco, a collection e importa dados que estão em outro script (arquivo models/dataTestForDb.js) para o banco criado. Assim, quando requisitado com GET no ENDPOINT products será retornado esses dados previamente importados no banco, isentando a necessidade de criá-los manualmente para testar a API. Se não quiser usar esse script, ok, a API funciona, mas sem retornar dados; a menos que, alternativamente, cadastre-os, manualmente, usando a rota de POST, por exemplo.

Note: Não criei script (importador de dados) para a rota sales. Se requisitares algo para esse ENDPOINT, sem ter dados na collection sales no banco, não terás retorno de dados.

Note 2: Os dados que se encontram no arquivo models/dataTestForDb.js, foram obtidos do ENDPOINT de produtos para gamers, de uma API pública do Mercado Livre. Apenas modifiquei alguns pontos e parâmetros para se adaptar ao meu projeto.

4. Instale as dependências

Estando com acesso a internet e dentro da pasta raíz do projeto, execute o comando:

npm install

5. Execute o projeto

Estando com acesso a internet e dentro da pasta raíz do projeto, execute o comando:

npm start

Se tudo ocorreu bem, após executar esse comando o servidor da API do projeto estará disponível para uso. Faça as requisições.

6. Fazendo requisições

Use algum software cliente de API (ex.: Postman, Insomnia e etc) e faça as requisições para os ENDPOINTs usando a URL http://localhost:3000 Se for o caso, não esqueça de substituir porta 3000 pela porta que você definiu na variável PORT do arquivo .env.

Endpoints

Sumário

Produtos

  • GET: /products
  • GET: /products/:id
  • POST: /products
  • PUT: /products/:id
  • DELETE: /products/:id

Vendas

  • GET: /sales
  • GET: /sales/:id
  • POST: /sales
  • PUT: /sales/:id
  • DELETE: /sales/:id

Linter

Sumário

Foi usado ESLint para fazer a análise estática do código, afim de manter padrões de indentação e espaçamento dos trechos de códigos. No entanto, para usá-lo de forma mais manual, o projeto já vem com as dependências relacionadas ao ESLint configuradas no arquivos package.json.

Para executá-lo basta usar --- dentro da pasta do projeto --- o comando npm run lint. Se a análise do ESLint encontrar problemas no código, tais problemas serão mostrados no seu terminal. Se não houver problema no seu código, nada será impresso no seu terminal.

ESLint de forma automática

Particulamente eu preferi utilizar o plugin ESLint pela extensão do VSCode, em favor da produtividade.


Observações

Sumário

Estrutura da lista de requisitos funcionais

Estrutura do banco de dados:

  • Observação: O _id é gerado automaticamente.

  • O banco deve ter duas collections: uma para os produtos e outra para as vendas

    • A tabela de produtos terá o seguinte nome: products

      • Os campos da collection products terão esse formato:

        {
          "name": "Sony Playstation 5 825gb Digital Edition Cor  Branco E Preto",
          "price": 6499,
          "thumbnail": "http://http2.mlstatic.com/D_799755-MLA47058389754_082021-I.jpg",
          "description": "",
          "quantity": 7
        }
        
    • A tabela de vendas terá o seguinte nome: sales

      • Os campos da tabela sales terão esse formato:

        { "itensSold": [{ "productId": "5f43cbf4c45ff5104986e81d", "quantity": 2 }] }
        

Shape de retorno após "insert" no banco:

  • A tabela de produtos

    • A resposta retornada após um insert (criação) no banco precisa ter o seguinte shape:

      { "_id": ObjectId("5f43cbf4c45ff5104986e81d"), "name": "Produto tal", "quantity": 10 }
      
  • A tabela de vendas

    • A resposta retornada após um insert (criação) no banco precisa ter o seguinte shape:

      {
      "_id": ObjectId("5f43cc53c45ff5104986e81e"),
      "itensSold": [{ "productId": "5f43cbf4c45ff5104986e81d", "quantity": 2 }]
      }
      

Requisitos funcionais

Sumário

Para entender melhor a lógica por trás do código de desenvolvimento da API, é interessante olhar a Requisitos funcionais do projeto. Acesse aqui o readme desses Requisitos Funcionais.