Skip to content

LambdaHandler.fromHttpApi misroutes REST API Gateway v1 nested {proxy+} resources #220

Description

@gabrielcolson

LambdaHandler.fromHttpApi supports API Gateway REST API v1 events, but the v1 event adapter appears to prefer event.pathParameters.proxy over event.path when building the internal Request path.

That breaks nested proxy resources such as /user/{proxy+}.

For a request to:

POST /dev/user/session

API Gateway REST v1 can produce an event like:

{
  httpMethod: "POST",
  path: "/dev/user/session",
  pathParameters: {
    proxy: "session",
  },
  requestContext: {
    stage: "dev",
    path: "/dev/user/session",
  },
  resource: "/user/{proxy+}",
  headers: {
    "Content-Type": "application/json",
  },
  multiValueHeaders: {},
}

The current adapter logic effectively routes this as:

/session

because it uses pathParameters.proxy as the path. The expected route path after removing the stage prefix is:

/user/session

This means an Effect HttpApi route under /user/session will not match when invoked through a REST API nested proxy integration.

Expected Behavior

For REST API Gateway v1 events, the adapter should preserve the full logical request path for nested proxy resources.

For the event above, the request path should become:

/user/session

not:

/session

Actual Behavior

The adapter prefers:

event.pathParameters.proxy

which only contains the suffix matched by the {proxy+} segment. For nested proxy resources like /user/{proxy+}, that omits the static resource prefix.

Suspected Cause

In the API Gateway v1 adapter, the path is built from event.pathParameters.proxy if present, falling back to event.path.

That seems valid only for root catch-all resources like /{proxy+}. It is not valid for nested catch-all resources like /user/{proxy+}.

Additional REST v1 robustness issues

Two related REST v1 normalization concerns came up while working around this locally:

  1. REST API Gateway event.path / requestContext.path may include the stage prefix, so the adapter may need to normalize that before routing.
  2. If multiValueHeaders exists but is empty, the adapter appears to prefer it over headers, which can drop headers such as content-type.

Version

Observed with:

"@effect-aws/lambda": "^1.5.1"

Local Workaround

We currently normalize the event before passing it to LambdaHandler.fromHttpApi:

  • Strip the REST API stage prefix from event.path.
  • Rewrite requestContext.path.
  • Rewrite pathParameters.proxy from the normalized full path.
  • Populate missing multiValueHeaders entries from headers.

This works, but it feels like behavior that should live in the REST API Gateway v1 adapter.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions