Skip to content

emmanuelmarcosdeoliveira/first-node-api

Repository files navigation

šŸ“š First Node API

Node.js TypeScript Fastify PostgreSQL Drizzle ORM Vitest Docker JWT

šŸ“‹ ƍndice

šŸ“– Sobre o Projeto

Esta é uma API RESTful desenvolvida em Node.js com TypeScript que gerencia um sistema de cursos online. A aplicação permite autenticação de usuÔrios, criação e gerenciamento de cursos, e controle de acesso baseado em roles (estudante/gerente).

Principais Funcionalidades

  • āœ… Sistema de autenticação JWT
  • āœ… Controle de acesso baseado em roles
  • āœ… CRUD de cursos
  • āœ… Sistema de matrĆ­culas
  • āœ… Validação de dados com Zod
  • āœ… Documentação automĆ”tica da API
  • āœ… Testes automatizados
  • āœ… Containerização com Docker

šŸ”„ Fluxo Principal da Aplicação

Este diagrama mostra o fluxo mais importante da aplicação, desde a autenticação até o gerenciamento de cursos:

flowchart TD
    Start([šŸ‘¤ UsuĆ”rio Acessa API]) --> Auth{šŸ” Autenticado?}

    Auth -->|NĆ£o| Login[šŸ”‘ POST /sessions<br/>Login com Email/Senha]
    Login --> Verify[šŸ” Verificar Credenciais<br/>no PostgreSQL]
    Verify --> Hash[šŸ”’ Validar Hash<br/>com Argon2]
    Hash --> ValidCreds{āœ… Credenciais<br/>VĆ”lidas?}
    ValidCreds -->|NĆ£o| Error400[āŒ Erro 400<br/>Credenciais InvĆ”lidas]
    ValidCreds -->|Sim| GenerateJWT[šŸŽ« Gerar JWT Token<br/>com ID + Role]
    GenerateJWT --> TokenResponse[šŸ“¤ Retornar Token JWT]

    Auth -->|Sim| ProtectedRoute[šŸ›”ļø Rota Protegida<br/>Header: Authorization]
    TokenResponse --> ProtectedRoute

    ProtectedRoute --> ValidateJWT[šŸ” Validar JWT Token]
    ValidateJWT --> ValidToken{āœ… Token<br/>VĆ”lido?}
    ValidToken -->|NĆ£o| Error401[āŒ Erro 401<br/>Token InvĆ”lido]
    ValidToken -->|Sim| CheckRole[šŸ‘„ Verificar Role<br/>do UsuĆ”rio]

    CheckRole --> ManagerRole{šŸ‘Øā€šŸ’¼ Role =<br/>Manager?}
    ManagerRole -->|NĆ£o| Error403[āŒ Erro 403<br/>Sem PermissĆ£o]
    ManagerRole -->|Sim| BusinessLogic[āš™ļø Executar<br/>Lógica de Negócio]

    BusinessLogic --> CourseOps{šŸ“š Operação<br/>com Cursos}
    CourseOps -->|GET /courses| ListCourses[šŸ“‹ Listar Cursos<br/>com Paginação]
    CourseOps -->|POST /courses| CreateCourse[āž• Criar Curso<br/>Validar com Zod]
    CourseOps -->|GET /courses/:id| GetCourse[šŸ” Buscar Curso<br/>por ID]

    ListCourses --> DBQuery1[šŸ—„ļø Consulta PostgreSQL<br/>com Drizzle ORM]
    CreateCourse --> ValidateData[āœ… Validar Dados<br/>com Zod Schema]
    GetCourse --> DBQuery2[šŸ—„ļø Consulta PostgreSQL<br/>com Drizzle ORM]

    ValidateData --> ValidData{āœ… Dados<br/>VĆ”lidos?}
    ValidData -->|NĆ£o| ErrorValidation[āŒ Erro 400<br/>Dados InvĆ”lidos]
    ValidData -->|Sim| DBInsert[šŸ—„ļø Inserir no<br/>PostgreSQL]

    DBQuery1 --> Success1[āœ… Sucesso 200<br/>Lista de Cursos]
    DBQuery2 --> Success2[āœ… Sucesso 200<br/>Dados do Curso]
    DBInsert --> Success3[āœ… Sucesso 201<br/>Curso Criado]

    Error400 --> End([šŸ Fim])
    Error401 --> End
    Error403 --> End
    ErrorValidation --> End
    Success1 --> End
    Success2 --> End
    Success3 --> End

    classDef startEnd fill:#1e3a8a,stroke:#60a5fa,stroke-width:3px,color:#ffffff
    classDef process fill:#7c3aed,stroke:#a78bfa,stroke-width:3px,color:#ffffff
    classDef decision fill:#ea580c,stroke:#fb923c,stroke-width:3px,color:#ffffff
    classDef database fill:#059669,stroke:#34d399,stroke-width:3px,color:#ffffff
    classDef success fill:#047857,stroke:#10b981,stroke-width:3px,color:#ffffff
    classDef error fill:#dc2626,stroke:#f87171,stroke-width:3px,color:#ffffff

    class Start,End startEnd
    class Login,Verify,Hash,GenerateJWT,ProtectedRoute,ValidateJWT,CheckRole,BusinessLogic,ListCourses,CreateCourse,GetCourse,ValidateData,TokenResponse process
    class Auth,ValidCreds,ValidToken,ManagerRole,CourseOps,ValidData decision
    class DBQuery1,DBQuery2,DBInsert database
    class Success1,Success2,Success3 success
    class Error400,Error401,Error403,ErrorValidation error
Loading

šŸŽÆ Principais Componentes do Fluxo:

  1. šŸ” Autenticação: Sistema JWT com validação de credenciais
  2. šŸ›”ļø Autorização: Controle de acesso baseado em roles (Manager/Student)
  3. āœ… Validação: Schemas Zod para validação de dados
  4. šŸ—„ļø PersistĆŖncia: PostgreSQL com Drizzle ORM
  5. šŸ”’ SeguranƧa: Hash de senhas com Argon2

šŸš€ Tecnologias Utilizadas

  • Node.js - Runtime JavaScript
  • TypeScript - Linguagem de programação tipada
  • Fastify - Framework web rĆ”pido e eficiente
  • PostgreSQL - Banco de dados relacional
  • Drizzle ORM - ORM type-safe para TypeScript
  • Zod - Validação de schemas
  • JWT - Autenticação baseada em tokens
  • Argon2 - Hash de senhas seguro
  • Vitest - Framework de testes
  • Docker - Containerização
  • Pino - Logger estruturado

šŸ“ Estrutura do Projeto

src/
ā”œā”€ā”€ @types/              # DefiniƧƵes de tipos personalizados
ā”œā”€ā”€ database/            # Configuração e schema do banco
│   ā”œā”€ā”€ client.ts        # Cliente do banco de dados
│   ā”œā”€ā”€ schema.ts        # Definição das tabelas
│   └── seed.ts          # Dados iniciais
ā”œā”€ā”€ routes/              # Rotas da API
│   ā”œā”€ā”€ hooks/           # Middlewares de autenticação
│   ā”œā”€ā”€ create-course.ts # Criação de cursos
│   ā”œā”€ā”€ get-courses.ts   # Listagem de cursos
│   ā”œā”€ā”€ get-courses-by-id.ts # Busca por ID
│   └── login.ts         # Autenticação
ā”œā”€ā”€ test/                # Testes automatizados
│   └── factories/       # Factories para testes
ā”œā”€ā”€ utils/               # UtilitĆ”rios
ā”œā”€ā”€ app.ts               # Configuração do Fastify
└── server.ts            # Servidor principal

šŸ”§ Configuração e Instalação

PrƩ-requisitos

  • Node.js 18+
  • PostgreSQL 14+
  • Docker (opcional)

Instalação

  1. Clone o repositório
git clone https://github.com/emmanuelmarcosdeoliveira/first-node-api
cd first-node-api
  1. Instale as dependĆŖncias
npm install
  1. Configure as variƔveis de ambiente
cp .env.example .env

Configure as seguintes variƔveis no arquivo .env:

Exemplo:

DATABASE_URL="postgresql://usuario:senha@localhost:5432/nome_do_banco"
JWT_SECRET="seu_jwt_secret_aqui"
NODE_ENV="development"
  1. Execute as migraƧƵes do banco
npm run db:migrate
  1. Popule o banco com dados iniciais
npm run db:seed
  1. Inicie o servidor
npm run dev

A aplicação estarÔ disponível em http://localhost:3333

šŸ“Š Fluxo da Aplicação

graph TD
    A[Cliente] --> B[Fastify Server]
    B --> C{Endpoint}

    C -->|POST /sessions| D[Login Route]
    D --> E[Verificar Credenciais]
    E --> F[Hash Password com Argon2]
    F --> G{Credenciais VƔlidas?}
    G -->|Sim| H[Gerar JWT Token]
    G -->|NĆ£o| I[Retornar Erro 400]
    H --> J[Retornar Token]

    C -->|GET /courses| K[Get Courses Route]
    K --> L[Verificar JWT]
    L --> M{Token VƔlido?}
    M -->|NĆ£o| N[Retornar Erro 401]
    M -->|Sim| O[Verificar Role Manager]
    O --> P{Role Manager?}
    P -->|NĆ£o| Q[Retornar Erro 403]
    P -->|Sim| R[Buscar Cursos no BD]
    R --> S[Retornar Lista de Cursos]

    C -->|POST /courses| T[Create Course Route]
    T --> U[Verificar JWT]
    U --> V{Token VƔlido?}
    V -->|NĆ£o| W[Retornar Erro 401]
    V -->|Sim| X[Verificar Role Manager]
    X --> Y{Role Manager?}
    Y -->|NĆ£o| Z[Retornar Erro 403]
    Y -->|Sim| AA[Validar Dados com Zod]
    AA --> BB{Dados VƔlidos?}
    BB -->|NĆ£o| CC[Retornar Erro 400]
    BB -->|Sim| DD[Criar Curso no BD]
    DD --> EE[Retornar ID do Curso]
Loading

šŸ” Autenticação e Autorização

Sistema de Roles

A aplicação implementa um sistema de controle de acesso baseado em roles:

  • Student: UsuĆ”rio estudante (role padrĆ£o)
  • Manager: UsuĆ”rio gerente com permissƵes administrativas

Fluxo de Autenticação

  1. Login: O usuƔrio faz login com email e senha
  2. Validação: As credenciais são verificadas no banco de dados
  3. Token JWT: Um token Ʃ gerado contendo o ID e role do usuƔrio
  4. Middleware: Todas as rotas protegidas verificam o token JWT
  5. Autorização: O sistema verifica se o usuÔrio tem a role necessÔria

Proteção de Rotas

// Middleware para verificar JWT
preHandler: [checkRequestJWT, checkUserRole("manager")];

šŸ“ API Endpoints

Autenticação

Método Endpoint Descrição Autenticação
POST /sessions Login do usuÔrio Não

Cursos

Método Endpoint Descrição Autenticação Role
GET /courses Listar todos os cursos Sim Manager
GET /courses/:id Buscar curso por ID Sim Manager
POST /courses Criar novo curso Sim Manager

Exemplo de Requisição - Login

curl -X POST http://localhost:3333/sessions \
  -H "Content-Type: application/json" \
  -d '{
    "email": "manager@example.com",
    "password": "senha123"
  }'

Exemplo de Resposta - Login

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Exemplo de Requisição - Criar Curso

curl -X POST http://localhost:3333/courses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer SEU_JWT_TOKEN" \
  -d '{
    "title": "Curso de Node.js"
  }'

🧪 Testes

Executar Testes

# Executar todos os testes
npm run tests

# Executar testes com coverage
npm run test:coverage

# Executar testes em modo watch
npm run test:watch

Estrutura dos Testes

  • Factories: Criação de dados de teste
  • Integration Tests: Testes de integração das rotas
  • Coverage: Relatório de cobertura de código

🐳 Docker

Executar com Docker

# Construir a imagem
docker build -t first-node-api .

# Executar o container
docker run -p 3333:3333 first-node-api

Docker Compose

# Subir todos os serviƧos
docker-compose up -d

# Ver logs
docker-compose logs -f

# Parar serviƧos
docker-compose down

šŸ“š Documentação da API

A documentação interativa da API estÔ disponível em:

  • Desenvolvimento: http://localhost:3333/docs

A documentação é gerada automaticamente usando:

  • OpenAPI/Swagger: Especificação da API
  • Scalar: Interface de documentação moderna

šŸ¤ Contribuição

Exemplo:

  1. FaƧa um fork do projeto

  2. Crie uma branch para sua feature (git checkout -b feature/AmazingFeature)

  3. Commit suas mudanƧas (git commit -m 'Add some AmazingFeature')

  4. Push para a branch (git push origin feature/AmazingFeature)

  5. Abra um Pull Request



Scripts DisponĆ­veis

# Desenvolvimento
npm run dev              # Inicia servidor em modo desenvolvimento

# Banco de Dados
npm run db:generate      # Gera migraƧƵes
npm run db:migrate       # Executa migraƧƵes
npm run db:studio        # Abre Drizzle Studio
npm run db:seed          # Popula banco com dados iniciais

# Testes
npm run tests            # Executa testes
npm run pretest          # Executa migraƧƵes antes dos testes

šŸ‘Øā€šŸ’» Author


Emmanuel Oliveira

developed by šŸ’– Emmanuel Oliveira
Ā© Todos os Direitos Reservados

Releases

No releases published

Packages

No packages published