Treat every API endpoint as a contract:
Example (pagination with schema validation):
export async function GET(request: Request) {
const url = new URL(request.url);
const offsetLimitRaw = {
offset: url.searchParams.get("offset"),
limit: url.searchParams.get("limit"),
};
// paginationSchema: offset int >= 0, limit int within an agreed range
const validation = validateBody(paginationSchema, offsetLimitRaw);
if (isValidationFailure(validation)) {
return NextResponse.json({ error: validation.error }, { status: 400 });
}
const { offset, limit } = validation.data;
const all = await getCombos();
const combos = all.slice(offset, offset + limit);
return NextResponse.json({ combos });
}
Team standard: no manual parseInt/fallback defaults for externally supplied API parameters; any transformation layer must preserve/emit the documented output shape.
Enter the URL of a public GitHub repository