Publicado
- 4 min read
Crie uma API com Node.js e TypeScript usando o padrão TDD

Introdução
Neste post, vamos explorar como criar uma API utilizando Node.js e TypeScript aplicando o padrão de desenvolvimento TDD (Test-Driven Development). O TDD é uma metodologia que prioriza a escrita de testes antes de implementar a lógica da aplicação, resultando em código mais bem estruturado e com menos bugs. Ao final deste tutorial, você terá uma API funcional e testada, pronta para ser utilizada em qualquer aplicação.
Pré-requisitos
Antes de começarmos, certifique-se de ter o seguinte instalado no seu ambiente de desenvolvimento:
- Node.js (versão 14 ou superior)
- npm (gerenciador de pacotes do Node.js)
- TypeScript
- Um editor de código (como Visual Studio Code)
Conceitos principais
1. O que é TDD?
O TDD é uma abordagem de desenvolvimento que se concentra em escrever testes antes de escrever o código funcional que implementa aqueles testes. O ciclo TDD é simples:
- Escreva um teste que falha.
- Escreva código suficiente para passar no teste.
- Refatore o código, mantendo os testes passando.
2. Instalação de dependências
Para iniciar nosso projeto, crie uma nova pasta e dentro dela, execute os seguintes comandos:
npm init -y
npm install express @types/express typescript ts-node nodemon --save
npm install jest ts-jest @types/jest --save-dev
Em seguida, crie um arquivo de configuração do TypeScript (tsconfig.json
):
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true
}
}
E um arquivo de configuração do Jest (jest.config.js
):
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node'
}
Mini-projeto prático: Criando uma API simples
1. Estrutura de Pastas
Crie a seguinte estrutura de pastas para o seu projeto:
/src
/controllers
/routes
/tests
index.ts
2. Implementando a API
Vamos criar uma API simples que gerencia um recurso de “tarefas”.
a) Criando o modelo de Tarefa
Dentro da pasta /src
crie um arquivo task.ts
:
export interface Task {
id: number
title: string
completed: boolean
}
const tasks: Task[] = []
export const getTasks = () => tasks
export const createTask = (title: string): Task => {
const newTask: Task = {
id: tasks.length + 1,
title,
completed: false
}
tasks.push(newTask)
return newTask
}
b) Criando o controller
Em /src/controllers
, crie taskController.ts
:
import { Request, Response } from 'express'
import { createTask, getTasks } from '../task'
export const getAllTasks = (req: Request, res: Response) => {
const tasks = getTasks()
res.json(tasks)
}
export const addTask = (req: Request, res: Response) => {
const { title } = req.body
const task = createTask(title)
res.status(201).json(task)
}
c) Criando as rotas
Em /src/routes
, crie taskRoutes.ts
:
import { Router } from 'express'
import { getAllTasks, addTask } from '../controllers/taskController'
const router = Router()
router.get('/tasks', getAllTasks)
router.post('/tasks', addTask)
export default router
d) Configurando o servidor
No arquivo index.ts
, configure o servidor Express:
import express from 'express'
import taskRoutes from './routes/taskRoutes'
const app = express()
const PORT = process.env.PORT || 3000
app.use(express.json())
app.use('/api', taskRoutes)
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`)
})
Testes
1. Escrevendo os testes
Dentro da pasta /tests
, crie taskController.test.ts
:
import request from 'supertest'
import app from '../index' // Exporte o app do arquivo index.ts
describe('Task API', () => {
it('should create a new task', async () => {
const response = await request(app).post('/api/tasks').send({ title: 'New Task' })
expect(response.status).toBe(201)
expect(response.body.title).toBe('New Task')
})
it('should return all tasks', async () => {
const response = await request(app).get('/api/tasks')
expect(response.status).toBe(200)
expect(Array.isArray(response.body)).toBeTruthy()
})
})
2. Executando os testes
Adicione o seguinte comando ao package.json
para executar os testes:
"scripts": {
"test": "jest"
}
Para rodar os testes, execute:
npm test
Padrões de projeto aconselháveis
- Separação de preocupações: Use o padrão MVC (Model-View-Controller) para organizar o código.
- Injeção de dependências: Facilita o teste e a manutenção.
- Boas práticas de nomenclatura: Torne seu código legível e compreensível.
Prós e Contras do TDD
Prós
- Código bem testado: Produz uma base de código mais robusta e livre de bugs.
- Refatoração mais segura: Permite melhorias na base de código sem perder a funcionalidade.
Contras
- Curva de aprendizado: Para iniciantes, pode ser desafiador entender a mentalidade de TDD.
- Tempo adicional: O desenvolvimento pode inicialmente ser mais lento devido à necessidade de escrever testes.
Performance de cada ferramenta
- Node.js: Alta performance para aplicações de I/O intensivo, ideal para APIs.
- TypeScript: Adiciona tipos ao JavaScript, resultando em uma melhor manutenção e menos erros comuns.
- Jest: Alta performance em testes, com paralelismo e capacidade de mocks.
Dicas para próximos passos
- Explore o uso de middlewares no Express.
- Aprenda sobre autenticação e autorização em APIs.
- Experimente adicionar um banco de dados ao seu projeto, como MongoDB ou PostgreSQL.
Possíveis erros e soluções
- Erro: “Cannot find module”: Certifique-se de que todas as dependências estão instaladas adequadamente.
- Erro de rota 404: Verifique se as rotas estão definidas corretamente e se o servidor está em execução.
Links para materiais de apoio
Com este guia, você agora possui uma base sólida em como criar uma API utilizando Node.js e TypeScript com TDD. Continue praticando e explorando novas funcionalidades!