Skip to content

LucianoSabino/api-typescript

Repository files navigation

link da plylist

Inicializando o Node e o Git

    npm init -y

    git init
  • Comandos para o git:

    -   `git add .` : seleciona todos os arquivos
    -   `git commit -m "colocar oq esta commitando"` : Vai fazer o commit
    

Instalando dependencia

    yarn add express

    yarn add -D tsc typescript ts-node

    yarn add -D @types/express @types/node

    yarn add -D nodemon
  • No arquivo package.json em scripts e coloque:

      "dev": "nodemon --watch \"src/\" --exec \"node_modules/.bin/ts-node src/index.ts\" -e ts"
    
  • Depois coloque:

      "compilerOptions": {
          "module": "ESNext",
          "moduleResolution": "node",
          "target": "ESNext",
          "esModuleInterop": true,
          "skipLibCheck": true,
          "strict": true
      },
      "include": [
          "src"
      ]
    
  • Depois para inicializar o typescript:

      npx tsc --init
    
  • Criando variavel de ambiente. Execute esse comando

    yarn add -D dotenv
    

depois crie um arquivo na raiz do projeto .env

  • inicializando eslint:

      npx eslint --init
    
  • Depois crie um arquivo com o nome:

        .gitignore
    

e coloque

        /node_modules
        .env_

para o git iginorar esses arquivos.

  • Blibioteca para mensagem de erro:

      yarn add http-status-codes
    

Biblioteca de validação YUP

Yup é um construtor de esquema para análise e validação de valor em tempo de execução.
    yarn add yup
Explicando um pouco do codigo (src/server/controller/cidade/create)

imagem de arquitetura do projeto

Interfaces

  • ICidade: Define a estrutura de um objeto que representa uma cidade. Possui as propriedades nome (nome da cidade) e estado (estado da cidade).

  • IFilter: Define a estrutura de um objeto que representa um filtro. Possui a propriedade filter (critério de filtragem).

  • Validação

  • createValidation: Cria um esquema de validação para garantir que os dados recebidos nas requisições estejam no formato correto. Valida tanto o corpo da requisição (body) quanto os parâmetros da query (query).

  • Corpo da requisição: Verifica se o nome da cidade possui pelo menos 3 caracteres e se o estado possui exatamente 2 caracteres. Parâmetros da query: Verifica se o parâmetro filter possui pelo menos 3 caracteres.

(src/server/shared/middlewares/Validation)

imagem de arquitetura do projeto

Define um middleware de validação reutilizável para aplicações.

Definições de Tipos:

  • TProperty: Define os possíveis locais onde a validação pode ser aplicada em uma requisição HTTP: corpo, cabeçalho, parâmetros ou query string.
  • TGetSchema: Representa uma função que recebe um esquema de validação e o retorna. É usada para criar esquemas de forma dinâmica.
  • TAllSchemas: Representa um objeto que mapeia cada TProperty a um esquema de validação correspondente.
  • TGetAllSchema: Representa uma função que recebe uma função TGetSchema e retorna um objeto parcial do tipo TAllSchemas. É responsável por gerar os esquemas de validação para todas as partes da requisição.
  • TValidation: Representa uma função que recebe uma função TGetAllSchema e retorna um middleware (RequestHandler). É a assinatura da nossa função de validação principal.

Função validation:

  • Entrada: Uma função getAllSchemas para gerar esquemas de validação.
  • Saída: Uma função middleware que valida requisições HTTP.

Funcionamento:

  • Geração de Esquemas: Chama getAllSchemas para obter os esquemas de validação para diferentes partes da requisição.
  • Inicialização do Objeto de Erros: Cria um objeto vazio errorsResult para armazenar os erros de validação.

Itera e Valida: Valida a parte correspondente da requisição usando schema.validateSync. Captura erros de validação e extrai as mensagens de erro. Adiciona as mensagens de erro ao errorsResult. Tratamento de Resultados: Se não houver erros, chama next() para passar para o próximo middleware. Se houver erros, retorna uma resposta com status 400 (Bad Request) e os detalhes dos erros.

Teste para Api

Jest é um poderoso framework de testes JavaScript de código aberto Qualque duvida esta no [video](https://youtu.be/G6Lo8wk4Y5w?si=0Lm1hyt72u474iMg)

Instale essas biblioteca:

    yarn add jest ts-jest @types/jest
    yarn add -D supertest @types/supertest

Depois inicie:

    yarn jest --init

No arquivo jest.config.ts coloque:

    coverageReporters: ["json"],
    setupFilesAfterEnv: ["./tests/jest.setup.ts"],
    testMatch: ["<rootDir>/tests/**/*.test.ts"],
    transform: {
        "^.+\\.(ts|tsx)$": "ts-jest",
    },

Depois crie uma psata tests dentro dela um arquivo jest.setup.ts vai conter:

imagem de arquitetura do projeto

No arquivo tsconfig.json depois de compilerOptions coloque:

    "exclude": ["./jest.config.ts", "./node_modules", "./tests", "./build"]

Colocar no .gitignore:

    /coverage
  • Exemplo de um teste para criar ciadade

imagem de arquitetura do projeto

Na hora de executar os teste rodar o comando:

    yarn test

Assim foi feito para todas as rotas.

Deploy da API Express no Render

Banco de dados

OBS: SE atente aos caminhos dos arquivos e comandos.
Utilizando Knex.js
Knex.js é uma biblioteca para Node.js que facilita a interação com bancos de dados relacionais. Em outras palavras, ele é um query builder, ou seja, uma ferramenta que constrói consultas SQL de forma mais intuitiva e organizada, eliminando a necessidade de escrever as consultas manualmente.
  • Instalando as blibioteca:

      yarn add knex
    
Utilizando o banco de dados Sqlite
  • Instalando as blibioteca:

      yarn add sqlite3
    
No arquivo _database/Knex/knexfile.ts_ esta as configuração de conexão do banco de dados.

imagem de arquitetura do projeto

Tendo tres tipos de conexão

  • test so para quando for rodar os testes assim os dados seram apagados depois
  • Produção quando estiver no servidor
  • Desenvolvimento
No arquivo _database/Knex/index.ts_ esta passando as configuração de conexão e alternando entre elas

imagem de arquitetura do projeto

Fazendo as migrações
  • Execute esse comando para criar um arquivo de migração:

      yarn knex --knexfile ./src/server/database/Knex/knexfile.ts migrate:make test
    

Esse test, pode ser qualquer nome.

Deve aparecer um arquivo dentro da pastra de database/migrations: Caso não tenha criar uma

Depois so fazer as configurações de tabelas, Exemplo:

imagem de arquitetura do projeto

Depois no arquivo package.json coloque:

    "knex:rollback-all": "knex --knexfile ./src/server/database/Knex/knexfile.ts migrate:rollback --all",
    "knex:rollback": "knex --knexfile ./src/server/database/Knex/knexfile.ts migrate:rollback",
    "knex:migrate": "knex --knexfile ./src/server/database/Knex/knexfile.ts migrate:latest",
    "knex:seed": "knex --knexfile ./src/server/database/Knex/knexfile.ts seed:run",

Depois so rodar o comando e sera criado a tabela com as informações:

    yarn knex:migrate
  • Foi criado uma pasta models dentro de server e colocado só a interfeice: caminho correto server/models/Cidade.ts

      export interface Icidade {
          id: number;
          nome: string;
      }
    

Depois exprotado no index: caminho server/models/index.ts

    export * from "./Cidade";
  • Depois foi criado uma uma pasta dentro de server/Knex/@types/knex.d.ts e colocado:

      import { Icidade } from "../../models";
    
      declare module "knex/types/tables" {
          interface Tables {
              cidade: Icidade;
          }
      }
    
Inserindo dados no banco
  • Foi criado uma pasta server/providers/cidade/Create.ts onde vai ficar responsavel por toda parte de inserir dados no banco de dados. Assim quando quiser trocar de ORM é so modificar esse aquivo.

O codigo ficou assim

imagem de arquitetura do projeto

no arquivo index foi feito a exportação server/providers/cidade/index.ts

    import * as create from "./Create";
    export const CidadeProvider = {
        ...create,
    }

Depois foi feito a modificação no controller/cidade/Create.ts ficando assim para salva as cidades no banco.

imagem de arquitetura do projeto

Foi feita uma alteração na pasta testes: *test/cidade/jest.setup.ts
- Como ao rodar test esta criando um banco de dados em menoria, então é necessario rodar uma migração especifica para isso.
        beforeAll(async () => {
            await Knex.migrate.latest();
        });

        afterAll(async () => {
            await Knex.destroy();
        });
Como ficou o resto providers cidade : *dataabase/providers/cidade/ "Count, DeleteByid, GetAll, GetById, UpdateById".ts*

Obs: Tambem tem alteração na respequetivas pastas na parte de controller/cidade para o funcionamento.

  • Count

imagem de arquitetura do projeto

  • DeleteById

imagem de arquitetura do projeto

  • GetAll

imagem de arquitetura do projeto

  • GetById

imagem de arquitetura do projeto

  • UpdateById

imagem de arquitetura do projeto

Foi alterado index de *src/index.ts
  • Assim quando a aplicação estiver em produção criar uma migratio, ou seja uma tabela no sevidor.

imagem de arquitetura do projeto

  • Foi adiciomado no arquivo .env

      IS_LOCALHOST=true
    
Inserindo cidade altomatica *server/database/seeds/0000_insert_cidade.ts*
  • O nome 0000_insert_cidade.ts foi colocado manualmente, nele conterar o codigo para inserir todos as cidades da Bahia.

  • É feita uma validação com count para quer, se ouver alguna cidade no banco não se cadastrada nem uma desse arry.

imagem de arquitetura do projeto

  • Tambem feito alteração em src/index.ts, fazendo com que ele insira as cidades altomaticamente

      if (process.env.IS_LOCALHOST !== "true") {
          Knex.migrate
              .latest()
              .then(() => {
                  Knex.seed
                      .run()
                      .then(() => startServer())
                      .catch(console.log);
              })
              .catch(console.log);
      } else {
          startServer();
      }
    

Parte de pessoa

  • Foi criado a migration de pessoa 0001_creat_pessoa.ts e a unica diferença foi a parte da ligação com a tabela de cidade, ficando assim:

      table.bigInteger("cidadeId").index().notNullable().references("id").inTable(ETableNames.CIDADE).onUpdate("CASCADE").onDelete("RESTRICT");
    

imagem de arquitetura do projeto

  • Alem de acrecentar os outros campos como na interface database/models/Pessoa.ts:

      export interface IPessoa {
          id: number;
          email: string;
          cidadeId: number;
          nomeCompleto: string;
      }
    

Depois é só rodar o comando

    yarn knex:migrate
  • Alem de ter adicionado no database/seeds:

      PESSOA = "pessoa",
    
O Resto foi bem paracido com que foi feito com cidade, provaid e controller

Controler de usuario

  • Foi feito o models

      export interface Iusuario {
          id: number;
          email: string;
          senha: string;
          nome: string;
      }
    
  • Depois a migrations

imagem de arquitetura do projeto

  • Depois a exportação no database/Knex/@types/knex.d.ts

    import { Icidade, Ipessoa, Iusuario } from "../../models";
    
    declare module "knex/types/tables" {
        interface Tables {
            cidade: Icidade;
            pessoa: Ipessoa;
            usuario: Iusuario;
        }
    }
    
  • Feito os providers OBS: Sem a altenticação do token

Create imagem de arquitetura do projeto

GetByEmail imagem de arquitetura do projeto

  • Depois o controller, segue as mesma coisa de cidade e pessao

No SignIn é feita a parte de login, comparação de senha e email imagem de arquitetura do projeto

No SignUp é feita a parte de criar usuario imagem de arquitetura do projeto

  • Depois é so fazer as rotas
_Cripitografia de Senha_
É diferente do TOKEN
  • Adicionar a biblioteca

      yarn add bcryptjs
      yarn add @types/bcryptjs -D
    
  • Como é um arquivo que vai ser utilizado em toda aplicação ele esta em database/shared/services/PasswordCrypto.ts

  • Basicamente para criptografa a senha é so isso:

imagem de arquitetura do projeto

  • Agora no database/providers/usuario/Create.ts é so adicionar isso :

      const hashedPassword = await PasswordCrypto.hashPassword(usuario.senha);
      usuario.senha = hashedPassword;
    

Isso que dizer que antes de salvar o usuario, criptogarfa a senha e depois salva no banco de dados.

  • Foi modificado tbm no server/controller/usuario/SignIn.ts, para verificar a senha pela criptografia.

imagem de arquitetura do projeto

_Fazendo a parte de validação com TOKEN e JWT_
  • Adicionar a biblioteca

      yarn add jsonwebtoken
      yarn add @types/jsonwebtoken -D
    
  • Como é um arquivo que vai ser utilizado em toda aplicação ele esta em database/shared/middlewares/ensureAuthenticated.ts, nesse arquivo vai ser resposavel por fazer a verificação do Token

imagem de arquitetura do projeto

  • Agora no arquivo database/shared/services/JWTService.ts, cria o Token

imagem de arquitetura do projeto

  • Agora no arquivo de database/controller/usuario/SignIn.ts, so foi alterado a parte de else que chama a função de criar um token, fica assim:

      else {
          // Gerando o tokem
          const accessToken = JWTService.sign({ uid: result.id });
    
          if (accessToken === "JWT_SECRET_NOT_FOUND") {
              res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
                  errors: {
                      default: "Erro ao gerar o Token de acesso!",
                  },
              });
              return;
          }
    
          res.status(StatusCodes.OK).json({ accessToken });
      }
    

Configuração para o banco de dados em deploy/Produção

  • Vai ser utilizado o postgresql

  • adicionando a biblioteca

      yarn add pg
      yarn add @types/pg -D
    
  • Foi alterado no arquivo database/Knex/knexfile.ts, foi modificado a parte de produção ficando assim:

imagem de arquitetura do projeto

  • Alem do arquivo index database/Knex/index.ts

imagem de arquitetura do projeto

Esta cendo utelizado um banco em nuvem
  • Duvida como alterar o projeto para o banco de dados Link do video base
  • Link do site para criar o banco de dados na nuvem gratuito tembo
  • Duvida configuração do banco de dados na nuvem video
Outro site
  • Link do site neon
  • Video qualquer duvida video

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published