节点 ExpressJS |如何通过自定义查询参数验证

Posted

技术标签:

【中文标题】节点 ExpressJS |如何通过自定义查询参数验证【英文标题】:Node ExpressJS | How to pass custom query params validation 【发布时间】:2019-07-29 15:57:33 【问题描述】:

在这里学习 ExpressJS。 我有一个 get 路由,它需要查询参数,即


app.get('/api', (req, res) => 
  res.send( name: req.query.name, age: req.query.age, club: req.query.club )
)

在邮递员下面http://localhost:5000/api?name=Messi&age=31&club=Barcelona

返回 200,res.body 为:


    "name": "Messi",
    "age": "31",
    "club": "Barcelona"


问题

我如何在哪里编写自定义验证:

如果请求的查询参数不存在:状态 400 如果缺少任何参数,即(姓名、年龄、俱乐部),则返回一个响应,说明需要任何缺少的参数(姓名、年龄和/或年龄)

【问题讨论】:

【参考方案1】:

上述答案是正确,但作为使用过可扩展和可维护 API 的人,我建议使用 JSON Schemas 标准化您的 API 验证过程以定义预期输入,并且AJV 来验证这些架构。

示例用法:

const Ajv = require('ajv');
const express = require('express');

const app = express();

app.get('/api', (req, res) => 

    // define precisely the expected shape of the request
    const schema = 
        type: 'object',
        properties: 
            name:  type: 'string' ,
            age:  type: 'string' ,
            club:  type: 'string' 
        ,
        required: ['name', 'age', 'club']
    

    // validate the request
    const ajv = new Ajv();
    const valid = ajv.validate(schema, req.query);
    if(!valid) res.status(400).send(ajv.errors);

    // request is valid. Do whatever
    res.send(req.query);

)

app.listen(8080, () => console.log('Server listening on port 8080'));

回复/api

[
    
        "keyword": "required",
        "dataPath": "",
        "schemaPath": "#/required",
        "params": 
            "missingProperty": "name"
        ,
        "message": "should have required property 'name'"
    
]

回复/api?name=messi&age=10&club=barcelona


    "name": "messi",
    "age": "10",
    "club": "barcelona"

是的,这需要更多的代码,但相信我,如果您想为复杂且可扩展的 API 验证做好准备,这是您的必经之路。

【讨论】:

绝对好答案!你以前用过Joi吗? 谢谢!是的,我做到了。 Joi 的默认设置是它的模式仅在 JS 层中定义。使用 AJV 和其他 JSON 验证器,您可以在 JSON 文件中定义模式并将它们导入脚本中,这在可维护性方面有很大的优势。 此外,Joi 有自己定义结构的方式,而 JSON Schemas 是许多库和实体共享的标准。基于 JSON 的结构定义的副作用、更多文档和更少错误。 这是有道理的。我现在正在研究 AJV。 我们如何将 AJV 模式验证保存在 validateInput() 助手中,以便在针对 DRY 方法时可以跨多个 http 动词请求重用?【参考方案2】:

您可以构建一个简单的验证中间件。

function validateQuery(fields) 

    return (req, res, next) => 

        for(const field of fields) 
            if(!req.query[field])  // Field isn't present, end request
                return res
                    .status(400)
                    .send(`$field is missing`);
            
        

        next(); // All fields are present, proceed

    ;



app.get('/api', validateQuery(['name', 'age', 'club']), (req, res) => 
  // If it reaches here, you can be sure that all the fields are not empty.
  res.send( name: req.query.name, age: req.query.age, club: req.query.club )
)

您还可以使用第三方模块来验证请求。

Express Validator Express Superstruct(我是作者

【讨论】:

幻想曲。非常感谢马科斯! 我一定也会去看看你的图书馆! ?【参考方案3】:

你需要检查每个参数值的值

If(typeof req.query.name == 'undefined' )
  res.status(400).send('name is missing') 

检查每个值

【讨论】:

我建议在res.status...之前使用return @NullisTrue 我正在写一个答案,给我几分钟。

以上是关于节点 ExpressJS |如何通过自定义查询参数验证的主要内容,如果未能解决你的问题,请参考以下文章

查询通过 prometheus 节点导出器文本文件收集器公开的自定义指标失败

如何在GraphQL中添加自定义查询?

如何使用 Strapi 在 GraphQL 中添加自定义查询?

如何在 Django 管理自定义列中获取请求参数?

使用expressjs路由的firebase函数获取未定义的参数

ExpressJS 节点 HTTPS 服务器上的 Heroku 错误 H13