Next.js + サーバーサイドTypeScript + 関数フレーバーでクリーンなアプリを作ったので実装意図とか書く Advent Calendar 2022
の10日目。株式会社mofmofに生息しているshwldです。
前日はエンティティの状態遷移について書きました
エンティティのバリデーション
入力データの検証はzodを使います。
export const validationSchema = z
.object({
...AccountValidator.validators,
createdById: genericValidator.id,
})
.strict();
/domain/core/src/models/account/mutations/build-account.ts#L27-L32
zodのschemaはそのまま活用できるようにexportしています。
以下のように、Result型
(このカレンダー内の別記事参照)を利用するためのヘルパーを作っており、zodのschemaを渡すことで機能します。
export const validateWith =
<TOutput, TDef extends ZodTypeDef, TInput = TOutput>(
schema: ZodSchema<TOutput, TDef, TInput>
) =>
(input: TInput): Result<InvalidAttributesError, TOutput> => {
const parsedInput = schema.safeParse(input);
return toResult(
!parsedInput.success
? Either.left(InvalidAttributesError.from(parsedInput.error))
: Either.right(parsedInput.data)
);
};
/domain/core/src/shared/validator.ts#L24-L36
このヘルパーは、zod schemaを受け取り、バリデーションメソッドを返します。
バリデーションメソッドは入力を検証しResult型を返します。
また、バリデーションの結果、型が変わる場合それが戻り値に反映もされます。
const validate = validateWith(validationSchema)
const result = validate(input)
// result is Result<InvalidAttributesError, ValidAttributes>
実際にこういうふうに使っています。
export const build = (
input: Account_BuildInput
): Result<InvalidAttributesError, Account_BuiltAttributes> => {
return pipe(
{
...input,
createdAt: new Date(),
updatedAt: new Date(),
},
validateWith(validationSchema),
map(v => ({
...v,
__state: STATE_IS_BUILT,
}))
);
};
次回予告
明日はリポジトリ層について書きます。