Search code examples
javascriptnode.jsexpressrestmiddleware

Handling multiple parameters in app.param()


I’m working on an API in Express.js and trying to implement an app.param() function that handles the id parameter in a GET request:

app.param('id', (req, res, next, id) => {
    const envelopeIndex = Number(id);
    const envelopeId = envelopes.findIndex(envelope => envelope.id === envelopeIndex);
    if (envelopeId === -1) {
        res.status(400).send("Error: No envelope found with this ID");
    }
    req.id = envelopeId;
    next();
});

For another POST request handler that transfers some amount from one envelope to another (through their IDs), I also want to validate two route parameters that are both IDs (/envelopes/:from/:to/).

My questions:

  1. Can I refactor the middleware above so that it handles multiple parameters and I don’t have to repeat myself?
  2. If so, is there a way I can dynamically assign to the request object the validated ID (e.g. if I am validating ID of 'from', it assigns req.senderId the validated ID, etc.)

I tried:

  • Repeating the middleware three times (once per route parameter)

Solution

  • req.id = envelopeId; Be careful poluting the req object with custom fields, it could effect other middlewares, the params are already on the req object anyway, req.params.id.

    By avoiding the above, it also makes your problem a little easier to handle.

    You could just create 2 named params that point to the same function.

    eg.

    const handleId = (req, res, next, id) => {
        const envelopeIndex = Number(id);
        const envelopeId = envelopes.findIndex(envelope => envelope.id === envelopeIndex);
        if (envelopeId === -1) {
            res.status(400).send("Error: No envelope found with this ID");
        }
        next();
    }); 
    
    app.param('id', handleId);
    app.param('id_to', handleId);
    

    Your POST route could then just be ->

    app.post('/envelopes/:id/:id_to/', (req, res) => {
      console.log(req.params.id);
      console.log(req.params.id_to);
      res.end('ok');
    })