Skip to content

API backend TypeScript com Fastify, Prisma e Zod. Implementa Repository Pattern, DI, JWT, e documentação Swagger. Pronto para Docker, escalável e bem estruturado para desenvolvimento produtivo.

License

Notifications You must be signed in to change notification settings

danielmeloalencar/backend-base-fastify-docker

Repository files navigation

Backend Produtivo Banner

Last commit stars size license

📌

Uma API backend ROBUSTA, porém PRODUTIVA

Construída com Fastify, Prisma, TypeScript, e Zod para validação de esquemas. Este projeto segue padrões modernos de desenvolvimento como Dependency Injection, Repository Pattern, e inclui documentação automática com Swagger. .

📋 Índice

🚀 Tecnologias

  • Fastify: Framework web rápido e eficiente
  • Prisma: ORM moderno para acesso ao banco de dados
  • TypeScript: Superset tipado de JavaScript
  • Zod: Validação de esquemas com tipagem TypeScript
  • JWT: Autenticação baseada em tokens
  • Husky: Hooks Git para automação
  • Commitizen: Padronização de commits
  • Jest: Framework de testes
  • Swagger: Documentação automática da API

🔧 Instalação

  1. Clone o repositório:
git clone https://github.com/seunome/ApifyCloneV2.git
cd ApifyCloneV2/backend

⚠️ Importante: Este projeto funcionará melhor com YARN para rodar os scripts automáticos de padronização de commit, padronização de código e formatação.

Para instalar o YARN execute no seu terminal o comando abaixo

npm install yarn -g
  1. Instale as dependências:
yarn install # ou apenas yarn
  1. Configure o Husky (importante!):
yarn prepare

⚠️ Importante: O comando prepare configura o Husky, que gerencia os hooks Git para garantir qualidade do código e padronização de commits.

  1. Configure o arquivo .env na raiz do projeto: Renomeie o arquivo .env.example para .env e configure de acordo com suas informações
DATABASE_URL="file:./backendApiFy.db"
JWT_SECRET="sua_chave_jwt_secreta_aqui"
  1. Execute as migrações do banco de dados:
yarn db:migrate
  1. Gere o cliente Prisma:
yarn run db:generate

🔧 Docker

Se desejar usar docker, execute o comando abaixo na raiz do projeto.

docker compose up -d

✅ Qualidade de Código

Para garantir que seu código e mensagens de commit sempre seguirão o padrão do projeto, use sempre o comando abaixo quando for commitar alterações, caso contrário será retornado um erro.

yarn commit

🛠 Configuração

Banco de Dados

O projeto está configurado para usar SQLite por padrão, mas você pode mudar para PostgreSQL ou qualquer outro banco suportado pelo Prisma alterando o provider no arquivo prisma/schema.prisma.

datasource db {
  provider = "postgresql" // Altere de "sqlite" para "postgresql"
  url      = env("DATABASE_URL")
}

Em seguida, atualize sua variável de ambiente DATABASE_URL no arquivo .env:

DATABASE_URL="postgresql://user:password@localhost:5432/mydatabase"

📁 Estrutura do Projeto

src/
  ├── config/         # Configurações do projeto
  ├── middlewares/    # Middlewares como autenticação
  ├── repositories/   # Camada de acesso a dados
  ├── routes/         # Definição de rotas da API
  ├── services/       # Lógica de negócios
  ├── utils/          # Funções utilitárias
  ├── schemas.ts      # Schemas Zod para validação
  ├── server.ts       # Ponto de entrada do servidor
  └── types.ts        # Tipos TypeScript

📜 Scripts Disponíveis

  • npm run dev: Inicia o servidor de desenvolvimento
  • npm run db:migrate: Executa migrações do Prisma
  • npm run db:studio: Abre o Prisma Studio para visualizar o banco de dados
  • npm run db:generate: Gera o cliente Prisma
  • npm run test: Executa os testes
  • npm run prepare: Configura o Husky
  • npm run check: Executa o ESLint para verificar o código
  • npm run check:fix: Corrige automaticamente problemas de linting
  • npm run prettier: Formata o código com Prettier
  • npm run commit: Adiciona e comita alterações

💻 Desenvolvimento

Adicionando Novas Rotas

  1. Crie um novo arquivo em src/routes/ para o recurso (ex: productRoutes.ts):
// filepath: src/routes/productRoutes.ts
import { FastifyTypedInstance } from '../types';
import { ProductService } from '../services/productService';
import { authenticate } from '../middlewares/authenticate';

export async function productRoutes(fastify: FastifyTypedInstance) {
  const productService = new ProductService();

  // Rota pública
  fastify.get(
    '/products',
    {
      schema: {
        description: 'List all products',
        tags: ['products'],
        response: {
          200: /* seu schema Zod aqui */
        }
      }
    },
    async (request, reply) => {
      const products = await productService.getAllProducts();
      return reply.send(products);
    }
  );

  // Rota protegida
  fastify.post(
    '/products',
    {
      schema: {
        description: 'Create a new product',
        tags: ['products'],
        security: [{ bearerAuth: [] }], // Indica que requer autenticação
        body: /* seu schema Zod aqui */,
        response: {
          201: /* seu schema Zod aqui */
        }
      },
      preHandler: authenticate, // Middleware de autenticação
    },
    async (request, reply) => {
      // Implementação da rota
    }
  );
}
  1. Registre as novas rotas em src/routes/index.ts:
// filepath: src/routes/index.ts
import { FastifyTypedInstance } from '../types';
import { userRoutes } from './userRoutes';
import { productRoutes } from './productRoutes';

export async function routes(fastify: FastifyTypedInstance) {
  await userRoutes(fastify);
  await productRoutes(fastify);
}

Adicionando Novas Tabelas

  1. Edite o arquivo prisma/schema.prisma para adicionar seu novo modelo:
// filepath: prisma/schema.prisma
model Product {
  id          String   @id @default(uuid())
  name        String
  description String
  price       Float
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
  userId      String
  user        User     @relation(fields: [userId], references: [id])
}
  1. Atualize o modelo User para incluir o relacionamento:
// filepath: prisma/schema.prisma
model User {
  id        String    @id @default(uuid())
  name      String
  email     String    @unique
  password  String
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  products  Product[]
}
  1. Execute o comando de migração:
yarn db:migrate
  1. Crie um repositório para o novo modelo:
// filepath: src/repositories/productRepository.ts
import { PrismaClient, Product } from '@prisma/client';

const prisma = new PrismaClient();

export interface CreateProductData {
  name: string;
  description: string;
  price: number;
  userId: string;
}

export class ProductRepository {
  async findAll(): Promise<Product[]> {
    return prisma.product.findMany();
  }

  async create(data: CreateProductData): Promise<Product> {
    return prisma.product.create({
      data,
    });
  }

  async findById(id: string): Promise<Product | null> {
    return prisma.product.findUnique({
      where: { id },
    });
  }

  async findByUser(userId: string): Promise<Product[]> {
    return prisma.product.findMany({
      where: { userId },
    });
  }
}

Relacionamentos no Prisma

O Prisma suporta vários tipos de relacionamentos:

  1. Um para Um (1:1):
// filepath: prisma/schema.prisma
model User {
  id       String    @id @default(uuid())
  profile  Profile?
}

model Profile {
  id       String    @id @default(uuid())
  bio      String
  userId   String    @unique
  user     User      @relation(fields: [userId], references: [id])
}
  1. Um para Muitos (1:N):
// filepath: prisma/schema.prisma
model User {
  id       String    @id @default(uuid())
  posts    Post[]
}

model Post {
  id       String    @id @default(uuid())
  title    String
  content  String
  userId   String
  user     User      @relation(fields: [userId], references: [id])
}
  1. Muitos para Muitos (N:M):
// filepath: prisma/schema.prisma
model Post {
  id        String     @id @default(uuid())
  title     String
  categories Category[] @relation("PostToCategory")
}

model Category {
  id    String  @id @default(uuid())
  name  String
  posts Post[]  @relation("PostToCategory")
}

📖 Documentação da API

A documentação da API é gerada automaticamente usando Swagger. Após iniciar o servidor, acesse:

http://localhost:3333/docs

A interface do Swagger mostrará todas as rotas disponíveis, seus parâmetros, corpo de requisição e respostas.

🤝 Contribuindo

  1. Faça o fork do projeto
  2. Crie sua feature branch (git checkout -b feature/minha-feature)
  3. Execute yarn prepare para configurar o Husky
  4. Faça suas alterações
  5. Execute os testes (yarn test)
  6. Use yarn commit para fazer commits padronizados
  7. Envie para o branch (git push origin feature/minha-feature)
  8. Abra um Pull Request

Desenvolvido por Daniel Alencar

About

API backend TypeScript com Fastify, Prisma e Zod. Implementa Repository Pattern, DI, JWT, e documentação Swagger. Pronto para Docker, escalável e bem estruturado para desenvolvimento produtivo.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published