Skip to content

HenriqueSerres/Trybesmith-Proj-26

Repository files navigation

Boas vindas ao repositório do projeto Trybesmith!

Para realizar o projeto, atente-se a cada passo descrito a seguir, e se tiver qualquer dúvida, nos envie por Slack! #vqv 🚀

Aqui você vai encontrar os detalhes de como estruturar o desenvolvimento do seu projeto a partir deste repositório, utilizando uma branch específica e um Pull Request para colocar seus códigos.

Termos e acordos

Ao iniciar este projeto, você concorda com as diretrizes do Código de Conduta e do Manual da Pessoa Estudante da Trybe.

Entregáveis

🤷🏽‍♀️ Como entregar

Para entregar o seu projeto você deverá criar um Pull Request neste repositório.

Lembre-se que você pode consultar nosso conteúdo sobre Git & GitHub e nosso Blog - Git & GitHub sempre que precisar!

👨‍💻 O que deverá ser desenvolvido

Para este projeto, você vai criar uma loja de itens medievais, no formato de uma API, utilizando Typescript.

Você irá desenvolver todas as camadas da aplicação (Models, Service e Controllers) em seu código e, por meio dessa aplicação, será possível realizar as operações básicas que se pode fazer em um determinado banco de dados: Criação, Leitura, Atualização e Exclusão (ou CRUD, para as pessoas mais íntimas 😜 - Create, Read, Update e Delete).

Você irá criar alguns endpoints que irão ler e escrever em um banco de dados, utilizando o MySQL.


O código para cadastro de pessoas usuárias deve ser criado por você utilizando os conhecimentos adquiridos nesse bloco.

⚠️ Dicas Importantes ⚠️:

  • Não haverá front-end neste projeto, portanto não se preocupe com a visualização, apenas com as funcionalidades e organização do código;

  • Sua API deve ser desenvolvida dentro da pasta ./src.

🗓 Data de Entrega
  • Este projeto é individual
  • São X dias de projeto
  • Data para entrega final do projeto: 24/06/2022 14:10

Orientações

🐳 Rodando no Docker vs Localmente

Com Docker

Rode os serviços node e db com o comando docker-compose up -d.

  • Lembre-se de parar o mysql se estiver usando localmente na porta padrão (3306), ou adapte, caso queria fazer uso da aplicação em containers
  • Esses serviços irão inicializar um container chamado trybesmith e outro chamado trybesmith_db.
  • A partir daqui você pode rodar o container trybesmith via CLI ou abri-lo no VS Code.

Use o comando docker exec -it trybesmith bash.

  • Ele te dará acesso ao terminal interativo do container criado pelo compose, que está rodando em segundo plano.

Instale as dependências [Caso existam] com npm install

⚠ Atenção ⚠ Caso opte por utilizar o Docker, TODOS os comandos disponíveis no package.json (npm start, npm test, npm run dev, ...) devem ser executados DENTRO do container, ou seja, no terminal que aparece após a execução do comando docker exec citado acima.

⚠ Atenção ⚠ O git dentro do container não vem configurado com suas credenciais. Ou faça os commits fora do container, ou configure as suas credenciais do git dentro do container.

⚠ Atenção ⚠ Não rode o comando npm audit fix! Ele atualiza várias dependências do projeto, e essa atualização gera conflitos com o avaliador.

Dica: A extensão Remote - Containers (que estará na seção de extensões recomendadas do VS Code) é indicada para que você possa desenvolver sua aplicação no container Docker direto no VS Code, como você faz com seus arquivos locais.


Sem Docker

Instale as dependências [Caso existam] com npm install

⚠ Atenção ⚠ Não rode o comando npm audit fix! Ele atualiza várias dependências do projeto, e essa atualização gera conflitos com o avaliador.

Dica: Para rodar o projeto desta forma, obrigatoriamente você deve ter o node instalado em seu computador. ✨ Dica: O avaliador espera que a versão do node utilizada seja a 16.

‼️ Antes de começar a desenvolver
  1. Clone o repositório
  • git clone https://github.com/tryber/sd-017-project-trybesmith.git.
  • Entre na pasta do repositório que você acabou de clonar:
    • cd sd-017-project-trybesmith
  1. Instale as dependências [Caso existam]
  • npm install
  1. Crie uma branch a partir da branch main
  • Verifique se você está na branch main
    • Exemplo: git branch
  • Se você não estiver, mude para a branch main
    • Exemplo: git checkout main
  • Agora crie uma branch à qual você vai submeter os commits do seu projeto
    • Você deve criar uma branch no seguinte formato: nome-de-usuario-nome-do-projeto
    • Exemplo: git checkout -b joaozinho-sd-017-project-trybesmith
  1. Adicione as mudanças ao stage do Git e faça um commit
  • Verifique que as mudanças ainda não estão no stage
    • Exemplo: git status (deve aparecer listada a pasta joaozinho em vermelho)
  • Adicione o novo arquivo ao stage do Git
    • Exemplo:
      • git add . (adicionando todas as mudanças - que estavam em vermelho - ao stage do Git)
      • git status (deve aparecer listado o arquivo joaozinho/README.md em verde)
  • Faça o commit inicial
    • Exemplo:
      • git commit -m 'iniciando o projeto x' (fazendo o primeiro commit)
      • git status (deve aparecer uma mensagem tipo nothing to commit )
  1. Adicione a sua branch com o novo commit ao repositório remoto
  • Usando o exemplo anterior: git push -u origin joaozinho-sd-017-project-trybesmith
  1. Crie um novo Pull Request (PR)
  • Vá até a página de Pull Requests do repositório no GitHub
  • Clique no botão verde "New pull request"
  • Clique na caixa de seleção "Compare" e escolha a sua branch com atenção
  • Clique no botão verde "Create pull request"
  • Adicione uma descrição para o Pull Request e clique no botão verde "Create pull request"
  • Não se preocupe em preencher mais nada por enquanto!
  • Volte até a página de Pull Requests do repositório e confira que o seu Pull Request está criado
⌨️ Durante o desenvolvimento
  • Faça commits das alterações que você fizer no código regularmente

  • Lembre-se de sempre após um (ou alguns) commits atualizar o repositório remoto

  • Os comandos que você utilizará com mais frequência são:

    1. git status (para verificar o que está em vermelho - fora do stage - e o que está em verde - no stage)
    2. git add (para adicionar arquivos ao stage do Git)
    3. git commit (para criar um commit com os arquivos que estão no stage do Git)
    4. git push -u nome-da-branch (para enviar o commit para o repositório remoto na primeira vez que fizer o push de uma nova branch)
    5. git push (para enviar o commit para o repositório remoto após o passo anterior)
🤝 Depois de terminar o desenvolvimento (opcional)

Para sinalizar que o seu projeto está pronto para o "Code Review" dos seus colegas, faça o seguinte:

  • Vá até a página DO SEU Pull Request, adicione a label de "code-review" e marque seus colegas:

    • No menu à direita, clique no link "Labels" e escolha a label code-review;

    • No menu à direita, clique no link "Assignees" e escolha o seu usuário;

    • No menu à direita, clique no link "Reviewers" e digite students, selecione o time tryber/students-sd-017.

Caso tenha alguma dúvida, aqui tem um video explicativo.

🕵🏿 Revisando um pull request

Use o conteúdo sobre Code Review para te ajudar a revisar os Pull Requests.

🍪 Informações sobre a API

⚠️ Leia as informações abaixo atentamente e siga à risca o que for pedido. ⚠️

👀 Observações importantes:

  • O não cumprimento de um requisito, total ou parcialmente, impactará em sua avaliação;

  • O projeto deve rodar na porta 3000;

  • O arquivo index.ts existe para rodar corretamente os testes. Todo o projeto (incluindo as rotas) deverá ser feito dentro do arquivo app.ts;

  • Você pode utilizar as funções json.parse e json.stringify nos models;


Todos os seus endpoints devem estar no padrão REST

  • Use os verbos HTTP adequados para cada operação;

  • Agrupe e padronize suas URL em cada recurso;

  • Garanta que seus endpoints sempre retornem uma resposta, havendo sucesso nas operações ou não;

  • Retorne os códigos de status corretos (recurso criado, erro de validação, etc).


Há dois arquivos no diretório ./src/: index.ts e app.ts, ambos não devem ser renomeados ou apagados.

Você poderá fazer modificações em ambos os arquivos, porém no arquivo app.ts o seguinte trecho de código não deve ser removido:

import express from 'express';

const app = express();

app.use(express.json());

export default app;

Isso está configurado para o avaliador funcionar corretamente.

🏦 Conexão com o Banco

A conexão do banco local deverá conter os seguintes parâmetros:

import dotenv from 'dotenv';
import mysql from 'mysql2/promise';

dotenv.config();

const connection = mysql.createPool({
  host: process.env.MYSQL_HOST,
  user: process.env.MYSQL_USER,
  password: process.env.MYSQL_PASSWORD,
}); // sua conexão NÃO deve ter o database, este deve ser especificado em cada query

export default connection;

⚠️ É essencial configurar essas 3 variáveis de ambiente para testar o projeto localmente: ⚠️

  host: process.env.MYSQL_HOST
  user: process.env.MYSQL_USER
  password: process.env.MYSQL_PASSWORD

⚠️ Variáveis de ambiente além das especificadas acima não são suportadas, pois não são esperadas pelo avaliador do projeto. ⚠️

⚠️ É essencial que seu arquivo tenha o nome connection.ts e esteja no diretório src/models ⚠️

🪑 Tabelas

O banco terá três tabelas: pessoas usuárias, produtos e pedidos.

DROP SCHEMA IF EXISTS Trybesmith;
CREATE SCHEMA Trybesmith;

CREATE TABLE Trybesmith.Users (
  id INTEGER AUTO_INCREMENT PRIMARY KEY NOT NULL,
  username TEXT NOT NULL,
  classe TEXT NOT NULL,
  level INTEGER NOT NULL,
  password TEXT NOT NULL
);

CREATE TABLE Trybesmith.Orders (
  id INTEGER AUTO_INCREMENT PRIMARY KEY NOT NULL,
  userId INTEGER,
  FOREIGN KEY (userId) REFERENCES Trybesmith.Users (id)
);

CREATE TABLE Trybesmith.Products (
  id INTEGER AUTO_INCREMENT PRIMARY KEY NOT NULL,
  name TEXT NOT NULL,
  amount TEXT NOT NULL,
  orderId INTEGER,
  FOREIGN KEY (orderId) REFERENCES Trybesmith.Orders (id)
);

O arquivo Trybesmith.sql contém as queries que criam e populam o banco como o teste faz, e os testes restauram o banco de dados após sua execução.

Para que o avaliador funcione corretamente, tanto local quanto remoto, sua connection.ts não deve conter o database e suas queries devem conter o banco de dados explicitamente como o exemplo abaixo:

SELECT * FROM Trybesmith.Products;

Suas queries

🎛 Linter

Usaremos o ESLint para fazer a análise estática do seu código.

Este projeto já vem com as dependências relacionadas ao linter configuradas nos arquivos package.json.

Para poder rodar o ESLint em um projeto basta executar o comando npm install dentro do projeto e depois npm run lint. Se a análise do ESLint encontrar problemas no seu 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.

Você pode também instalar o plugin do ESLint no VSCode. Para isso, basta fazer o download do plugin ESLint e instalá-lo.

⚠️ Pull requests com issues de linter não serão avaliadas. Atente-se para resolvê-las antes de finalizar o desenvolvimento! ⚠️

🛠 Testes

Todos os requisitos do projeto serão testados automaticamente. Cada endpoint possui vários requisitos e os testes para cada requisito de um endpoint estão no arquivo de teste.

Para executar os testes localmente, digite no terminal o comando npm test, ou para executar apenas um teste você pode usar npm test 01.

Dica: desativando testes

Especialmente no início, quando a maioria dos testes está falhando, a saída após executar os testes é bastante poluída. Você pode desabilitar temporariamente um teste utilizando a função skip junto à função it. Como o nome indica, essa função "pula" um teste:

  it.skip('Será validado que o campo "username" é obrigatório', async () => {
    const result = await request(app).post("/users").send({
      level: 2,
      classe: "classe",
      password: "senha",
    });
    expect(result.statusCode).toEqual(400);
    expect(result.body.message).toEqual("Username is required");
  });

Uma estratégia é pular todos os testes no início e ir implementando um teste de cada vez, removendo dele a função skip.

Testando um arquivo específico

⚠️ Lembre-se de não entregar o projeto com nenhum teste ignorado. Testes ignorados serão tratados como testes falhando. ⚠️

⚠️ Não apague, em hipótese alguma, qualquer teste ou arquivo deste repositório. ⚠️

🗣 Nos dê feedbacks sobre o projeto!

Ao finalizar e submeter o projeto, não se esqueça de avaliar sua experiência preenchendo o formulário. Leva menos de 3 minutos!

FORMULÁRIO DE AVALIAÇÃO DE PROJETO

⚠️ O avaliador automático não necessariamente avalia seu projeto na ordem em que os requisitos aparecem no readme. Isso acontece para deixar o processo de avaliação mais rápido. Então, não se assuste se isso acontecer, ok?

🗂 Compartilhe seu portfólio!

Você sabia que o LinkedIn é a principal rede social profissional e compartilhar o seu aprendizado lá é muito importante para quem deseja construir uma carreira de sucesso? Compartilhe esse projeto no seu LinkedIn, marque o perfil da Trybe (@trybe) e mostre para a sua rede toda a sua evolução.

Requisitos

1 - Crie um endpoint para a listagem de produtos

  • O endpoint deve ser acessível através do caminho (/products);
Além disso, as seguintes verificações serão feitas:

👉 Para caso os dados sejam enviados corretamente

  • [Será validado que é possível listar todos os produtos com sucesso]
    • O resultado retornado para listar produtos com sucesso deverá ser conforme exibido abaixo, com um status http 200:
    [
      {
        "id": 1,
        "name": "Poção de cura",
        "amount": "20 gold",
        "orderId": null
      },
      {
        "id": 2,
        "name": "Escudo do Herói",
        "amount": "100 diamond",
        "orderId": 1
      }
    ]

2 - Crie um endpoint para o cadastro de produtos

  • O endpoint deve ser acessível através do caminho (/products);

  • Os produtos enviados devem ser salvos na tabela Products do banco de dados;

  • O endpoint deve receber a seguinte estrutura:

  {
    "name": "Espada longa",
    "amount": "30 peças de ouro"
  }
Além disso, as seguintes verificações serão feitas:

👉 Para name

  • [Será validado que o campo "name" é obrigatório]

    • Se o campo "name" não for informado, o resultado retornado deverá ser um status http 400 e
      { "message": "\"name\" is required" }
  • [Será validado que o campo "name" tem o tipo string]

    • Se o campo "name" não for do tipo string, o resultado retornado deverá ser um status http 422 e
      { "message": "\"name\" must be a string" }
  • [Será validado que o campo "name" é uma string com mais de 2 caracteres]

    • Se o campo "name" não for uma string com mais de 2 caracteres, o resultado retornado deverá ser um status http 422 e
      { "message": "\"name\" length must be at least 3 characters long" }

👉 Para amount

  • [Será validado que o campo "amount" é obrigatório]

    • Se o campo "amount" não for informado, o resultado retornado deverá ser um status http 400 e
      { "message": "\"amount\" is required" }
  • [Será validado que o campo "amount" tem o tipo string]

    • Se o campo "amount" não for do tipo string, o resultado retornado deverá ser um status http 422 e
      { "message": "\"amount\" must be a string" }
  • [Será validado que o campo "amount" é uma string com mais de 2 caracteres]

    • Se o campo "amount" não for uma string com mais de 2 caracteres, o resultado retornado deverá ser um status http 422 e
      { "message": "\"amount\" length must be at least 3 characters long" }

👉 Para caso os dados sejam enviados corretamente

  • [Será validado que é possível cadastrar um produto com sucesso]
    • O resultado retornado para cadastrar o produto com sucesso deverá ser conforme exibido abaixo, com um status http 201:
      {
        "id": 1,
        "name": "Poção de cura",
        "amount": "20 gold",
      }

3 - Crie um endpoint para o cadastro de pessoas usuárias

  • O endpoint deve ser acessível através do caminho (/users);

  • As informações de pessoas usuárias cadastradas devem ser salvas na tabela Users do banco de dados;

  • O endpoint deve receber a seguinte estrutura:

{
  "username": "string",
  "classe": "string",
  "level": 1,
  "password": "string"
}
Além disso, as seguintes verificações serão feitas:

👉 Para username

  • [Será validado que o campo "username" é obrigatório]

    • Se a requisição não tiver o campo "username", o resultado retornado deverá ser um status http 400 e
      { "message": "\"username\" is required" }
  • [Será validado que o campo "username" tem o tipo string]

    • Se o campo "username" não for do tipo string, o resultado retornado deverá ser um status http 422 e
      { "message": "\"username\" must be a string" }
  • [Será validado que o campo "username" é uma string com mais de 2 caracteres]

    • Se o campo "username" não for do tipo string com mais de 2 caracteres, o resultado retornado deverá ser um status http 422 e
      { "message": "\"username\" length must be at least 3 characters long" }

👉 Para classe

  • [Será validado que o campo "classe" é obrigatório]

    • Se a requisição não tiver o campo "classe", o resultado retornado deverá ser um status http 400 e
      { "message": "\"classe\" is required" }
  • [Será validado que o campo "classe" tem o tipo string]

    • Se o campo "classe" não for do tipo string, o resultado retornado deverá ser um status http 422 e
      { "message": "\"classe\" must be a string" }
  • [Será validado que o campo "classe" é uma string com mais de 2 caracteres]

    • Se o campo "classe" não for do tipo string com mais de 2 caracteres, o resultado retornado deverá ser um status http 422 e
      { "message": "\"classe\" length must be at least 3 characters long" }

👉 Para level

  • [Será validado que o campo "level" é obrigatório]

    • Se a pessoa usuária não tiver o campo "level", o resultado retornado deverá ser um status http 400 e
      { "message": "\"level\" is required" }
  • [Será validado que o campo "level" tem o tipo number]

    • Se o campo "level" não for do tipo number, o resultado retornado deverá ser um status http 422 e
      { "message": "\"level\" must be a number" }
  • [Será validado que o campo "level" deve ser um número maior que 0]

    • Se o campo "level" não for do tipo number maior que 0, o resultado retornado deverá ser um status http 422 e
      { "message": "\"level\" must be greater than or equal to 1" }

👉 Para password

  • [Será validado que o campo "password" é obrigatório]

    • Se a requisição não tiver o campo "password", o resultado retornado deverá ser um status http 400 e
      { "message": "\"password\" is required" }
  • [Será validado que o campo "password" tem o tipo string]

    • Se o campo "password" não for do tipo string, o resultado retornado deverá ser um status http 422 e
      { "message": "\"password\" must be a string" }
  • [Será validado que o campo "password" é uma string com 8 ou mais caracteres]

    • Se o campo "password" não for do tipo string com mais de 8 caracteres, o resultado retornado deverá ser um status http 422 e
      { "message": "\"password\" length must be at least 8 characters long" }

👉 Para caso os dados sejam enviados corretamente

  • [Será validado que é possível cadastrar a pessoa usuária com sucesso]
    • Se a pessoa usuária for cadastrada com sucesso, o resultado deverá ser conforme o exibido abaixo, com um status http 201 e retornando um token:
    {
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
    }

4 - Crie um endpoint para listar todos os pedidos

  • O endpoint deve ser acessível através do caminho (/orders).
  • Essa rota deve retornar todos os pedidos e os ids dos produtos associados a estes.

Dica: São os produtos que contém os ids dos pedidos.

Dica: Você pode fazer a agregação direto na linguagem de programação, pegando pedidos e produtos separadamente e os juntando no TypeScript, ao invés de tentar criar uma complexa query em SQL.

Além disso, as seguintes verificações serão feitas:

👉 Para orders

  • [Será validado que é possível listar todos os pedidos com sucesso]
    • Quando houver mais de um pedido, o resultado retornado para listar pedidos com sucesso deverá ser conforme exibido abaixo, com um status http 200:
      [
        {
          "id": 1,
          "userId": 2,
          "productsIds": [1, 2]
        },
        {
          "id": 2,
          "userId": 2,
          "productsIds": [3, 4]
        }
      ]

Requisito Bônus

5 - Crie um endpoint para o login de pessoas usuárias

  • O endpoint deve ser acessível através do caminho (/login).

  • A rota deve receber os campos username e password, e esses campos devem ser validados no banco de dados.

  • Um token JWT deve ser gerado e retornado caso haja sucesso no login. No seu payload deve estar presente o id e username.

  • O endpoint deve receber a seguinte estrutura:

  {
    "username": "string",
    "password": "string"
  }

⚠️ Na configuração do JWT não use variáveis de ambientes para não ter conflito com o avaliador.

Além disso, as seguintes verificações serão feitas:

👉 Para caso haja problemas no login

  • [Será validado que o campo "username" é enviado]

    • Se o login não tiver o campo "username", o resultado retornado deverá ser um status http 400 e
      { "message": "\"username\" is required" }
  • [Será validado que o campo "password" é enviado]

    • Se o login não tiver o campo "password", o resultado retornado deverá ser um status http 400
      { "message": "\"password\" is required" }
  • [Será validado que não é possível fazer login com um username inválido]

    • Se o login tiver o username inválido, o resultado retornado deverá ser um status http 401 e
      { "message": "Username or password invalid" }
  • [Será validado que não é possível fazer login com uma senha inválida]

    • Se o login tiver a senha inválida, o resultado retornado deverá ser um status http 401 e
      { "message": "Username or password invalid" }

👉 Para caso os dados sejam enviados corretamente

  • [Será validado que é possível fazer login com sucesso]
    • Se o login foi feito com sucesso, o resultado deverá ser um status http 200 e deverá retornar um token:
    {
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
    }

6 - Crie um endpoint para o cadastro de um pedido

  • O endpoint deve ser acessível através do caminho (/orders);

  • Um pedido só pode ser criado caso a pessoa usuária esteja logada e o token JWT validado;

  • Os pedidos enviados devem ser salvos na tabela Orders do banco de dados, salvando id da pessoa usuária da aplicação que fez esse pedido.

  • A tabela Products também deve ser alterada, atualizando todos os produtos com os id incluídos na chave productsIds da requisição, e adicionando nesses produtos o orderId do pedido recém criado;

  • O endpoint deve receber a seguinte estrutura:

  {
    "productsIds": [1, 2]
  }

⚠️ Ao cadastrar um pedido, lembre-se de atualizar os respectivos produtos no banco de dados, incluindo neles o número do pedido criado.

Além disso, as seguintes verificações serão feitas:

👉 Para token

  • [Será validado que não é possível cadastrar pedidos sem token]

    • Se o token não for informado, o resultado retornado deverá ser um status http 401 e
      { "message": "Token not found" }
  • [Será validado que não é possível cadastrar um pedido com token inválido]

    • Se o token informado não for válido, o resultado retornado deverá ser um status http 401 e
      { "message": "Invalid token" }

👉 Para products

  • [Será validado que o campo "productsIds" é obrigatório]

    • Se o corpo da requisição não possuir o campo "productsIds", o resultado retornado deverá ser um status http 400 e
      { "message": "\"productsIds\" is required" }
  • [Será validado que não é possível criar um pedido com o campo "productsIds" não sendo um array]

    • Se o valor do campo "productsIds" não for um array, o resultado retornado deverá ser um status http 422 e
      { "message": "\"productsIds\" must be an array" }
  • [Será validado que não é possível cadastrar um pedido se o campo "productsIds" for um array vazio]

    • Se o campo "productsIds" possuir um array vazio, o resultado retornado deverá ser um status http 422 e
      { "message": "\"productsIds\" must include only numbers" }

👉 Para caso os dados sejam enviados corretamente

  • [Será validado que é possível criar um pedido com sucesso com 1 item]

    • O resultado retornado para cadastrar um pedido com sucesso deverá ser conforme exibido abaixo, com um status http 201:
      {
        "userId": 1,
        "products": [1],
      }
  • [Será validado que é possível criar um pedido com sucesso com vários itens]

    • O resultado retornado para cadastrar um pedido com sucesso deverá ser conforme exibido abaixo, com um status http 201:
      {
        "userId": 1,
        "products": [1, 2]
      }

About

Backend - - REST - Rotas - CRUD - MySQL - Typescript

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published