javascript - Next.js 14 Handler API - Validarea corespunzătoare a corpului JSON al cererii


Încerc să construiesc un API pentru o aplicație iOS la care lucrez. Folosesc Next.js 14 pentru asta și funcționează, pentru cea mai mare parte, dar sunt puțin nedumerit cum să validez corespunzător corpul unui Request. ESLint îmi aruncă tot felul de erori și avertismente și, deși aș putea să „rezolv” majoritatea dintre ele, există unul cu care sunt cu adevărat nesigur:

Atribuire nesigură a unei valori any

Acest lucru se întâmplă când spun const body=await request.json();. Nu înțeleg cum să rezolv asta. Metoda json() returnează any în acest punct, dar este imediat validată apelând validateRequest la o linie mai târziu.

Aș putea să-l transform în RequestBody: const body=await request.json() as RequestBody;, dar asta cam strică scopul, nu-i așa?

Ai vreo idee cum să gestionezi corect asta?

// app/api/route.tsx

interface RequestBody {
  name: string;
}

function validateRequest(object: any): object is RequestBody {
  return (
    (object as RequestBody) && typeof (object as RequestBody).name === "string"
  );
}

export async function POST(request: Request) {
  try {
    // Warning: Unsafe assignment of an `any` value
    const body = await request.json();

    if (!validateRequest(body)) {
      return new Response("Invalid Data", { status: 400 });
    }

    return Response.json({ message: body.name });
  } catch {
    return new Response("Bad Request", { status: 400 });
  }
}

Am urmat acest răspuns pentru validarea la runtime a datelor: https://stackoverflow.com/a/44078574/3134192

Răspuns #1

Sugerez să folosiți o bibliotecă de validare precum Zod, Yup sau Valibot. Folosind Zod, definiți schema și puteți valida corpul cu .parse sau alte metode. Puteți găsi mai multe exemple în documentația oficială.

Definiți schema dvs.:

const User = z.object({
   name: z.string()
});

Apoi poți valida corpul cu metoda parse sau safe parse:

// will throw and error if body is not valid
User.parse({ username: "Ludwig" });

// will return object with properties: {success: boolean, error: ZodError}
User.safeParse({ username: "Ludwig" });

Zod face mult mai mult, poți chiar să deduci un tip din schema ta:

// extract the inferred type
type User = z.infer<typeof User>