Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an elegant way to check if the POST request body matches the expected parameters at the endpoint? [duplicate]

I implemented a simple server in NodeJS using TypeScript and ExpressJS. At present, in each endpoint, I check if the incoming request body matches the expected parameters in the following way: -

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 = req.body;

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

But this would get tedious if there are many expected parameters in a given endpoint. What is the best way to achieve this?

EDIT

I edited this question because, before I had included some interfaces and the question looked similar to Detect whether object implement interface in TypeScript dynamically, which (understandably) confused people, while the scenario was different from that. There, the asker wanted to know if an object implements an interface. Here, I want to see if the body in a post request is the expected one.

like image 990
Jayaraj P Avatar asked Oct 26 '25 10:10

Jayaraj P


2 Answers

So here is my example and what I had in mind. Its a very basic example and goes under the assumption that everything you define in your rules MUST be present in the body:

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;
}

You can also place the matches function in a class of its own and require/import it above your request and use it like for example: Validator.validate() (rename it to validate). That way you can also extend the logic some more and check for length and/or check deeper in the object.

like image 189
svenbravo7 Avatar answered Oct 28 '25 23:10

svenbravo7


What you are looking for is called a schema. It's a way to define what a json object should look like or be formatted as and then use that to compare against the body that is being sent to the API. I would look into this.

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

like image 41
Jeymz Avatar answered Oct 29 '25 00:10

Jeymz