fastify / aws-lambda-fastify

Insipired by aws-serverless-express to work with Fastify with inject functionality.
MIT License
498 stars 32 forks source link

Use event.pathParameters.proxy instead of event.path #182

Closed hfhchan-plb closed 10 months ago

hfhchan-plb commented 10 months ago

Prerequisites

Fastify version

3.3.1

Plugin version

No response

Node.js version

18.x

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

13.5

Description

While migrating from serverless-express, I noticed that paths are being processed differently by aws-lambda-fastify. It seems that serverless-express will use event.pathParameters.proxy instead of event.path, which means if on API Gateway I have it configured 'v2/{proxy+}' and I am accessing /v2/token, it will call the express router with the path /token instead of /v2/token.

I wonder if an additional flag can be added to replicate that behaviour?

Steps to Reproduce

I'm using this with NestJS:

      const expressApp = express();
      const adapter = new ExpressAdapter(expressApp);
      await initApp(adapter, appModule);
      const server = configure({
        app: expressApp,
        binarySettings: { contentTypes: ['application/pdf', 'application/x-gzip'] },
      });
      return server;

vs

      const adapter = new FastifyAdapter();
      await initApp(adapter, appModule);
      const server = awsLambdaFastify(adapter.getInstance() as FastifyInstance, {
        binaryMimeTypes: ['application/pdf', 'application/x-gzip'],
        decorateRequest: true,
      });
      return server;

and NestJS with express gives me req.route.path = '/token' while NestJS with fastify gives me req.routerPath = '/v2/token'.

Expected Behavior

Matching serverless-express or providing a flag to toggle that behaviour.

hfhchan-plb commented 10 months ago

Looks like that behaviour was added to serverless-express in 2021: https://github.com/vendia/serverless-express/issues/86

adrai commented 10 months ago

How does the configured route look in your code? similar to https://github.com/fastify/aws-lambda-fastify/blob/master/test/basic.test.js#L23 ? Can you create a PR with a failing test?

adrai commented 10 months ago

I did not test it, but it might be it would work by changing this line like this:

- let url = event.path || event.rawPath || '/' // seen rawPath for HTTP-API
+ let url = (event.pathParameters && event.pathParameters.proxy && `/${event.pathParameters.proxy}`) || event.path || event.rawPath || '/' // seen rawPath for HTTP-API

Can you test this?

hfhchan-plb commented 10 months ago

Yes that works, but I'm not sure how it should interact with retainStage.

adrai commented 10 months ago

Can you please provide a new test case based on your example? How does your event look like?

adrai commented 10 months ago

Just released v3.4.1 that should work.

pass the pathParameterUsedAsPath option like this:

      const adapter = new FastifyAdapter();
      await initApp(adapter, appModule);
      const server = awsLambdaFastify(adapter.getInstance() as FastifyInstance, {
        binaryMimeTypes: ['application/pdf', 'application/x-gzip'],
        decorateRequest: true,
        pathParameterUsedAsPath: 'proxy'
      });
      return server;

In case this does not work for you, please provide a new test case.

hfhchan-plb commented 10 months ago

How does your event look like?

{
  "body": null,
  "headers": {},
  "httpMethod": "GET",
  "isBase64Encoded": false,
  "multiValueHeaders": {},
  "multiValueQueryStringParameters": null,
  "path": "/data/token",
  "pathParameters": { "proxy": "data/token" },
  "queryStringParameters": null,
  "requestContext": {
    "path": "/v2/data/token",
    "protocol": "HTTP/1.1",
    "resourcePath": "/prod/v2/{proxy*}",
    "stage": "prod"
  },
  "resource": "/v2/{proxy+}",
  "stageVariables": null
}

(This is using serverless-offline with API gateway path: 'v2/{proxy+}' specified, with sensitive fields stripped)

adrai commented 10 months ago

Oh, yes I forgot the types... v3.4.2 should address this