PITCH: NextFastAPI — Crie APIs com middlewares no estilo Express usando Next.js App Router
🔧 Inspirado no
next-connect
— usado aqui no próprio TabNews — o NextFastAPI traz uma abordagem moderna e tipada para o novo App Router do Next.js, com suporte a middlewares encadeáveis, múltiplos métodos e tratamento de erros prontos para produção.
Se você está usando o App Router do Next.js e sentiu falta da organização e extensibilidade que o next-connect
oferecia, especialmente para middlewares e múltiplos métodos (GET
, POST
, etc.), agora você pode contar com o NextFastAPI — uma forma simples e estruturada de criar suas rotas.
🚀 Instalação
npm install nextfastapi
# ou
yarn add nextfastapi
📄 Começando Rápido
🔹 Criando uma rota GET simples
// app/api/hello/route.ts
import { RouteController, expose } from "nextfastapi";
const controller = new RouteController();
controller.get(async (req) => {
return Response.json({ message: "Hello from NextFastAPI!" });
});
export const GET = expose(controller);
⚙️ Middlewares
O NextFastAPI suporta middlewares encadeáveis usando next()
, igual ao Express ou next-connect — e com tipagem segura (req.context
).
Você pode usá-los globalmente (todas as rotas) ou apenas em métodos específicos.
🔹 Middleware Global (aplicado a todos os métodos)
import type { Middleware } from "nextfastapi/types";
type Context = {
requestTime?: string;
};
const controller = new RouteController<Context>();
const addRequestTime: Middleware<Context> = (req, params, next) => {
req.context.requestTime = new Date().toISOString();
return next();
};
controller.use(addRequestTime);
controller.get((req) => {
return Response.json({ requestedAt: req.context.requestTime });
});
controller.post((req) => {
return Response.json({ postedAt: req.context.requestTime });
});
export const GET = expose(controller);
export const POST = expose(controller);
🔹 Middleware para um método específico
import type { Middleware } from "nextfastapi/types";
import { ForbiddenError } from "nextfastapi/errors";
type Context = {
userRole?: "admin" | "user";
};
// Simulando role
const insertRole: Middleware<Context> = (req, _, next) => {
req.context.userRole = "user"; // ou "admin"
return next();
};
const onlyAdmin: Middleware<Context> = (req, _, next) => {
if (req.context.userRole !== "admin") {
throw new ForbiddenError({ message: "Acesso restrito para administradores." });
}
return next();
};
const controller = new RouteController<Context>();
controller.get(insertRole, onlyAdmin, (req) => {
return Response.json({ secret: "Área de admin" });
});
controller.post((req) => {
return Response.json({ open: "Área pública" });
});
export const GET = expose(controller);
export const POST = expose(controller);
⚠️ Tratamento de Erros
Você pode usar as classes de erro incluídas no pacote e deixá-las serem tratadas automaticamente. Ou, se quiser, pode usar um .onError()
personalizado.
🔹 Erro automático com classe pronta
import { BadRequestError } from "nextfastapi/errors";
controller.get((req) => {
throw new BadRequestError({ message: "Parâmetros inválidos." });
});
🔹 Handler de erro customizado
import { transformError } from "nextfastapi/errors";
controller.onError((err, req) => {
const safeError = transformError(err);
return Response.json(
{
error: safeError.message,
action: safeError.action,
},
{ status: safeError.statusCode }
);
});
📚 Erros HTTP disponíveis
Você pode lançar qualquer uma dessas classes de erro com mensagem personalizada. Elas já trazem status HTTP e mensagem de ação por padrão:
Classe de Erro | Status | Ação Padrão |
---|---|---|
BadRequestError | 400 | Verifique os dados da requisição. |
UnauthorizedError | 401 | Envie credenciais de autenticação válidas. |
ForbiddenError | 403 | Verifique se tem permissão para acessar. |
NotFoundError | 404 | Verifique o identificador do recurso. |
MethodNotAllowedError | 405 | Use um método HTTP suportado. |
ConflictError | 409 | Resolva conflitos antes de reenviar. |
UnprocessableEntityError | 422 | Verifique os dados enviados. |
TooManyRequestsError | 429 | Reduza a frequência de requisições. |
InternalError | 500 | Tente novamente ou contate o suporte. |
✅ Conclusão
- ✅ Crie rotas com
.get()
,.post()
etc. e exporte comexpose(controller)
- ✅ Use middlewares com
controller.use(...)
ou diretamente nos métodos - ✅ Compartilhe dados entre handlers com
req.context
- ✅ Lide com erros automaticamente ou com
.onError()
- ✅ Tipagem segura para
Request
,Context
,Params
e erros
🔗 Código Aberto
MIT © 2025 – Desenvolvido por Ezequias Lopes
GitHub: https://github.com/silvaezequias/nextfastapi
💬 Ficou com dúvidas? Quer ver exemplos reais? Comenta aí que respondo com prazer!