提问者:小点点

是否有一种优雅的方法来检查POST请求体是否与endpoint处的预期参数匹配?


我使用NodeJS(在TypeScript而不是JavaScript中)和Express实现了一个简单的服务器。 目前,在每个endpoint中,我以以下方式检查传入的请求体是否与预期的参数匹配:-

express.Router().post('/add', (req: Request, res: Response) => {
     if (!req.body.operand1 || typeof req.body.operand1 !== 'number' ||
         !req.body.operand2 || typeof req.body.operand2 !== 'number') {
          res.send('Request body is invalid');
          return;
     }

     const parameters: AddEndpointParameters = req.body;

     res.send(parameters.operand1 + parameters.operand2);
}

interface AddEndpointParameters {
     operand1: number;
     operand2: number;
}

但是如果在给定endpoint中有许多预期参数,这将变得单调乏味。 有没有更好的办法做到这一点? 例如,我可以用某种方式直接比较请求体和接口吗?

例如。

express.Router().post('/add', (req: Request, res: Response) => {
     if (!matches(req.body, AddEndpointParameters)) {
          res.send('Request body is invalid');
          return;
     }

     const parameters: AddEndpointParameters = req.body;

     res.send(parameters.operand1 + parameters.operand2);
}

interface AddEndpointParameters {
     operand1: number;
     operand2: number;
}

PS:我知道有些问题询问如何检查对象是否与JavaScript/TypeScript中的JSON/Interface/Class匹配。 但是由于某种原因,我找不到一个与这种上下文匹配的直截了当的解决方案(可能是由于我的幼稚)。 如果您能指出一个解决方案或方法,适合这种情况,我将非常高兴,以防我错过。 谢了。


共2个答案

匿名用户

这是我的例子和我的想法。 这是一个非常基本的示例,假设您在规则中定义的所有内容都必须存在于主体中:

const AddEndpointRules = {
    operand1: 'number',
    operand2: 'number'
};

express.Router().post('/add', (req: Request, res: Response) => {
    // --- Changed
    if (!matches(req.body, AddEndpointRules)) {
        res.send('Request body is invalid');
        return;
    }
    // ---

    const parameters: AddEndpointParameters = req.body;

    res.send(parameters.operand1 + parameters.operand2);
}

function matches(body, rules) {
    // All keys of rules must be present, so we use that to check our body
    for (let attribute in rules) {
        // The type of value must be same as our rule
        // Not present would mean 'undefined'
        if (typeof body[attribute] !== rules[attribute]) {
            // We invalidate body as soon as we find our first invalid attribute
            return false;
        }
    }

    // All checked out, request body is OK
    return true;
}

您还可以将matches函数放在自己的类中,并在请求之上要求/导入它,并使用它,例如:validator.validate()(将其重命名为validate)。 这样,您还可以更多地扩展逻辑,检查长度和/或在对象中更深入地检查。

匿名用户

您正在寻找的是模式。 它是一种定义json对象应该是什么样子或格式化为什么样子的方法,然后使用它与发送到API的主体进行比较。 我会调查这件事的。

https://www.npmjs.com/package/jsonschema