next-safe-route
1
总安装量
1
周安装量
#42812
全站排名
安装命令
npx skills add https://github.com/mhbdev/next-safe-route --skill next-safe-route
Agent 安装分布
amp
1
opencode
1
kimi-cli
1
codex
1
github-copilot
1
gemini-cli
1
Skill 文档
@mhbdev/next-safe-route
Use this skill to generate correct route-handler code that uses this package idiomatically.
Capabilities
- Build route handlers with
createSafeRoute()and chained.params(),.query(),.body(),.use(),.handler(). - Preserve strong typing in
context.params,context.query,context.body, andcontext.data. - Configure validation adapters:
- Default: zod via main package import
- Optional: valibot via
@mhbdev/next-safe-route/valibot - Optional: yup via
@mhbdev/next-safe-route/yup
- Customize failures with:
validationErrorHandlerfor schema errorshandleServerErrorfor unexpected exceptions
Required Inputs
Collect these before generating code:
- HTTP method and route path.
- Validation library (
zod,valibot, oryup). - Expected schema for
params,query, andbody. - Desired validation/server error response shape.
- Middleware-derived context fields needed in
context.data.
Decision Table
| Need | Use |
|---|---|
| Only zod is required | createSafeRoute() with default adapter |
| valibot schemas | createSafeRoute({ validationAdapter: valibotAdapter() }) |
| yup schemas | createSafeRoute({ validationAdapter: yupAdapter() }) |
| Custom schema error payload/status | validationErrorHandler |
| Custom unexpected-error payload/status | handleServerError |
| Auth or request-derived shared data | .use(async (request) => ({ ... })) |
Workflow
- Define schemas for
params,query, and/orbody. - Create builder with
createSafeRoute(...). - Chain
.params(),.query(),.body()only for inputs that should be validated. - Add
.use()middleware for typed context enrichment. - Implement
.handler((request, context) => Response). - Return explicit
Response/Response.json(...).
Middleware Writing Notes
- Write middleware as
.use(async (request) => ({ ...contextFields })). - Return
Responsefrom middleware to short-circuit the chain (for auth failures or early exits). - Return plain serializable objects for context fields; avoid relying on prototype methods.
- Assume merge order is left-to-right:
- Later middleware keys override earlier middleware keys.
- Middleware fields are available in
context.dataonly.
- Keep middleware focused on cross-cutting concerns:
- Authentication and authorization
- Tenant and organization resolution
- Correlation/request IDs
- Feature flags
- Avoid consuming request body in middleware when route body validation is used, because request streams are single-read.
- Keep middleware deterministic and side-effect-light; prefer throwing only for truly exceptional failures and use
Responsefor expected denials.
Middleware Pattern
import { createSafeRoute } from '@mhbdev/next-safe-route';
export const GET = createSafeRoute()
.use(async (request) => {
const auth = request.headers.get('authorization');
if (!auth) {
return Response.json({ message: 'Unauthorized' }, { status: 401 });
}
const user = await resolveUserFromAuth(auth);
if (!user) {
return Response.json({ message: 'Forbidden' }, { status: 403 });
}
return { user };
})
.use(async () => ({ requestId: crypto.randomUUID() }))
.handler((request, context) => {
return Response.json({
requestId: context.data.requestId,
userId: context.data.user.id,
});
});
Behavioral Contract
- Validation order is
params->query->body. - Default validation errors: HTTP
400, JSON body withmessageandissues. - Default unhandled errors: HTTP
500, JSON{ "message": "Internal server error" }. - If
.body()is configured, accepted content types are:application/jsonmultipart/form-dataapplication/x-www-form-urlencoded
- For repeated query/body form keys, output arrays; single keys output scalars.
- Supports Next.js 16 async params (
context.paramsmay be a Promise).
Constraints and Gotchas
- Use for App Router Route Handlers; do not generate Pages Router
NextApiRequest/NextApiResponsepatterns with this package. - If no
.body()schema is provided, do not rely on parsed request body in handler logic. - Optional adapters (
valibot,yup) require those packages installed in the consumer project.
Reference Patterns
Zod default
import { createSafeRoute } from '@mhbdev/next-safe-route';
import { z } from 'zod';
export const POST = createSafeRoute()
.params(z.object({ id: z.uuid() }))
.query(z.object({ search: z.string().optional() }))
.body(z.object({ title: z.string().min(1) }))
.handler((request, context) => {
return Response.json({
id: context.params.id,
search: context.query.search,
title: context.body.title,
});
});
Valibot adapter
import { createSafeRoute } from '@mhbdev/next-safe-route';
import { valibotAdapter } from '@mhbdev/next-safe-route/valibot';
import { object, string } from 'valibot';
export const GET = createSafeRoute({
validationAdapter: valibotAdapter(),
})
.query(object({ q: string() }))
.handler((request, context) => Response.json({ q: context.query.q }));