Hapi 是否需要使用多个 Joi 模式验证?

Is it necessary to use multiple Joi schema validations with Hapi?

我查看了一个现有的代码库,我注意到该代码库有两个模式验证,我认为单个模式可以验证,因为第二个模式是第一个模式的分支。 请参阅下面的代码库。

export const StudentSchema = Joi.object().keys({
    _id,
    name,
    dob,
    gender,
    grade
});

export const StudentUpdateSchema = Joi.object().keys({
    name,
    dob,
})

现在这些模式正在以下路线中使用:

//CREATE ROUTE
{
    method: 'POST',
    path: '/students/{id}',
    handler: async (request) => {
        const { id } = request.params;
        return Student.create(id, request.payload);
    },
    options: {
        ...sharedOptions,
        description: 'Enrolling a student',
        validate: {
            failAction,
            payload: StudentSchema,
            params: {
                studentId: Joi.objectId().required()
            },
        },
        response: {
            status: {
                200: StudentSchema,
                400: Joi.any(),
            },
        },
    },
},
// UPDATE ROUTE
{
        method: 'PUT',
        path: '/students/{id}',
        handler: async (request) => {
            const { id } = request.params;
            return Student.update(Id, { $set: request.payload });
        },
        options: {
            ...sharedOptions,
            description: 'Update student details',
            validate: {
                failAction,
                payload: StudentUpdateSchema,
                params: {
                    studentId: Joi.objectId().required(),
                },
            },
            response: {
                status: {
                    200: StudentSchema,
                    400: Joi.any(),
                    404: Joi.any(),
                },
            },
        },
    }

我是 Hapi 的新手,但对 Express 和 Mongoose 有一些经验,我倾向于重写这些验证以仅在 'POST' 和 'PUT' 方法中使用 StudentSchema,因为StudentSchema 包含处理创建和更新功能所需的所有内容。

任何有 HapiJS 经验的人都可以验证 pros/cons 使用单个模式对象(在本例中为 StudentSchema)还是我应该继续使用两个模式的当前范例?

我认为这种设计模式是更好的做法,在部分更新中,您应该有一个合适的模式来更好地表示传入的对象。但是,您可以通过使用 optionalKeys.

扩展第一个模式来避免这两个模式,同时保留其背后的概念
const createSchema = Joi.object().keys({
    _id:  Joi.objectId(),
    name: Joi.string().required(),
    dob: Joi.string().required(),
    gender: Joi.string().required(),
    grade: Joi.number().required()
});

const updateSchema = createSchema.optionalKeys("gender", "grade", "_id");

Joi.validate({name: "this fails"}, createSchema); // error: required fields missing
Joi.validate({name: "this works"}, updateSchema);

这样你就有了一个完整的模式来保护你,同时也允许部分字段更新。