# Como criar uma API com IA: backend REST passo a passo

URL: https://agentvera.dev/pt/blog/build-api-with-ai/ · Publicado: 2026-10-25

Guia prático para criar uma API com IA: stack, schema e migrations, autenticação, validação, testes, OpenAPI, deploy e os erros de segurança dos agentes.

**Resumo:**

- Escreva primeiro os recursos, endpoints, formato de erro e regras no CLAUDE.md ou AGENTS.md, depois peça ao agente um recurso por vez, com testes e um commit após cada etapa.
- Valide todo corpo de requisição com um schema, mude o banco só por migrations e confira no servidor que cada registro pertence a quem chama, não apenas que a pessoa está logada.
- Gere a documentação OpenAPI a partir dos mesmos schemas, rode as migrations como etapa separada do deploy e peça a um dev para revisar autenticação, autorização e dados antes dos usuários reais.

Dá para criar uma API com IA em uma tarde: peça a um [agente de código](/pt/glossary/coding-agent/) como Claude Code ou Codex “uma API REST de tarefas com usuários” e você recebe rotas, um banco de dados e um servidor rodando. Se essa API sobrevive aos primeiros usuários reais é outra história. Entrada sem validação, endpoints que entregam dados de outras pessoas e migrations que ninguém leu são os problemas de sempre. Este post mostra como eu crio um backend REST com agentes, da escolha da stack ao deploy, e onde vale ir devagar.

Ele faz parte da série que começou com [criar um SaaS com IA](/pt/blog/build-saas-mvp-with-ai/). O post do SaaS trata do produto; este trata do backend por baixo dele, para um app mobile, um frontend ou outros serviços chamarem. Se você é novo nesse jeito de trabalhar, [como fazer vibe coding](/pt/blog/how-to-vibe-code/) é um bom aquecimento.

## 1. Defina a API antes de qualquer código

Uma API é um contrato. Depois que um app mobile é publicado em cima dela, mudar o nome de um campo sai caro. Então, antes de o agente escrever código, anote:

- **Recursos:** os substantivos. Por exemplo `users`, `projects`, `tasks`, `comments`.
- **Endpoints:** `GET /v1/projects`, `POST /v1/projects`, `GET /v1/projects/:id/tasks`, `PATCH /v1/tasks/:id` e assim por diante.
- **Quem pode fazer o quê:** “Membros de um projeto podem ler as tarefas dele; só o dono pode apagar o projeto.”
- **Formato de erro:** um único formato para todo erro, com status HTTP, um código legível por máquina e uma mensagem.
- **Paginação:** cursor ou página, tamanho padrão e máximo.

Mantenha a primeira versão nos endpoints de que um cliente real precisa. API de admin, webhooks e importação em massa podem esperar.

## 2. Coloque as regras em um arquivo de especificação

Agentes não lembram de conversas anteriores. O Claude Code lê o `CLAUDE.md` no início de cada sessão; o Codex e muitos outros agentes leem o `AGENTS.md`. Coloque suas decisões ali:

```markdown
# Tasks API

## Stack
- Node.js LTS, TypeScript, Fastify
- PostgreSQL, Prisma for schema and migrations
- Zod for request validation; OpenAPI generated from the same schemas
- Vitest; tests use app.inject() against a test database

## Rules
- All routes under /v1. JSON only.
- Every request body, query and param is validated with a schema.
- Errors: { "error": { "code": "...", "message": "..." } }, never a stack trace.
- Every query on tasks and projects checks project membership.
- Never return password hashes or tokens; use explicit response schemas.
- Database changes only through migration files.
- List endpoints: cursor pagination, default 20, max 100.
- Secrets come from environment variables; never in code or logs.
- Ask before adding a dependency.
- After every task: pnpm lint && pnpm test

## Out of scope (for now)
Admin API, file uploads, webhooks, GraphQL.
```

Cada regra aqui existe porque os agentes erram sem ela. “Explicit response schemas” impede que o agente devolva a linha inteira do usuário, hash da senha incluído. “Max 100” impede que alguém peça um milhão de linhas. Mais sobre como escrever esse arquivo em [CLAUDE.md e AGENTS.md](/pt/blog/claude-md-agents-md/).

## 3. Escolha uma stack sem surpresas

O agente escreve código melhor em uma stack que já viu milhares de vezes. Duas escolhas seguras:

| | TypeScript | Python |
| --- | --- | --- |
| Framework | Fastify (ou Express, Hono) | FastAPI |
| Validação | Zod ou JSON Schema | Pydantic |
| Acesso ao banco | Prisma ou Drizzle | SQLAlchemy |
| Migrations | Prisma Migrate, Drizzle Kit | Alembic |
| OpenAPI | @fastify/swagger | Nativo |
| Testes | Vitest + `app.inject()` | pytest + `TestClient` |

As duas funcionam. Escolha a linguagem que você consegue ler, porque vai ler muitos diffs. Nos exemplos vou usar TypeScript, Fastify, Prisma e PostgreSQL.

Rode o Postgres localmente com Docker para que o agente nunca precise de um banco compartilhado:

```bash
docker run --name tasks-db -e POSTGRES_PASSWORD=dev -p 5432:5432 -d postgres:16
mkdir tasks-api && cd tasks-api && git init
```

## 4. Primeiro o plano, depois um recurso por vez

Meu primeiro prompt pede um plano, não código:

```text
Read CLAUDE.md. Don't write code yet.
Propose:
1. The Prisma schema (models, relations, indexes, unique constraints)
2. The full endpoint list with request and response shapes
3. How authorization works for each endpoint
4. 6–8 implementation steps, each ending with tests that pass
List open questions at the end.
```

Corrija o plano, responda às perguntas, atualize a especificação. Depois vá etapa por etapa:

```text
Implement step 2: the projects resource (list, create, get, update,
delete). Validate input with Zod, use explicit response schemas,
check membership on every query. Write tests for the happy path,
invalid input, and a second user who is not a member. Run the tests,
show me the result, then stop.
```

O “then stop” está ali para eu ler o diff e fazer o commit antes da próxima etapa. Quando o agente sai do rumo, volto um commit em vez de desembaraçar cinco recursos.

## 5. Schema e migrations

O schema é a parte mais difícil de mudar depois, então leia com atenção:

- **Restrições no banco, não só no código.** `NOT NULL`, e-mails únicos, chaves estrangeiras com um comportamento de `ON DELETE` escolhido de propósito.
- **Índices para as consultas que você roda.** Toda chave estrangeira usada em filtro e toda coluna usada para ordenar em um endpoint de listagem.
- **Timestamps** (`createdAt`, `updatedAt`) em toda tabela; ajudam na depuração e na paginação por cursor.
- **Dinheiro como inteiro ou decimal**, nunca ponto flutuante.

Toda mudança passa por uma migration:

```bash
npx prisma migrate dev --name add_tasks   # create and apply locally
npx prisma migrate reset                  # rebuild the dev database from zero
npx prisma migrate deploy                 # apply pending migrations in production
```

Quando já houver dados reais, leia cada arquivo de migration que o agente escrever. Pare e pergunte sobre `DROP COLUMN`, `DROP TABLE`, renomeações (o Prisma pode transformá-las em drop e add), `UPDATE` ou `DELETE` sem `WHERE` e novas colunas `NOT NULL` em tabelas grandes sem valor padrão.

## 6. Autenticação: use algo que já existe

Não deixe o agente inventar armazenamento de senha ou formato de token. Use um provedor de autenticação hospedado ou uma biblioteca conhecida, e deixe para o agente só a integração:

- **Senhas** com hash argon2 ou bcrypt por meio de uma biblioteca mantida, nunca guardadas ou logadas em texto puro.
- **Sessões ou tokens:** para um cliente de navegador no mesmo site, um cookie de sessão `HttpOnly`, `Secure`, `SameSite` é a opção segura mais simples. Para clientes mobile ou de terceiros, access tokens de vida curta com refresh tokens.
- **Verifique os tokens direito.** Assinatura, expiração, emissor e audiência; rejeite o algoritmo `none`. Peça ao agente para mostrar exatamente onde isso acontece.
- **Limite a taxa de login e de redefinição de senha** para que ninguém consiga testar milhares de senhas.

## 7. Autorização: o bug que os agentes mais escrevem

Autenticação responde “quem é?”. Autorização responde “essa pessoa pode mexer neste registro?”. APIs escritas por agentes costumam acertar a primeira e errar a segunda. A versão clássica é um `GET /v1/tasks/:id` que confere se o token é válido e depois carrega a tarefa pelo ID. Qualquer usuário logado lê qualquer tarefa trocando o número. A OWASP coloca isso, broken object level authorization, em primeiro lugar no seu API Security Top 10.

A correção é um hábito, não uma biblioteca:

- Toda consulta que carrega um registro por ID também filtra pelo que quem chama pode acessar: `where: { id, project: { members: { some: { userId } } } }`.
- “Não encontrado” e “não é seu” devolvem o mesmo `404`, para que ninguém consiga sondar IDs.
- **Teste com dois usuários** em todo endpoint que recebe um ID. Esses são os testes mais valiosos do projeto.

Um erro parecido é o mass assignment: o agente passa o corpo da requisição direto para `update()`, e um usuário envia `"role": "admin"` ou `"ownerId": "..."`. Schemas de validação que listam só os campos permitidos impedem isso.

Peça ao agente: “Liste todos os endpoints e a verificação de autorização que cada um faz. Marque qualquer endpoint que carregue um registro por ID sem filtrar por quem chama.”

## 8. Validação e erros

Toda entrada que cruza a fronteira é validada: corpo, query string, parâmetros de rota, headers que você usa. Com Zod e Fastify, a rota declara seus schemas, e requisições inválidas são rejeitadas com `400` antes de o seu código rodar.

- **Rejeite campos desconhecidos** em vez de ignorá-los em silêncio; isso revela bugs do cliente cedo.
- **Limite tamanhos:** comprimento de strings, de arrays, do corpo da requisição, tamanho da página.
- **Um formato de erro** para tudo, e um tratador global de erros que loga os detalhes no servidor mas devolve ao cliente só `code` e `message`. Stack traces e erros de SQL nas respostas entregam um mapa para atacantes.
- **Só consultas parametrizadas.** O ORM faz isso por padrão; fique de olho em helpers de SQL bruto com concatenação de strings, como o `$queryRawUnsafe` do Prisma.

## 9. Testes que importam

O `app.inject()` do Fastify envia requisições ao app sem abrir uma porta, então os testes de API são rápidos. Você não precisa de 100% de cobertura; precisa destes:

1. **O caminho feliz de cada endpoint**, conferindo status e formato da resposta.
2. **Entrada inválida** devolve `400` com o seu formato de erro.
3. **Sem token** devolve `401`; **registro de outra pessoa** devolve `404`.
4. **A paginação** respeita o máximo.
5. **As migrations rodam do zero** em um banco limpo.

Os testes rodam em um banco de testes separado, resetado entre execuções. Nunca deixe a suíte de testes chegar perto de credenciais de produção.

Fique atento ao agente “consertando” um teste que falha mudando a asserção. Se um arquivo de teste aparece em um diff que você não pediu, pergunte por quê. [Code review com IA](/pt/blog/ai-code-review/) tem um checklist para isso.

## 10. Documentação OpenAPI a partir dos mesmos schemas

Documentação escrita à mão fica desatualizada. Gere-a a partir dos schemas de validação, para que ela descreva exatamente o que o código aceita. No Fastify, o `@fastify/swagger` monta um documento OpenAPI a partir dos schemas das rotas e o `@fastify/swagger-ui` o serve; o FastAPI faz isso de fábrica.

```text
Add @fastify/swagger and @fastify/swagger-ui. Generate the OpenAPI
document from the existing route schemas, add descriptions and
examples, document the error format and auth. Serve the UI at /docs
only when NODE_ENV is not production.
```

O arquivo OpenAPI serve para mais do que documentação: agentes de frontend podem gerar um cliente tipado a partir dele, e outras ferramentas podem descobrir seus endpoints por ele.

## 11. Deploy

Uma API pequena roda bem como contêiner em uma plataforma como Fly.io, Railway ou Render, ou em qualquer servidor com Docker. Um checklist:

- **Um Dockerfile** com build multi-stage e usuário não root. Peça um ao agente e depois leia.
- **Migrations como etapa separada** (`prisma migrate deploy`) antes de a nova versão subir, não dentro de cada instância do app na inicialização.
- **Variáveis de ambiente** para a URL do banco, segredos e origens de CORS permitidas, definidas na plataforma, não na imagem.
- **Um endpoint de saúde** (`/health`) que a plataforma possa checar.
- **CORS** limitado aos seus frontends reais; nunca `*` com credenciais.
- **Só HTTPS**, headers de segurança (por exemplo com `@fastify/helmet`) e logs de requisição sem senhas, tokens ou dados pessoais.
- **Backups** ativados no banco de produção, e uma restauração testada pelo menos uma vez.
- **Rastreamento de erros** como o Sentry, para você saber dos `500` antes que os usuários contem.

## O que a IA erra

- **Devolver linhas inteiras do banco.** Hashes de senha, flags internas e e-mails de outros usuários no JSON. Schemas de resposta explícitos resolvem.
- **Inventar APIs.** Funções de biblioteca que não existem ou mudaram há várias versões. Dê ao agente a documentação atual e cole os erros de volta como estão.
- **Sem paginação.** `findMany()` sem limite funciona até a tabela ter 200.000 linhas.
- **Consultas N+1.** Uma consulta por item dentro de um loop. Peça ao agente para logar as consultas em desenvolvimento e procure repetições.
- **Erros engolidos.** Um `catch {}` que devolve `200` mesmo assim.
- **Segredos no código.** Um segredo JWT fixo no código “só por enquanto” que vai parar em produção.
- **Escopo que cresce sozinho.** “Também adicionei um endpoint de admin.” Reverta ou mova para uma branch própria.

## Segurança: curto, mas sério

- Mantenha o `.env` no `.gitignore`; troque qualquer chave que já tenha ido para um commit.
- Não cole chaves de API no chat; o agente só precisa do nome da variável.
- Aponte o agente para um banco local ou de staging, nunca para produção.
- Leia os comandos que o agente roda, principalmente comandos de banco, `rm`, force pushes e `curl … | sh`.
- Rode `pnpm audit` (ou o equivalente do seu gerenciador de pacotes) de vez em quando e passe a saída para o agente.
- Limite a taxa dos endpoints públicos, não só do login.

Para mais sobre como manter os agentes seguros na sua máquina, veja [segurança de agentes de código com IA](/pt/blog/ai-coding-agent-security/).

## Quando chamar um dev humano

Algumas horas de revisão de um dev backend experiente se pagam:

- Antes de usuários reais se cadastrarem, para autenticação e autorização
- Quando a API guarda dados pessoais, de saúde ou de pagamento
- Quando um parceiro ou cliente corporativo vai se integrar a ela
- Quando o desempenho desaba: consultas lentas, índices faltando, limites de conexão
- Quando você e o agente já falharam três vezes em corrigir o mesmo bug

Facilite a vida dessa pessoa: o arquivo de especificação, o documento OpenAPI, a pasta de migrations e uma execução de testes verde.

## Como faço isso com o AgentVera

Tudo isso funciona em um terminal só. Com vários agentes, o AgentVera ajuda nestes pontos:

- **Trabalho paralelo em worktrees.** No [workspace](/pt/features/workspace/) rodo um agente na API e outro no frontend ou nos testes, cada um na sua [git worktree](/pt/glossary/git-worktree/), para que não pisem nos arquivos um do outro. O método está em [git worktrees para agentes em paralelo](/pt/blog/git-worktree-parallel-agents/).
- **Testar endpoints sem outra ferramenta.** O [cliente de API](/pt/features/api-client/) encontra os endpoints do projeto a partir de arquivos OpenAPI e de rotas em Express, Fastify, Hono, Next.js, FastAPI, Django, NestJS e outros. Envio uma requisição com parâmetros, headers e corpo, e se a resposta for um erro, passo a requisição e a resposta para um agente com um clique.
- **Ver o que chegou ao banco.** O [gerenciador de banco de dados](/pt/features/database-manager/) abre o Postgres local para eu conferir as linhas que o agente criou, e o [DB Guard](/pt/features/db-guard/) avalia o risco de cada migration quando o agente termina o turno e pode testá-la em um banco shadow.
- **Contêineres.** A [página do Docker](/pt/features/docker/) mostra o contêiner do Postgres e seus logs ao lado dos agentes.
- **Revisar turnos.** O [code review](/pt/features/code-review/) confere cada turno concluído antes de eu fazer o merge.

Isso acelera o ciclo; a especificação, os testes e a sua própria revisão continuam sendo o que torna a API segura.

## Resumindo

Para criar uma API com IA, decida o contrato primeiro, escreva as regras no `CLAUDE.md` ou `AGENTS.md`, escolha uma stack popular e peça ao agente um recurso por vez, com testes. Valide toda entrada, mude o banco só por migrations, confira a posse de cada registro, gere o OpenAPI a partir dos mesmos schemas e rode as migrations como etapa separada do deploy. Peça uma revisão humana antes de os usuários reais chegarem. Se você quer rodar os agentes de backend, frontend e testes lado a lado, [baixe o AgentVera de graça](/pt/download/).

## Perguntas frequentes

**Dá para criar uma API REST com IA sem ser dev backend?** Você consegue criar uma API funcional para um produto pequeno com um agente de código, desde que mantenha o escopo pequeno, escreva as regras para o agente e teste cada endpoint. Autenticação, autorização e tudo o que envolve dados pessoais ou de pagamento devem ser revisados por um dev experiente antes do lançamento.

**Qual a melhor stack para criar uma API com IA?** Uma bem popular, que os agentes já viram muitas vezes: TypeScript com Fastify ou Express, ou Python com FastAPI, mais PostgreSQL e uma ferramenta de migrations. Stacks populares significam menos funções inventadas e mais ajuda quando você trava.

**Qual é o bug de segurança mais comum em APIs escritas por IA?** Falta de autorização no nível do objeto: o endpoint confere se o usuário está logado, mas não se o registro é dele, então trocar um ID na URL devolve os dados de outra pessoa. Teste isso com dois usuários em todo endpoint que recebe um ID.

**A IA deve escrever minha autenticação do zero?** Não. Use uma biblioteca conhecida ou um provedor de autenticação hospedado para senhas, sessões e tokens. Deixe o agente fazer a integração e escrever as regras de autorização, que são específicas do seu app, e teste essas regras com cuidado.

**Como gerar documentação OpenAPI para uma API feita com IA?** Peça ao agente para gerá-la a partir dos mesmos schemas que validam as requisições, por exemplo com @fastify/swagger no Fastify ou a documentação nativa do FastAPI. Assim a documentação não se afasta do que o código realmente aceita.

---

**Sobre o AgentVera.** AgentVera é um app desktop para macOS, Windows e Linux, desenvolvido pela Solviera Teknoloji. Ele roda 18 agentes de programação com IA (Claude Code, Codex, Gemini CLI, Copilot, Cursor, Antigravity, opencode, Hermes, Qwen Code, Kimi Code, Kiro, Amp, Droid, Goose, Vibe, Crush, Aider, Cline) lado a lado, por projeto, em terminais reais com as instalações e logins de CLI do próprio usuário. O plano gratuito tem agentes ilimitados. Baixar: https://agentvera.dev/pt/download/ · Preços: https://agentvera.dev/pt/pricing/
