Search code examples
node.jsexpressaws-lambdaserverless

How do I get my parameters to pass from serverless to my express router?


I am working with AWS Lambda using express/nodejs and serverless

However, serverless (serverless offline) is matching the full path of my URL and can handle parameters. This then gets passed on to my handler which uses express to resolve the paths. However, the express router is no longer receiving the full path - the parameters matched are being dropped.

I have the following configuration in my .yml file:

functions:
     api:
       handler: lambda.universal
       events:
         - httpApi:
            method: '*'
            path: /api
         - httpApi:
            method: '*'
            path: /api/{params}

This is the handler:

export const universal = (event: APIGatewayProxyEvent, context: Context) =>
{
    awsServerlessExpress.proxy(server, event, context);
}

Which goes to this router (I removed some things for brevity):

 router.get("/:param", async (req: Request, res: Response) => {

 
      console.log("get with param hit");
      const response = getNode(); // defined elsewhere

      res.status(200).send(response);

  });


 router.get("/", async (req: Request, res: Response) => {

 
      console.log("get hit (no param)");
      const response = getNode(); // defined elsewhere

      res.status(200).send(response);

  });

When I run a call to either URL (i.e. localhost:3000/api/, or localhost:3000/api/parameter-here), it still hits the second of those routes and prints "get hit (no param)". I've also looked at the arguments the router receives (req and res) and it doesn't contain the full path. req.path is always just '/', req.paramas is always {}, req.route contains stuff but not useful, and req.url is just '/'.

Is there a way I can have the {params} received by serverless passed into the routes of my routers?

Thanks!


Solution

  • So, answering my own question:

    The literal answer to my question is that I needed to include the middleware before defining my routes:

    // 3.x
    const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware')
    router.use(awsServerlessExpressMiddleware.eventContext())
    router.get('/', (req, res) => {
      res.json({
        stage: req.apiGateway.event.requestContext.stage
      })
    })
    

    However, the better answer was to update to v4 which handles this in a better way. I followed the instructions at the first of these two URLs to upgraded it (but 2 URLs included in case one goes dead! The second also has more info.

    https://github.com/vendia/serverless-express/blob/mainline/UPGRADE.md https://www.npmjs.com/package/@vendia/serverless-express