Zod で Validation
zod は、TypeScript 向けのスキーマ定義ライブラリで、Prisma との相性が良い。zod でスキーマを定義し、Prisma のスキーマから Zod オブジェクトを生成することで、API のパラメータの validation を行うことができる。
まずは、zod, zod-prisma-types をインストールし、prisma/schema.prisma に generator を追加する
$ yarn add zod zod-prisma-types
...
generator zod {
provider = "zod-prisma-types"
output = "../src/schemas/zod"
useMultipleFiles = true
useTypeAssertions = true
}
useTypeAssertions = true を指定しないと、エラーになる。その他各種オプションは、zod-prisma-types を参照。
npx prisma generate すると、指定したディレクトリに Zod オブジェクトがドバっとできる。こんなに必要ないのだが、欲しい物だけに絞れなかったので、全部 generate しておいた。
この zod-prisma-types を使うと、prisma/schema.prisma の 各 model にコメントをつけることで、Zod オブジェクトを細かく指定できる。例えば、最大値や最小値、エラーメッセージなどを指定できる。
Zod によるパラメータの validation は、.parse, .safeParse などがあるが、エラーが起きた時に、エラーレスポンスを返したいので、.safeParse を使う。validation するのは、
- GET
/api/users: query - POST
/api/users: request body - GET
/api/users/{id}: slug - PUT
/api/users/{id}: slug, request body - DELETE
/api/users/{id}: slug
になる。例えば、POST の場合、
import { UserCreateInputSchema, type User as RequestType } from '@/schemas/zod';
...
export async function POST(request: Request) {
const requestBody: Partial<RequestType> = await request
.json()
.catch(() => {});
const query = UserCreateInputSchema.safeParse(requestBody);
if (query.success === false) {
const { errorCode, errorObject } = handleZodError(query.error);
return NextResponse.json({ error: errorObject }, { status: errorCode });
}
...
}
こんな感じになる。relation のある requestBody は、Prisma 的 connect などしないと、エラーになる。例えば、
export function formatPostParams(params: Partial<RequestType>) {
const { authorId, ...rest } = params;
let formattedParams: any = { ...rest };
if (authorId) {
formattedParams = {
...formattedParams,
author: { connect: { id: authorId } },
};
}
return formattedParams;
}