44

I am trying to redirect all traffic for one domain to another. Rather than running a server specifically for this job I was trying to use AWS API Gateway with lambda to perform the redirect.

I have this working ok for the root path "/" but any requests for sub-paths e.g. /a are not handled. Is there a way to define a "catch all" resource or wildcard path handler?

David
  • 7,652
  • 21
  • 60
  • 98

5 Answers5

37

As of last week, API Gateway now supports what they call “Catch-all Path Variables”.

Full details and a walk-through here: API Gateway Update – New Features Simplify API Development

Avi Flax
  • 50,872
  • 9
  • 47
  • 64
  • 2
    If you're still looking for this answer in 2018, please look at @geekQ's answer (https://stackoverflow.com/a/40608247/347777), as a true catch-all (that matches /a/b/c/d/...) is now possible. – Viccari Jan 26 '18 at 01:16
  • useful blog post to setup catch-all with cloudformation https://cjohansen.no/aws-apigw-proxy-cloudformation/ – linqu Mar 07 '19 at 07:04
27

You can create a resource with path like /{thepath+}. Plus sign is important.

Then in your lambda function you can access the value with both

  • event.path - always contains the full path
  • or event.pathParameters.thepath - contains the part defined by you. Other possible use case: define resource like /images/{imagepath+} to only match pathes with certain prefix. The variable will contain only the subpath.

You can debug all the values passed to your function with: JSON.stringify(event)

Full documentation

MacMcIrish
  • 193
  • 1
  • 7
geekQ
  • 29,027
  • 11
  • 62
  • 58
  • 5
    This doesn't work for me - when attempting to update the Resource, I get `Resource's path part only allow a-zA-Z0-9._- and curly braces at the beginning and the end.`. – scubbo Mar 04 '20 at 02:08
  • 1
    This doesn't seem to match the base URL `/` either. – Migwell Sep 27 '21 at 05:34
  • If you want to match a path without the wildcard param, you need to define a separate handler for them (in examples above, for `/` and `/images`) – jakub.g Jan 28 '22 at 21:36
  • BTW: It seems that `serverless-offline` changes `+` to`*` in `event.resource`, i.e. it makes it `/{thepath*}` instead of `/{thepath+}` (the YML file syntax). So if you have some JS-level logic relying on `event.resource` you need to normalize it in order to have the logic working same way with serverless-offline and real AWS. – jakub.g May 18 '22 at 08:40
9

Update: As of last week, API Gateway now supports what they call “Catch-all Path Variables”. See API Gateway Update – New Features Simplify API Development.


You will need to create a resource for each level unfortunately. The reason for this is API Gateway allows you to access those params via an object.

For example: method.request.path.XXXX

So if you did just /{param} you could access that with: method.request.path.param but if you had a nested path (params with slashes), it wouldn't work. You'd also get a 404 for the entire request.

If method.request.path.param was an array instead...then it could get params by position when not named. For example method.request.path.param[] ...Named params could even be handled under there, but accessing them wouldn't really be easy. It would require using something some sort of JSON path mapping (think like what you can do with their mapping templates). Sadly this is not how it's handled in API Gateway.

I think it's ok though because this might make configuring API Gateway even more complex. However, it does also limit API Gateway and to handle this situation you will ultimately end up with a more confusing configuration anyway.

So, you can go the long way here. Create the same method for multiple resources and do something like: /{1}/{2}/{3}/{4}/{5}/{6}/{7} and so on. Then you can handle each path parameter level if need be.

IF the number of parameters is always the same, then you're a bit luckier and only need to set up a bunch of resources, but one method at the end.

source: https://forums.aws.amazon.com/thread.jspa?messageID=689700&#689700

Avi Flax
  • 50,872
  • 9
  • 47
  • 64
Tom
  • 3,507
  • 1
  • 29
  • 29
  • 2
    As of last week, API Gateway now supports what they call “Catch-all Path Variables”: https://aws.amazon.com/blogs/aws/api-gateway-update-new-features-simplify-api-development/ – Avi Flax Sep 25 '16 at 14:06
  • 2
    You can also now use `ANY` request and `/{proxy+}` - so much more than just a wildcard path, but a wildcard HTTP method is also supported \o/ – Tom Dec 07 '16 at 22:48
8

Related to HTTPAPI that AWS introduced recently, $default is used a wildcard for catching all routes that don't match a defined pattern.

For more details, refer to: aws blogs

human
  • 2,250
  • 20
  • 24
  • 2
    This is correct. Unlike the `/{any}+` answers, this will also match `/`. However, I don't find that the above link actually explains this fact. A better reference is here: https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-routes.html#http-api-develop-routes.default – Migwell Sep 27 '21 at 06:42
1

You can create a resource with path variable /{param}, and you can treat this as wildcard path handler.

Thanks, - Ka Hou

Ka Hou Ieong
  • 5,835
  • 3
  • 20
  • 21
  • Thanks, do you know whether this would work with nested paths? i.e. if I use /{param} this would match /a but I'm not sure it would match /a/b/c? Since I am trying to redirect all traffic I'd ideally love to be able to say /* or equivalent. – David Mar 04 '16 at 12:08
  • 1
    defining a resource for `/{param}` will not handle nested paths. E.g. `/something` will match, but `/something/else` will not match the resource `/{param}` – Joe B Sep 09 '16 at 14:35
  • 1
    That is correct. API Gateway doesn't support multiple level path currently. – Ka Hou Ieong Sep 10 '16 at 22:42
  • 1
    @DavidGoate You can use the greedy pattern {param+} to match all sub-resources – pabombs May 21 '18 at 01:21