API simples em Node.js + TypeScript usando Fastify, Drizzle ORM (PostgreSQL) e Zod. Inclui documentação Swagger/Scalar em ambiente de desenvolvimento.
- Node.js 22+
- Docker e Docker Compose
- npm (ou outro gerenciador, mas o projeto usa
package-lock.json
)
- Fastify 5
- TypeScript
- Drizzle ORM + PostgreSQL
- Zod (validação)
- Swagger/OpenAPI + Scalar API Reference (em
/docs
quandoNODE_ENV=development
)
- Clone o repositório e acesse a pasta do projeto.
- Instale as dependências:
npm install
- Suba o banco Postgres com Docker:
docker compose up -d
- Crie um arquivo
.env
na raiz com:
# URL do banco (Docker local padrão)
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/desafio
# Ativa docs em /docs
NODE_ENV=development
- Rode as migrações (Drizzle):
npm run db:migrate
(opcional) Para inspecionar o schema/estado com o Drizzle Studio:
npm run db:studio
npm run dev
- Porta padrão:
http://localhost:3333
- Logs legíveis habilitados
- Documentação da API (em dev):
http://localhost:3333/docs
Base URL: http://localhost:3333
-
POST
/courses
- Cria um curso
- Body (JSON):
{ "title": "Curso de Docker" }
- Respostas:
- 201:
{ "courseId": "<uuid>" }
- 201:
-
GET
/courses
- Lista todos os cursos
- 200:
{ "courses": [{ "id": "<uuid>", "title": "..." }] }
-
GET
/courses/:id
- Busca um curso pelo ID
- Parâmetros:
id
(UUID) - Respostas:
- 200:
{ "course": { "id": "<uuid>", "title": "...", "description": "... | null" } }
- 404: vazio
- 200:
Há um arquivo requisicoes.http
com exemplos prontos (compatível com extensões de REST Client).
Tabelas principais definidas em src/database/schema.ts
:
courses
id
(uuid, pk, default random)title
(text, único, obrigatório)description
(text, opcional)
users
(exemplo para estudos)id
(uuid, pk, default random)name
(text, obrigatório)email
(text, único, obrigatório)
sequenceDiagram
participant C as Client
participant S as Fastify Server
participant V as Zod Validator
participant DB as Drizzle + PostgreSQL
C->>S: POST /courses {title}
S->>V: Validar body
V-->>S: OK ou Erro 400
alt válido
S->>DB: INSERT INTO courses (title)
DB-->>S: {id}
S-->>C: 201 {courseId}
else inválido
S-->>C: 400
end
C->>S: GET /courses
S->>DB: SELECT id,title FROM courses
DB-->>S: lista
S-->>C: 200 {courses: [...]}
C->>S: GET /courses/:id
S->>V: Validar param id (uuid)
V-->>S: OK ou Erro 400
alt encontrado
S->>DB: SELECT * FROM courses WHERE id=...
DB-->>S: course
S-->>C: 200 {course}
else não encontrado
S-->>C: 404
end
npm run dev
: inicia o servidor com reload e carrega variáveis de.env
npm run db:generate
: gera artefatos do Drizzle a partir do schemanpm run db:migrate
: aplica migrações no banconpm run db:studio
: abre o Drizzle Studio
- Conexão recusada ao Postgres: confirme
docker compose up -d
e que a porta5432
não está em uso. - Variável
DATABASE_URL
ausente: verifique seu.env
. O Drizzle exige essa variável paradb:generate
,db:migrate
edb:studio
. - Docs não aparecem em
/docs
: garantaNODE_ENV=development
no.env
e reinicie o servidor.
ISC (ver package.json
).