Группа правил в Nest
Пусть правила для одного поля уже описаны, а полная схема тела ещё не собрана. Копировать те же строки в другой файл рискованно: правка в одном месте не дойдёт до второго.
Отдельный объект схемы хранит правила
одной темы. Большую схему собирают
через extend или переносят
поля из shape маленькой схемы
в новый объект. Канал на Body
получает уже итоговую схему и не
различает, из скольких частей она
сложена.
npm install zod
Покажем на примере постов:
import { BadRequestException, Injectable, PipeTransform } from '@nestjs/common';
@Injectable()
export class SchemaPipe implements PipeTransform {
constructor(private schema: { '~standard': { validate: (value: unknown) => Promise<{ value?: unknown; issues?: { message: string }[] }> | { value?: unknown; issues?: { message: string }[] } } }) {}
async transform(value: unknown) {
const result = await this.schema['~standard'].validate(value);
if (result.issues) {
throw new BadRequestException(result.issues[0].message);
}
return result.value;
}
}
Правила названия вынесем в отдельную группу и включим её в схему тела:
import { z } from 'zod';
export const titleSchema = z.object({
title: z.string(),
});
export const createPostSchema = z.object({}).extend(titleSchema.shape);
На маршруте создания передаём итоговую схему в канал и возвращаем проверенное название клиенту:
import { Body, Controller, Post } from '@nestjs/common';
import { createPostSchema } from './create-post.schema.js';
import { SchemaPipe } from './schema.pipe.js';
@Controller('posts')
export class PostController {
@Post()
createPost(@Body(new SchemaPipe(createPostSchema)) body: { title: string }) {
return body.title;
}
}
Подключим контроллер в корневом модуле:
import { Module } from '@nestjs/common';
import { PostController } from './post.controller.js';
@Module({
controllers: [PostController],
})
export class AppModule {}
Сделайте создание работника, где
правила одного поля лежат в отдельной
группе схемы и входят в схему тела,
в контроллере WorkerController
и подключите его к корневому модулю.