Next.js API routes → Postman
In Next.js the folder structure is the router, which makes it hard to see every endpoint at a glance. routeman-cli walks app/ and pages/api/ the way Next.js does, then reads each handler to build the request. You don't need next build.
$ npx routeman-cli
What routeman-cli reads from a Next.js app
- App Router: every
route.ts/route.jsand its exportedGET,POST,PUT,PATCHandDELETEhandlers. Route groups such as(marketing)are dropped from the URL, and[slug]and catch-all segments become path variables. - Pages Router:
pages/api/**, including handlers that switch onreq.method, plusnext-connect. - Bodies: zod or valibot schemas applied to
await request.json(), destructuredrequest.json(), andrequest.formData()fields (sent as form-data). - Query parameters:
request.nextUrl.searchParams.get('page')andnew URL(request.url).searchParams. - Auth: helpers that read the
Authorizationheader or verify a JWT (withjoseorjsonwebtoken), followed through@/lib/...imports via tsconfigpaths. - basePath from
next.config.jsis added to every URL.
Example
app/
├─ api/auth/login/route.ts
├─ api/posts/route.ts GET, POST
├─ api/posts/[slug]/route.ts GET, DELETE
├─ api/posts/[slug]/comments/route.ts POST
└─ (marketing)/api/newsletter/route.ts POST (form)
lib/auth.ts requireUser(): jwtVerify on the Bearer token
// app/api/posts/route.ts
const PostInput = z.object({
title: z.string().min(5).max(140),
content: z.string(),
status: z.enum(['draft', 'published']).default('draft'),
});
export async function GET(request: NextRequest) {
const page = Number(request.nextUrl.searchParams.get('page') ?? 1);
const tag = request.nextUrl.searchParams.get('tag');
...
}
export async function POST(request: Request) {
await requireUser(request);
const input = PostInput.parse(await request.json());
...
}
// app/(marketing)/api/newsletter/route.ts
export async function POST(request: Request) {
const form = await request.formData();
const email = form.get('email');
...
}
$ npx routeman-cli
✓ next: 7 requests (4 POST, 2 GET, 1 DELETE)
✓ auth: bearer (login: POST /api/auth/login)
✓ wrote postman/next-blog-api.postman_collection.json
✓ wrote postman/next-blog-api.local.postman_environment.json
done in 0.07s - import the files in Postman (File → Import)
$ npx routeman-cli routes
POST /api/auth/login json: email, password
POST /api/newsletter form: email
GET /api/posts
POST /api/posts 🔒 json: title, content, status
DELETE /api/posts/{slug} 🔒
GET /api/posts/{slug}
POST /api/posts/{slug}/comments 🔒 json: body, parentId
7 routes, auth: bearer (login: POST /api/auth/login)
This is real output from routeman-cli 0.1.0:
- The
(marketing)route group is gone from the URL:/api/newsletter. Its body isform-datawithemailset touser@example.com. - Only the handlers that call
requireUser()are authenticated. The GET handlers stay public. - Creating a post sends
{"title": "Sample title", "content": "Sample text", "status": "draft"}, which is valid for the zod schema. [slug]becomes{{postSlug}}in the environment, with the example valuesample-slug.- The login handler returns
{ token }, and the login script finds and stores it asaccess_token.
Nuxt, SvelteKit, Astro and Remix
The same file-routing support covers Nuxt and Nitro (server/api, [id].get.ts, readBody, getQuery), SvelteKit +server.ts, Astro API endpoints and Remix / React Router resource routes. See all frameworks.