Search code examples
node.jsmiddleware

Nodejs best practice encapsulating send middleware


Ok so I am currently learning more node.js and decided to try out some basic middleware in a small api I created. I was wondering how I would wrap a successfull request. This is my approach.

Example Controller

exports.getTask = async function (req, res, next) {
    try {
        const task = await db.Task.findOne(
            {
                where: {
                    id: req.params.taskId,
                    userId: req.params.userId
                }
            });
        if (task) {
            req.locals.data = task;
            res.status(httpStatus.OK);
            next();
        }
        res.status(httpStatus.NOT_FOUND);
        next();
    } catch (err) {
        next(err);
    }
};

Middleware

exports.success = function(req, res, next) {
    const success = res.statusCode < 400;
    const successResponse = {
        timestamp: new Date().toUTCString(),
        success: success,
        status: res.statusCode
    };

    if (success) {
        successResponse.data = req.locals.data;
    }
    res.send(successResponse);
    next();
};

I dont think its very good having to set req.locals.data for every requst and then calling next res.status(status) maybe I just approached the situation the wrong way?

How could you make this better?


Solution

  • In this case, probably using the express middleware concept (calling next()) will be an overkill.

    I'd approach this by creating an abstraction for the success path. Consider something like this:

    const resWithSuccess = (req, res, data) => {
        res.json({
          data: data,
          timestamp: new Date().toUTCString(),
          // success: res.statusCode < 400, // --> actually you don't need this,
          //                                       since it will always be true
          // status: res.statusCode // --> or whatever else "meta" info you need
        });
    };
    

    Then, as soon as you need to respond with success, go for it:

    exports.getTask = async function (req, res, next) {
        // .... bla bla
        if (task) {
            resWithSuccess(tank);
        }
    };
    

    PS: ... and you can use the express middleware concept (calling next()) for the error path.