Skip to content
This repository has been archived by the owner on Aug 8, 2024. It is now read-only.

Unexpected behaviour with API-Gateway Custom Domain Name Mapping #27

Closed
art-dc opened this issue Oct 30, 2019 · 9 comments
Closed

Unexpected behaviour with API-Gateway Custom Domain Name Mapping #27

art-dc opened this issue Oct 30, 2019 · 9 comments

Comments

@art-dc
Copy link

art-dc commented Oct 30, 2019

Hi,

Recently we found out that the first parameter from the event.path was ignored. After a quick inspectation of the lib/proxyIntegration.js file, I found an "ugly hack" which caused this behaviour, along with the following comment:

ugly hack: if host is from API-Gateway 'Custom Domain Name Mapping', then event.path has the value '/basepath/resource-path/';
if host is from amazonaws.com, then event.path is just '/resource-path':

My guess is this function is necessary for cases where users of aws-lambda-router use the API-gateway like this: http://customdomain.com/[stage]/[...parameters] (i.e. using the stage in between the custom domain and the parameters). However, in my case only the prod stage should be published on the custom domain. That's why I created a base path mapping in my Custom Domain options which maps the / path to mylambdafunctionname:prod (the prod stage of my API). This is why I don't have the stage name in my custom url and I think this is what causes the code to (in my case undesirable) remove the first parameter. But this is just my guess. I'm not entirely sure what is meant by basepath in the "ugly hack" comment, but regardless of whether it's because of me not having the stage in my custom url or it's because of something else, my point regarding unexpected first parameter removal still stands.

I'd be glad to hear if more details are needed to debug this case.

@ghost
Copy link

ghost commented Nov 13, 2019

any update on this? even i am facing the same issue.

@swaner
Copy link
Contributor

swaner commented Nov 25, 2019

Are you using a proxy integration? https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-http.html

If so, I did a pull-request that has been merged where you can specify the proxy path. This should work for custom domains as well. See #26

In api gateway the resource should be defined like this:
/somebasepath/{proxy+}

This allows the route to be written without the base part, so we can write the route like this:
proxyIntegration: { proxyPath: 'proxy', routes: [ { path: 'generate', ...
Instead of the old way:
{ routes: [ { path: '/somebasepath/generate', ...

@art-dc
Copy link
Author

art-dc commented May 18, 2020

Hi,

Thanks for your reply. I've tested the new version of aws-lambda-router that includes your pull request just now. I've noticed that the thing you've achieved with your pull request differs from my issue.

Lambda's are usually deployed to an url like
https://xxxxxxxx.execute-api.eu-central-1.amazonaws.com/dev/{proxy+}

Where dev is the stage, either dev, prod or something else. When the router tries to match the requested url in event.path with the routes supplied to aws-lambda-router, it removes the first parameters (dev or prod or something else) because that parameter will not be supplied in the router handlers.

However, if you supply a custom domain in API Gateway, there are three options.

  • API
  • Stage
  • Path

The API is just the Lambda application. The path is probably what you are using in proxyPath: if you want https://example.com/v1/{proxy+} to all redirect to a certain lambda without the need to put /v1/ in all your routes in your lambda's handler.

Lastly, the Stage option, can be selected to make sure that https://api.example.com uses the prod stage whereas https://api-test.example.com uses the dev stage.

This way the stage does not have to be supplied in the request url, like https://api-test.example.com/dev/{proxy+}. And while the stage is not supplied, aws-lambda-router's code still (wrongly) removes the first parameter from the request url, causing a mismatch with the routes.

@gravitycode
Copy link

I did not understand this ugly hack and it has brought me a lot of headaches already. Couldn't we have a variable that disables this behavior?

@art-dc
Copy link
Author

art-dc commented Aug 19, 2020

@gravitycode I'd love to see an option to disable it in a future version as well.

@EthanDavis
Copy link
Contributor

I believe I'm running into the same or similar issue. I have an api gateway instance setup with a custom domain.

my routes are:
/api/health (GET)
/api/events (POST)

when I call https://custom-domain.com/api/events

I'm hitting the lambda but it's returning the following error:

{
    "message": "Could not find matching action for /events and method POST",
    "error": "NO_MATCHING_ACTION"
}

It seems like the router is removing the base /api? Or it's not getting passed through. Though I believe the issue is the former. When I add a base path mapping to my api gateway instance for /api then if I call:
https://custom-domain.com/api/api/events it succeeds. Any idea how I can fix this?

@EthanDavis
Copy link
Contributor

I've created a PR that implements your suggestion of having the ability to disable the removal of the base path.

See here: #72

@chgohlke
Copy link
Member

The PR #72 is closed now. To avoid the behaviour please use the following configuration of proxyIntegration:

proxyIntegration({
      removeBasePath: true,
      routes: [{
        ...
      }]
}

@EthanDavis
Copy link
Contributor

Created a PR adding documentation for removeBasePath in readme

#77

@art-dc art-dc closed this as completed Jun 29, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants