Hapijs和Joi:用存在validation查询参数:'禁止'
我的目标是为post创build索引路线。 用户应该能够指定一些查询参数(即标签,types),但不应该能够指定其他。 澄清:
这是好的:
/posts /posts?tags=food /posts?type=regular&tags=stackoverflow
这不好:
/posts?title=Hello
这是hapi包configuration:
servers: [ { host: 'localhost', port: 3000, options: { labels: ["api"], validation: { abortEarly: false, presence: 'forbidden' } } } ],
请注意presence: forbidden
选项。
这是路由configuration:
handler: function (request, reply) { Post.find(request.query, function (err, posts) { if(err) { console.log(err); } reply(posts); }); }, validate: { query: { type: Joi.string().optional(), tags: Joi.string().optional() } }
我的想法是validation应该允许任何type
和tags
参数的子集(包括空查询)。 但是,在做出任何允许的请求后,我收到以下错误:
{ "statusCode": 400, "error": "Bad Request", "message": "value is not allowed", "validation": { "source": "query", "keys": [ "value" ] } }
这是为什么? 当然没有关键的value
。 如何使validation按照我想要的方式运行?
如果您定义了一个非types的模式对象,Joi将其内部转换为object()
types。 所以这个模式:
var schema = { type: Joi.string().optional(), tags: Joi.string().optional() };
变为:
var schema = Joi.object().keys({ type: Joi.string().optional(), tags: Joi.string().optional() });
因为您在服务器设置中将presence
设置为forbidden
,所以将其应用于对象types,因此该模式变为:
var schema = Joi.object().forbidden().keys({ type: Joi.string().optional(), tags: Joi.string().optional() });
正如你所看到的,它将主对象标记为被禁止,除了undefined
之外,将不允许任何值:
var Joi = require('joi'); var schema = Joi.object().forbidden().keys({ type: Joi.string().optional(), tags: Joi.string().optional() }); var value = {}; Joi.validate(value, schema, { presence: 'forbidden' }, function (err, value) { console.log(err); });
它输出:
{ [ValidationError: value is not allowed] name: 'ValidationError', details: [ { message: 'value is not allowed', path: 'value', type: 'any.unknown' } ], _object: {}, annotate: [Function] }
所以你需要做的是标记主要的对象要么或optional
覆盖forbidden
:
validate: { query: Joi.object().required().keys({ type: Joi.string().optional(), tags: Joi.string().optional() }) }