· developers · api

API routes that feel like handlers, not framework.

File app/api/**/route.ts → GET/POST at /api/** . Typed VeskRequest/VeskResponse , cookies, headers, validation — same middleware as pages.

What you write

					
						import { VeskRequest, VeskResponse } from '@vesk/types'

export async function POST(req: VeskRequest) {
  const { name } = await req.json()
  if (!name) return VeskResponse.json({ error: "name required" }, { status: 400 })
  return VeskResponse.json({ ok: true, name })
}
					
				

No config. cookies() , headers() , locals() — same as pages.

What you get

  • Dynamic [slug] + catch-all [...rest] — same as pages.
  • Validation: withValidation(req, schema) → 422 + issuesToFieldMap .
  • Middleware onion: auth once, reused for pages + API.
  • ISR: export const revalidate = 60 .
vs other API stories
Pillar Vesk Next.js route handlers Express / Hono
Co-location Files under app/api + share middleware with pages Files under app/api (RSC split) Manual router file
Validation Built-in Zod + field map Manual (zod) per handler Middleware + lib
Auth share One middleware.ts for pages + API Duplicate per group App-level middleware
Typed errors VeskResponse.json + HttpError NextResponse untyped Manual