node.js - NestJS - 根據某個屬性有條件地驗證請求主體
我正在嘗試找到一種使用 DTO 驗證 body 的好方法(使用出色的 class-validator 和 class-transformer 庫)。它運作得非常好,即使是對於巢狀結構也很有效,但在我的情況下,我希望根據某些條件來設置 body 屬性。
可能有助於理解的範例:
讓我們假設我的身體應該總是有 selectedCategory。根據該欄位,內容可以來自類別 1,該類別包含 prop1,或者來自類別 2,該類別包含 prop2。
我不想允許兩者都為空,我真的希望根據 selectedCategory 必須要麼定義 prop1,要麼定義 prop2。
我認為我可以使用一個管道,但那麼我該如何指定要使用的正確 DTO 呢?
我建立了一個包含所有常用屬性的「基底」類別,並有幾個其他類別繼承自它。
我可以根據屬性 selectedCategory 手動實例化這個管道,那將是理想的,但我完全不知道作為管道的第二個參數(metadata)該傳入什麼。
感謝你的幫助。
答案#1
你有嘗試過使用群組嗎?與其擁有多個 DTO,不如只建立一個 DTO。每個屬性都會被分配到一個或多個群組:
@Min(12, {groups: ['registration', 'update']})
age: number;
@Length(2, 20, {groups: ['registration']})
name: string;
然後你可以有條件地將這些群組傳遞給類轉換器/驗證器:
@Injectable()
export class ConditionalValidationPipe implements PipeTransform {
async transform(entity: any, metadata: ArgumentMetadata) {
// Dynamically determine the groups
const groups = [];
if (entity.selectedCategory === 1) {
groups.push('registration');
}
// Transform to class with groups
const entityClass = plainToClass(EntityDto, entity, { groups })
// Validate with groups
const errors = await validate(entityClass, { groups });
if (errors.length > 0) {
throw this.createError(errors);
}
return entityClass;
}
}
答案#2
你試過使用 ValidateIf 陳述式嗎?
您可以對 props1 或 props2 進行多重驗證,並在 selectedCategory 分別為「category 1」或「category 2」時應用它們。
