Introdução: por que TypeScript e REST API são a combinação ideal para desenvolvimento rápido
\nO desenvolvimento web moderno exige velocidade e confiabilidade. Se você precisa criar rapidamente um backend para um aplicativo móvel, serviço web ou arquitetura de microsserviços, a combinação TypeScript + Node.js + Express é uma das ferramentas mais eficientes. O TypeScript adiciona tipagem estrita ao JavaScript, permitindo capturar erros em tempo de compilação, e não em tempo de execução. Isso é especialmente valioso ao construir APIs REST, onde cada endpoint deve saber claramente quais dados recebe e retorna.
\nNeste artigo, em 30 minutos, criaremos uma API REST completa para gerenciar uma lista de tarefas (To-Do List). Você aprenderá a configurar o projeto, escrever controllers, rotas e middleware. Tudo com exemplos práticos e código pronto.
\n\nPreparação e configuração do projeto (5 minutos)
\nPrimeiro, vamos criar a estrutura do projeto e instalar as dependências.
\nmkdir todo-api\ncd todo-api\nnpm init -y\nnpm install express cors uuid\nnpm install -D typescript @types/express @types/cors @types/uuid ts-node nodemon\nCrie o arquivo tsconfig.json na raiz do projeto:
{\n "compilerOptions": {\n "target": "ES2020",\n "module": "commonjs",\n "outDir": "./dist",\n "rootDir": "./src",\n "strict": true,\n "esModuleInterop": true,\n "skipLibCheck": true\n },\n "include": ["src/**/*"]\n}\nAdicione os scripts no package.json:
"scripts": {\n "dev": "nodemon --exec ts-node src/index.ts",\n "build": "tsc",\n "start": "node dist/index.js"\n}\nCrie a pasta src e o arquivo index.ts — ponto de entrada.
Estrutura básica de pastas
\n- \n
src/index.ts— ponto de entrada, inicialização do servidor \n src/routes/tasks.ts— rotas para tarefas \n src/controllers/taskController.ts— lógica de processamento de requisições \n src/models/task.ts— interfaces e tipos \n src/middleware/errorHandler.ts— tratamento de erros (opcional) \n
Criação do modelo de dados e interfaces (5 minutos)
\nVamos definir os tipos de dados para nossa tarefa. Crie o arquivo src/models/task.ts:
export interface Task {\n id: string;\n title: string;\n completed: boolean;\n createdAt: Date;\n}\n\nexport type CreateTaskDto = Pick<Task, 'title'>;\nexport type UpdateTaskDto = Partial<Pick<Task, 'title' | 'completed'>>;\nAqui usamos Pick e Partial — tipos utilitários nativos do TypeScript. CreateTaskDto aceita apenas o título, enquanto UpdateTaskDto aceita campos opcionais para atualização parcial.
Escrita dos controllers e rotas (15 minutos)
\nAgora a parte mais interessante — a lógica da aplicação. Vamos criar um armazenamento temporário de tarefas em memória (in-memory storage). Para produção, isso deve ser substituído por um banco de dados.
\n\nController de tarefas
\nArquivo src/controllers/taskController.ts:
import { Request, Response } from 'express';\nimport { v4 as uuidv4 } from 'uuid';\nimport { Task, CreateTaskDto, UpdateTaskDto } from '../models/task';\n\n// Armazenamento temporário\nlet tasks: Task[] = [];\n\n// GET /api/tasks\nexport const getAllTasks = (req: Request, res: Response) => {\n res.json(tasks);\n};\n\n// GET /api/tasks/:id\nexport const getTaskById = (req: Request, res: Response) => {\n const task = tasks.find(t => t.id === req.params.id);\n if (!task) {\n return res.status(404).json({ message: 'Tarefa não encontrada' });\n }\n res.json(task);\n};\n\n// POST /api/tasks\nexport const createTask = (req: Request, res: Response) => {\n const { title } = req.body as CreateTaskDto;\n if (!title || typeof title !== 'string') {\n return res.status(400).json({ message: 'O campo title é obrigatório e deve ser