【问题标题】:Joi Array ValidationJoi 数组验证
【发布时间】:2021-02-05 18:51:52
【问题描述】:

考虑一下这段代码 sn-p。我想通过 1 种或多种颜色查询“标记”...

module.exports = [
    {
        method: 'GET',
        path: '/search/markers',
        options: {
            auth,
            description: 'Get Markers',
            notes: 'Returns all marker info',
            tags: ['api', 'markers'],
            validate: {
                query: {
                    color: Joi.array().items(Joi.string().valid('Red', 'Blue')).single().allow(''),
                }
            },
            response: {
                schema: MarkersValidation.getSearchMarkers
            }
        },
        handler: SearchController.searchMarkers
    }
];

exports.searchMarkers = async (request, h) => {
    try {
        const Markers = h.models().Markers;
        const queryMarkers = Markers.query()
            .select(h.knex().raw([
                'markers.color'
            ]))
            if (request.query.color) {
                queryMarkers.andWhere(h.knex().raw(`color && '{${request.query.color}}'::text[]`));
            }
        }
    }
    catch (e) {
        //error handler
    }
}

但是,当我尝试使用 Red, Blue 应用颜色的查询参数时,我从 Postman 收到以下错误。当我应用单个颜色参数时,例如:Red,它工作正常。

错误

子“color”失败,因为[“color”的单个值失败,因为[“color”必须是[Red, Blue]]]]

网址

{{url}}/search/markers?color=Red, Blue

注意

我尝试删除 .single(),但是当我这样做时,我得到了这个错误:

child "color" 失败,因为 ["color" 必须是一个数组]

问题

我该如何解决这个问题?

假设我想要一个可用颜色列表来查询:'Green'、'Purple'、'Yellow'、'Red'、'Blue'。

如何向查询中添加 1 个或所有选项?

示例

{{url}}/search/markers?color=Red,

{{url}}/search/markers?color=Red, Blue, Yellow

这是我当前的代码,但显然不起作用,有什么想法吗?

const myColors = ['Green', 'Purple', 'Yellow', 'Red', 'Blue'];

validate: {
 query: {
  color: Joi.array().items(Joi.string().valid(myColors)).single().allow(''),
 }
}

更新 - 简化

在这张图片中,我有一个带有“.valid()”的数组并且验证失败。

在这张图片中,我有一个没有“.valid()”的数组并且验证通过了。

我的问题

如何将“.valid()”或类似的东西添加到我的 Joi.array 中,以便只有我设置的值对此查询有效?

【问题讨论】:

  • 您使用的是express 服务器吗?
  • 我正在使用带有 Postgres 的本地 Hapi 服务器
  • 谢谢!请在您的 hapi 路线中向我展示您的 request.query 对象(使用 JSON.stringify())。我的寻找单一颜色,如:{query: { "color": "red"}} 和多种颜色 {query: { "color": "red,blue"}}。我得到一个字符串而不是数组。即使是多个值。您是否在使用其他 hapi 模块或查询解析器?请显示您的设置。我在本地环境中没有得到 color 数组
  • 我不确定您要的是什么,我想我在上面的详细信息中添加了所有内容,但以防万一...这有效:-> 颜色:Joi.array()。 items(Joi.string()).single(),但是当我添加有效时,我收到错误“子“颜色”失败,因为 [“颜色”必须是 [红色,蓝色]] 之一”:-> 颜色: Joi.array().items(Joi.string()).single().valid('Red', 'Blue'), 如果我只查询一项,则添加有效确实有效,因此:有效,这有效: {{url}}/search/markers?color=Red 有效,这不起作用,我收到上面提到的错误:{{url}}/search/markers?color=Red, Blue
  • 为了澄清,我可以简单地使用这个: color: Joi.array().items(Joi.string()).single(), {{url}}/search/markers?color=红色、蓝色、绿色 --- 但问题是当我尝试添加 .valid() 时。我的意图是您只能通过一组预定义颜色列表进行查询,但是当我添加有效时,我得到了上面的错误。颜色:Joi.array().items(Joi.string()).single().valid('Red', 'Blue', 'Green'), {{url}}/search/markers?color=Red,蓝色、绿色

标签: node.js joi


【解决方案1】:
const myColors = require('../data/colors');

const validateColors = (colors) => {
    if (!colors) {
        return true;
    }
    const colorsArray = colors.split(',');
    const colorsSchema = Joi.array().items(Joi.string().valid(myColors)).allow('')
    return Joi.validate(colorsArray, colorsSchema);
}

query: {colors: Joi.string().allow('')}

【讨论】:

    【解决方案2】:

    您必须在 URL 中将颜色查询参数作为数组传递。

    {{url}}/search/markers?color[]=Red&color[]=Blue

    验证颜色数组的 joi 模式:

    const myColors = ['Green', 'Purple', 'Yellow', 'Red', 'Blue'];
    
    joi.object().keys({
      color: joi.array().items(myColors.map(col => col)),
    });

    【讨论】:

    • 这是绝对必须的吗?如果是这样,我将如何在后端执行此操作?
    • 是的,它是必需的。还编辑了答案以包含后端 joi 架构。
    猜你喜欢
    • 2017-07-28
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 2018-09-24
    • 2018-02-03
    • 2016-10-11
    相关资源
    最近更新 更多