Executando verificação de segurança...
8

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 ErroStatusAção Padrão
BadRequestError400Verifique os dados da requisição.
UnauthorizedError401Envie credenciais de autenticação válidas.
ForbiddenError403Verifique se tem permissão para acessar.
NotFoundError404Verifique o identificador do recurso.
MethodNotAllowedError405Use um método HTTP suportado.
ConflictError409Resolva conflitos antes de reenviar.
UnprocessableEntityError422Verifique os dados enviados.
TooManyRequestsError429Reduza a frequência de requisições.
InternalError500Tente novamente ou contate o suporte.

✅ Conclusão

  • ✅ Crie rotas com .get(), .post() etc. e exporte com expose(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!

Carregando publicação patrocinada...
2

Ezequias, extrapolando o escopo inicial do projeto, você pensa em oferecer um recurso semelhante para Server Actions e até mesmo para Server Components?

Achei a API da sua biblioteca bem interessante, e seria legal ver algo que também servisse para Server Actions e Server Components, contemplando todas as formas de servir requisições de clientes.

Mais uma vez, parabéns pelo projeto, e muito obrigado por compartilhar.

1

Cara, primeiramente obrigado pela sugestão. 👍
Eu realmente não tinha pensado nesse recurso antes, eu gostei bastante dessa ideia. Realmente pode ser aplicável.

Gostaria de saber como você imagina que seria o fluxo desse recurso em uma aplicação em Next? Você imagina essa funcionalidade mais voltada para middlewares ou outra questão?

Estou ansioso pela sua resposta, realmente achei muito interessante! 🚀

1
1