name: backend-dev description: Use esta habilidade para desenvolvimento backend — lógica de servidor, autenticação, microsserviços, funções serverless, middleware, jobs em background, estratégias de cache e padrões de arquitetura backend. Acione com palavras-chave: backend, servidor, endpoint de API, middleware, autenticação, autorização, microsserviço, serverless, job em background, fila, cache, sessão.
Desenvolvimento Backend
Princípios Fundamentais
- Serviços stateless — não armazene estado de sessão em memória; use Redis ou um banco de dados
- Fail fast — valide entradas na fronteira, retorne erros rapidamente
- Idempotência — endpoints POST/PUT que podem ser chamados várias vezes com segurança
- Observabilidade — todo serviço precisa de logs, métricas e rastreamentos
Estrutura de Endpoint de API
Ciclo de Vida da Requisição
Requisição → Limitação de Taxa → Autenticação → Autorização → Validação → Lógica de Negócio → Resposta
Nunca pule esta ordem. Autenticação antes da lógica de negócio. Validação antes do processamento.
Padrões de Resposta
// Sucesso
{ "data": { ... }, "meta": { "pagina": 1, "total": 100 } }
// Erro
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Descrição legível para humanos",
"details": [{ "field": "email", "issue": "Formato inválido" }]
}
}
Padrões de Autenticação
Melhores Práticas com JWT
- TTL curto do token de acesso (15 min) + token de atualização longo (7 dias)
- Armazene o token de atualização em cookie httpOnly (não em localStorage)
- Valide assinatura, expiração, emissor e audiência
- Rotacione os tokens de atualização ao usar
- Mantenha uma lista de revogação ou use apenas tokens de curta duração
Autenticação Baseada em Sessão
- Armazene o ID da sessão em cookie httpOnly, Secure, SameSite
- Armazene dados da sessão em Redis com TTL
- Regere o ID da sessão após o login (prevenção de fixação de sessão)
Autorização
// Verifique a autorização na camada de serviço, não apenas na rota
async function getOrder(userId: string, orderId: string) {
const order = await db.orders.findById(orderId)
if (!order) throw new NotFoundError()
// Verificação de autorização — o usuário só pode ver seus próprios pedidos
if (order.userId !== userId) throw new ForbiddenError()
return order
}
Jobs em Background & Filas
Use filas para:
- Envio de e-mail
- Processamento de imagem/arquivo
- Chamadas de API externa que não precisam ser síncronas
- Tarefas de longa duração
Padrões de Job
Fire-and-forget: Enfileirar e retornar imediatamente
Agendado: Executar em horário específico (cron)
Atrasado: Executar após X minutos/horas
Re-tentativa: Tentar novamente em caso de falha com backoff
Sempre implemente:
- Fila de mensagens mortas para jobs com falha
- Chave de idempotência para evitar processamento duplicado
- Tempo limite por job
- Contagem máxima de re-tentativas
Tratamento de Erros
// Hierarquia de erros estruturada
class AppError extends Error {
constructor(
public message: string,
public statusCode: number,
public code: string
) { super(message) }
}
class ValidationError extends AppError {
constructor(details: ValidationDetail[]) {
super('Falha na validação', 400, 'VALIDATION_ERROR')
this.details = details
}
}
// Tratador global de erros
app.use((err, req, res, next) => {
if (err instanceof AppError) {
return res.status(err.statusCode).json({ error: err })
}
// Registrar erros inesperados
logger.error('Erro inesperado', { err, req })
res.status(500).json({ error: { code: 'INTERNAL_ERROR' } })
})
Lista de Verificação de Middleware
Toda API de produção precisa:
- Logging de requisição (método, caminho, status, duração)
- Limitação de taxa (por IP, por usuário, por endpoint)
- Configuração de CORS (lista de permissões explícita)
- Helmet / cabeçalhos de segurança
- Propagação de ID de requisição (para rastreamento distribuído)
- Limites de tamanho do corpo
- Tratamento de tempo limite
Configuração de Ambiente
// Nunca codifique configuração — sempre a partir do ambiente
const config = {
db: {
url: process.env.DATABASE_URL, // obrigatório
poolSize: parseInt(process.env.DB_POOL_SIZE ?? '10')
},
jwt: {
secret: process.env.JWT_SECRET, // obrigatório
expiresIn: process.env.JWT_TTL ?? '15m'
}
}
// Valide a configuração obrigatória na inicialização — fail fast
const required = ['DATABASE_URL', 'JWT_SECRET']
for (const key of required) {
if (!process.env[key]) throw new Error(`Variável de ambiente obrigatória ausente: ${key}`)
}