Search code examples
node.jsexpressaws-lambdamiddleware

Will a Lambda function using Express reload it's middleware for each request?


TLDR: Will the middleware that gets called by app.use be recalculated for each individual request in Express?

I have a Lambda function that uses the following function as its middleware to inject the user into every request:

async function(req, res, next) {
  try {
    const IDP_REGEX = /.*\/.*,(.*)\/(.*):CognitoSignIn:(.*)/;
    const authProvider =
      req.apiGateway.event.requestContext.identity
        .cognitoAuthenticationProvider;
    const [, , , userId] = authProvider.match(IDP_REGEX);

    const cognito = new AWS.CognitoIdentityServiceProvider();
    const listUsersResponse = await cognito
      .listUsers({
        UserPoolId: process.env.AUTH_SAYM_USERPOOLID,
        Filter: `sub = "${userId}"`,
        Limit: 1,
      })
      .promise();
    const user = listUsersResponse.Users[0];
    req.user = user;
    next();
  } catch (error) {
    console.log(error);
    next(error);
  }
}

My question is: Will this middleware run once for each individual user? Or will this code run only every time the Lambda function "goes to sleep"? What I mean is, will there be a bug, if the Lambda function gets pinged often and never goes idle again that each request will have the user who made the first request? Or does the middleware calculate for each individual request?


Solution

  • This middleware will run upon every request and this has nothing to do with Lambda. Once the requests reaches your Express-based Lambda function, it's just going to act as a regular Express server.

    The middleware's responsibility is to intercept every HTTP call, regardless of where it's running.

    The only thing I see here is to move the declaration of const cognito = new AWS.CognitoIdentityServiceProvider(); out of your middleware's scope, so the instance of this object is cached for as long as the container lives. You will gain a couple of microseconds by doing so (which may be irrelevant, but is indeed a good practice).

    You have to keep in mind though that since modules in Node.js are singletons, anything required/declared in "global" scopes (outside a given function, for example) is going to be re-used in future invocations to the same running container. Use this in your favour but also be careful with unintentionally caching things you don't want to.