Skip to content

TheMegafuji/fastify-starter-api-template

Fastify Starter API Template

Uma base escalável e modular para o desenvolvimento de APIs backend utilizando Fastify, Prisma e PostgreSQL. Ideal para kickstart de projetos robustos que necessitam de autenticação JWT, testes automatizados e integração com ferramentas modernas (Docker, Vercel, Redis e AWS).

Sumário

Recursos

  • Servidor e API com Fastify: Gerenciamento eficiente de requisições HTTP e definição de rotas.
  • Banco de Dados com PostgreSQL e Prisma: Operações CRUD com Prisma Client e migrações via Prisma Migrate.
  • Autenticação JWT: Segurança para endpoints protegidos.
  • Sistema de Ranking: Listagem paginada, filtrada e ordenada dos jogadores.
  • Endpoints de Gameplay: Caça ao monstro com lógica de progressão (XP, ouro e níveis).
  • Middleware Personalizado: Autenticação e tratamento centralizado de erros.
  • Testes Automatizados: Cobertura de endpoints críticos com Jest e supertest.
  • Integração com Redis e AWS: Configurações para caching e serviços em nuvem.
  • Deploy Pronto para Docker e Vercel: Facilita o escalonamento e a implantação em ambientes serverless.

O que mudou (migração para Prisma)

As principais mudanças na camada de dados foram:

  • ORM anterior removido (entities/migrations/repository antigos deixaram de existir).
  • Prisma introduzido:
    • Schema em prisma/schema.prisma
    • Migrations em prisma/migrations/*
    • Prisma Client singleton (serverless-safe) em src/config/db.config.ts
  • Camada de dados com ports/adapters (para trocar banco com impacto mínimo):
    • Ports (interfaces): src/repositories/ports/*
    • Adapters: src/repositories/prisma/* (PostgreSQL) e src/repositories/memory/* (test)
    • O restante do app importa apenas src/repositories/player.repository.ts
  • Testes sem banco: em NODE_ENV=test, o repositório usa o adapter in-memory.

Tecnologias

  • Fastify – Framework web de alta performance.
  • Prisma – ORM/Toolkit (Client + Migrate) para TypeScript.
  • PostgreSQL – Banco de dados relacional.
  • JWT – Autenticação via JSON Web Tokens.
  • @sinclair/typebox – Definição e validação de schemas para Fastify. Utilizado para criar definições de tipos e realizar a validação automática dos dados de entrada e saída dos endpoints.
  • Jest – Framework para testes.
  • Docker – Containerização.
  • Vercel – Plataforma de deploy serverless.
  • Redis – Armazenamento em cache e gerenciamento de sessões.

Arquitetura

A estrutura do projeto segue uma abordagem modular, separando as responsabilidades em:

  • Controllers: Lógica de processamento e respostas HTTP.
  • Services: Regras de negócio e manipulação de dados.
  • Data layer (ports/adapters): Acesso a dados via interfaces (ports) + implementações (adapters), hoje com Prisma.
  • Routes: Definição dos endpoints e integração com os controllers.
  • Schemas: Validação de entrada e saída utilizando @sinclair/typebox. Essa abordagem permite que o Fastify valide automaticamente os dados das requisições, eliminando a necessidade de validação manual dentro dos controllers.
  • Plugins: Configurações personalizadas (ex.: autenticação, tratamento de erros).
  • Config: Arquivos de configuração para banco de dados, AWS, Redis, etc.
  • Tests: Scripts para testes automatizados, garantindo a integridade dos endpoints.

A seguir, a estrutura de pastas do projeto:

├── prisma/
    ├── schema.prisma
    ├── migrations/
    ├── seed.ts
    └── scripts/
        └── prisma.cjs
├── __tests__/
    ├── monster.test.ts
    └── ranking.test.ts
├── src/
    ├── api/
    │   └── index.ts
    ├── config/
    │   ├── aws.config.ts
    │   ├── db.config.ts
    │   ├── index.ts
    │   └── redis.config.ts
    ├── controllers/
    │   ├── auth.controller.ts
    │   ├── healthcheck.controller.ts
    │   ├── monster.controller.ts
    │   ├── player.controller.ts
    │   └── ranking.controller.ts
    ├── docs/
    │   ├── auth.doc.ts
    │   ├── healthcheck.doc.ts
    │   ├── monster.doc.ts
    │   ├── player.doc.ts
    │   └── ranking.doc.ts
    ├── entities/
    │   └── Player.entity.ts
    ├── plugins/
    │   ├── auth.ts
    │   └── errorHandler.ts
    ├── repositories/
    │   ├── player.repository.ts
    │   ├── ports/
    │   │   └── player.repository.port.ts
    │   ├── prisma/
    │   │   └── player.prisma.repository.ts
    │   └── memory/
    │       └── player.memory.repository.ts
    ├── routes/
    │   ├── auth.routes.ts
    │   ├── healthcheck.routes.ts
    │   ├── index.ts
    │   ├── monster.routes.ts
    │   ├── player.routes.ts
    │   └── ranking.routes.ts
    ├── schemas/
    │   ├── auth.schema.ts
    │   ├── healthcheck.schema.ts
    │   ├── monster.schema.ts
    │   ├── player.schema.ts
    │   └── ranking.schema.ts
    ├── services/
    │   ├── monster.service.ts
    │   ├── player.service.ts
    │   └── ranking.service.ts
    ├── types/
    │   ├── fastify-jwt.d.ts
    │   └── fastify.d.ts
    ├── local.ts
    └── server.ts
├── .editorconfig
├── .prettierrc
├── debug.log
├── Dockerfile
├── errors.log
├── jest.config.js
├── package-lock.json
├── package.json
├── README.md
├── tsconfig.json
└── vercel.json

Configuração para deploy na Vercel

Instalação

  1. Clone o repositório:

    git clone <URL_DO_REPOSITORIO>
    cd fastify-starter-api-template
  2. Instale as dependências:

    npm install

Qualidade de código (lint/format)

Husky (Git hooks)

Este template usa Husky para executar checagens automaticamente via Git hooks:

  • pre-commit: roda lint-staged (lint + format apenas nos arquivos staged)
  • O que roda no lint-staged (ver .lintstagedrc.cjs):
    • *.{ts,tsx,js,jsx}eslint --fix + prettier --write
    • *.{json,yml,yaml}prettier --write (Markdown é ignorado no hook)
  • pre-push: roda npm test
    • Para pular os testes no push, defina SKIP_TESTS=1 (ex.: PowerShell: $env:SKIP_TESTS=1; git push)

Observações:

  • O Husky é instalado via npm install (script prepare). Se precisar reinstalar manualmente: npm run prepare.
  • Para bypass pontual: git commit --no-verify / git push --no-verify (ou HUSKY=0).

Lint (ESLint)

Comandos disponíveis:

npm run lint
npm run lint:fix

Format (Prettier)

Para formatar o projeto:

npm run format

Configuração:

# Configurações do Servidor
PORT = 5000
NODE_ENV = development|production|homolog|test|local

# Banco de Dados - Opção 1: URLs completas (recomendado)
DATABASE_URL_WRITE = postgres://user:password@host:port/database
# opcional (read replica)
DATABASE_URL_READ = postgres://user:password@host:port/database

# Prisma CLI usa DATABASE_URL.
# Se você não setar DATABASE_URL, os scripts db:* fazem fallback automático para DATABASE_URL_WRITE.
# (opcional, mas recomendado para ferramentas externas)
DATABASE_URL = postgres://user:password@host:port/database

# Banco de Dados - Opção 2: Variáveis individuais
DB_HOST = localhost
DB_PORT = 5432
DB_USER = root
DB_PASSWORD = your_password
DB_NAME = your_database
DB_SSL = true|false
DB_MAX_CONNECTION = 10

# Redis e Cache
CACHE_PROVIDER = none|redis|upstash
REDIS_URL = redis://localhost:6379
# opcional (força TLS quando CACHE_PROVIDER=redis; se REDIS_URL começar com rediss://, TLS já é ativado)
REDIS_TLS = true|false
UPSTASH_REDIS_REST_URL = 
UPSTASH_REDIS_REST_TOKEN = 

# AWS Services (Opcional)
AWS_REGION = 
AWS_ACCESS_KEY_ID = 
AWS_SECRET_ACCESS_KEY = 

# JWT & API Security
JWT_SECRET = your-super-secret-jwt-key-here-make-it-long-and-random
API_SECRET_KEY = your-api-secret-key-for-additional-security

# Rate Limiting
RATE_LIMIT_REDIS_URL = redis://localhost:6379

# Logging
LOG_LEVEL = info
APP_NAME = your_app_name

# CORS
CORS_ORIGIN = http://localhost:3000,https://yourdomain.com

Variáveis de ambiente (validação e checagem)

O carregamento/validação do .env é centralizado em src/config/env.ts (com Zod):

  • Se existir um arquivo .env na raiz, ele é carregado automaticamente.
  • Em seguida, as variáveis são validadas e o app falha cedo (com mensagem detalhada) se algo essencial estiver errado.
  • Para validar sem subir o servidor, use:
npm run env:check

Regras importantes:

  • NODE_ENV=test: relaxa algumas exigências (ex.: JWT/DB) para facilitar testes.
  • JWT: em ambientes não-test, JWT_SECRET é obrigatório.
  • Banco: em ambientes não-test, é obrigatório configurar DATABASE_URL_WRITE ou as variáveis DB_*.
  • CORS: CORS_ORIGIN aceita múltiplas origens separadas por vírgula (URLs completas).

Logging (logger)

O logger é configurado em src/config/logger.ts usando Pino:

  • Em development/local: saída “pretty” (via pino-pretty).
  • Em production/homolog: logs estruturados (JSON).
  • Campos sensíveis comuns (token/password/authorization/cookies/etc.) são redigidos automaticamente.

Variáveis:

  • LOG_LEVEL: fatal|error|warn|info|debug|trace|silent (default: info em prod-like, debug em dev/local)
  • APP_NAME: nome do serviço aplicado nos logs (default: api)

Cache & Rate limit (Redis/Upstash opcionais)

Cache (CACHE_PROVIDER)

O cache é opcional e você deve escolher exatamente um provider via CACHE_PROVIDER:

  • none (padrão): sem cache (nenhuma conexão é aberta).
  • redis: usa Redis via REDIS_URL (opcionalmente com TLS).
  • upstash: usa Upstash via UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN.

Se CACHE_PROVIDER estiver ausente ou inválido, o fallback é none.

Variáveis (cache)

  • CACHE_PROVIDER: none | redis | upstash (default: none).
  • REDIS_URL: usado quando CACHE_PROVIDER=redis (ex.: redis://localhost:6379 ou rediss://...).
  • REDIS_TLS (opcional): true|false. Quando true, força TLS para CACHE_PROVIDER=redis. Se REDIS_URL começar com rediss://, TLS já é ativado automaticamente.
  • UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN: usados quando CACHE_PROVIDER=upstash.

Exemplos

1) Sem cache (default):

CACHE_PROVIDER=none

2) Redis (local):

CACHE_PROVIDER=redis
REDIS_URL=redis://localhost:6379
# opcional (default: false)
# REDIS_TLS=true

3) Redis (TLS / cloud):

CACHE_PROVIDER=redis
REDIS_URL=rediss://:password@your-host:6379
# opcional (já fica true com rediss://)
# REDIS_TLS=true

4) Upstash (REST):

CACHE_PROVIDER=upstash
UPSTASH_REDIS_REST_URL=https://YOUR-DB.upstash.io
UPSTASH_REDIS_REST_TOKEN=YOUR_TOKEN

Observações

  • TTL: o ttl do CacheService é em segundos.
  • Fail-safe: se CACHE_PROVIDER estiver configurado mas as variáveis necessárias estiverem faltando/erradas, o cache é desativado e o app não quebra (loga e segue).
  • No-op quando desativado: set/get/del/flush não quebram a aplicação quando CACHE_PROVIDER=none (ou quando o cache é desativado por falha de configuração/conexão).

Rate limit

O @fastify/rate-limit funciona de forma segura mesmo sem Redis:

  • Se RATE_LIMIT_REDIS_URL não estiver configurado, o plugin usa store em memória (por processo).
  • Com skipOnError: true, qualquer erro no Redis não bloqueia as requisições.
  • Em ambientes Vercel/serverless, RATE_LIMIT_REDIS_URL apontando para localhost é ignorado (fallback para memória) para evitar travar requests.

Exemplo com Redis dedicado para rate limit:

RATE_LIMIT_REDIS_URL=rediss://:password@your-redis-host:6379

Banco de dados (Prisma)

1) Gerar Prisma Client

npm run db:generate

2) Rodar migrations (dev/local)

npm run db:migrate:dev

3) Rodar migrations (deploy/prod, não-interativo)

npm run db:migrate

4) Seed (idempotente)

npm run db:seed

5) Reset (dev)

npm run db:reset
npm run db:seed

6) Prisma Studio

npm run db:studio

Execução

Ambiente de Desenvolvimento

Para iniciar o servidor em modo de desenvolvimento com hot-reloading:

npm run db:generate
npm run db:migrate:dev
npm run db:seed
npm run dev

Ambiente de Produção

Para construir e iniciar o projeto utilizando Vercel:

npm run build
npm run start

Testes

Os testes automatizados foram desenvolvidos com Jest e supertest. Para executá-los, use:

npm test

Os testes estão localizados na pasta tests/ e cobrem os endpoints de monster-hunt e ranking, garantindo o comportamento esperado.

Observação: em NODE_ENV=test, a camada de dados usa um adapter in-memory (não precisa Postgres).

Documentação da API

A documentação interativa da API está disponível via Swagger:

Por padrão, a UI está na raiz (/).

Acesse: http://localhost:5000/ (ou a porta definida em PORT) Nesta interface, você pode visualizar todos os endpoints, modelos de dados, parâmetros e exemplos de resposta.

Deploy

Docker

O projeto inclui um Dockerfile para containerização. Para construir e rodar o container:

docker build -t fastify-starter-api-template .
docker run -p 5000:5000 fastify-starter-api-template

Vercel

A configuração para deploy em Vercel está pronta no arquivo vercel.json. Basta conectar o repositório ao Vercel para que o deploy seja efetuado automaticamente.

Licença

Este projeto está licenciado sob a MIT License.

About

Template / Boilerplate open source para APIs backend escaláveis com Fastify, Prisma e PostgreSQL. Conta com autenticação JWT, documentação Swagger, testes com Jest e deploy via Docker/Vercel. Estrutura modular e boas práticas para kickstart de projetos modernos.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors