Claude-skill-registry api-validation
Apply when validating API request inputs: body, query params, path params, and headers. This skill covers Zod v4 patterns.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/api-validation" ~/.claude/skills/majiayu000-claude-skill-registry-api-validation && rm -rf "$T"
manifest:
skills/data/api-validation/SKILL.mdsource content
When to Use
Apply when validating API request inputs: body, query params, path params, and headers. This skill covers Zod v4 patterns.
Patterns
Pattern 1: Zod Schema Validation (v4)
// Source: https://zod.dev/ import { z } from 'zod'; const CreateUserSchema = z.object({ email: z.string().email('Invalid email'), password: z.string().min(8, 'Min 8 characters'), name: z.string().min(1, 'Name required').max(100), role: z.enum(['user', 'admin']).default('user'), }); type CreateUserDto = z.infer<typeof CreateUserSchema>;
Pattern 2: Request Handler with Validation
// Source: https://zod.dev/ export async function POST(request: NextRequest) { const body = await request.json(); const result = CreateUserSchema.safeParse(body); if (!result.success) { return NextResponse.json({ error: { code: 'VALIDATION_ERROR', message: 'Invalid request body', details: result.error.issues.map(issue => ({ field: issue.path.join('.'), message: issue.message, })), }, }, { status: 400 }); } // result.data is fully typed const user = await createUser(result.data); return NextResponse.json(user, { status: 201 }); }
Pattern 3: Query Params Validation
// Source: https://zod.dev/ const ListQuerySchema = z.object({ page: z.coerce.number().int().positive().default(1), limit: z.coerce.number().int().min(1).max(100).default(20), sort: z.enum(['asc', 'desc']).default('desc'), search: z.string().optional(), }); export async function GET(request: NextRequest) { const params = Object.fromEntries(request.nextUrl.searchParams); const result = ListQuerySchema.safeParse(params); if (!result.success) { return NextResponse.json({ error: 'Invalid query params' }, { status: 400 }); } const { page, limit, sort, search } = result.data; // ... }
Pattern 4: Reusable Validators (Zod v4)
// Source: https://zod.dev/ // Common field schemas - Zod v4 format validators const EmailSchema = z.string().email(); const UUIDSchema = z.string().uuid(); const DateStringSchema = z.string().datetime(); const PaginationSchema = z.object({ page: z.coerce.number().int().positive().default(1), limit: z.coerce.number().int().min(1).max(100).default(20), }); // Compose schemas const GetUserSchema = z.object({ params: z.object({ id: UUIDSchema }), }); const ListUsersSchema = z.object({ query: PaginationSchema.extend({ status: z.enum(['active', 'inactive']).optional(), }), });
Pattern 5: Validation Middleware
// Source: Best practice pattern function validate<T extends z.ZodSchema>(schema: T) { return async (req: Request, res: Response, next: NextFunction) => { const result = schema.safeParse({ body: req.body, query: req.query, params: req.params, }); if (!result.success) { return res.status(400).json({ error: { code: 'VALIDATION_ERROR', details: result.error.issues, }, }); } req.validated = result.data; next(); }; } // Usage app.post('/users', validate(CreateUserSchema), createUserHandler);
Zod v4 Migration Notes
Breaking Changes from v3:
- String format validators:
patterns still work in v4z.string().email() - Error messages: More descriptive (e.g., "Invalid input: expected string, received undefined")
behavior: Now identical to.nonempty()
, inferred type is.min(1)
notstring[][string, ...string[]]- Error API:
is nowerror.errors
(both work in v4 for compatibility)error.issues
Recommendation: The patterns in this skill use v4-compatible syntax that works in both v3 and v4.
Anti-Patterns
- No validation - Always validate external input
- Client-only validation - Server must validate too
- Trusting type assertions - Use runtime validation
- Vague error messages - Tell user what's wrong
Verification Checklist
- All endpoints validate input
- Schemas use Zod for runtime + types
- Error response includes field-level details
- Query params coerced to correct types
- Default values for optional fields