【问题标题】:Is it necessary to use multiple Joi schema validations with Hapi?是否有必要对 Hapi 使用多个 Joi 模式验证?
【发布时间】:2021-06-13 00:13:59
【问题描述】:

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

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 经验的人都可以验证使用单个架构对象(在本例中为 StudentSchema)的优缺点,还是我应该继续使用两种架构的当前范例?

【问题讨论】:

    标签: javascript node.js mongodb hapijs joi


    【解决方案1】:

    我认为这种设计模式是更好的做法,在部分更新时,您应该有一个合适的模式来更好地表示传入的对象。但是,您可以通过使用 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);
    

    这样您就拥有了一个完整的架构,可以保护您,同时还允许部分字段更新。

    【讨论】:

    • 感谢 Tom,但使用 const updateSchema = createSchema.optionalKeys("gender", "grade", "_id"); 会导致错误
    • 尝试了您的建议,但它返回 502 服务器错误,表明此方法存在错误。将代码恢复到现状是可行的,但必须有一种方法可以避免两种模式模式。
    • 只需从架构中删除“必需”,因为这可能会触发错误,我个人不建议这样做,但这是您的决定。
    猜你喜欢
    • 2020-09-19
    • 2018-09-24
    • 2019-10-10
    • 2013-10-19
    • 1970-01-01
    • 2016-02-19
    • 2017-10-02
    • 2020-05-30
    • 2018-05-25
    相关资源
    最近更新 更多