micronaut-aws icon indicating copy to clipboard operation
micronaut-aws copied to clipboard

Changed behaviour of routing evalution between Micronaut 3 and 4?

Open dniel opened this issue 3 months ago • 8 comments

Expected Behavior

I have upgraded one of the REST-API lambdas in our application from Micronaut 3 to 4. Its a REST API accessibly via AWS API Gateway under the api mapping /myapp and uses the Application type with io.micronaut.function.aws.proxy.payload1.ApiGatewayProxyRequestEventFunction routing in Micronaut to route to the correct @Controller in the lambda.

In application.yml micronaut.server.context-path is set to / and when I "Test" the Lambda from the API-Gateway console in the Test-tab I can see that the request event looks like this.

{
  "path": "/users",
  "resource": "/users",
  "httpMethod": "GET",
  "headers": {
    "Accept": "application/json"
  }
}

This works in both Micronaut 3 and 4 because path and resource is the same and the Lambda has context-root '/' set and return the json produced from my lambda response.

When testing this from postman to the api-gateway url, the request event looks like this Notice that the API Gateway has added the API mapping to the path property, but not to the resource property.

{
  "path": "/myapp/users",
  "resource": "/users",
  "httpMethod": "GET",
  "headers": {
    "Accept": "application/json"
  }
}

This works in Micronaut 3 using io.micronaut.function.aws.proxy.MicronautLambdaHandler because it seems like Micronaut 3 uses the "resource": "/users" property to evaluate the routing to correct method in the Controller.

When using Micronaut 3, I can change "path": "/whatever" in the request event like below, and it will still call my Users controller and return the expected response, because it use the "resource" property to route.

{
  "path": "/whatever",
  "resource":  "/users",
  "httpMethod": "GET",
  "headers": {
    "Accept": "application/json"
  }
}

Upgrading to Micronaut 4, this will break and return 404 instead.

  • Micronaut 3 seems to use property "resource" in the lambda event for routing.
  • Micronaut 4 seems to use property "path" in the lamnda event for routing.
  • resource and path does not have the same values, routing breaks when upgrading.

Actual Behaviour

In Micronaut 4 using the handler io.micronaut.function.aws.proxy.payload1.ApiGatewayProxyRequestEventFunction it seems like it has been changed which property in the request event that is evaluated for routing and its now the path-property instead, which by API Gateway includes the context-root set in the api mapping from Api Gateway, which means that the context root in the lambdas application.yml must now be set to the same.

A request as the one below will work in Micronaut 3, but not in Micronaut 4.

{
  "path": "/myapp/users",
  "resource": "/users",
  "httpMethod": "GET",
  "headers": {
    "Accept": "application/json"
  }
}

This means that the same lambda can't be used from different API Gatway APIs in Micronaut4 but could in Micronaut3.

Steps To Reproduce

  • Create a lambda with micronaut 3 using io.micronaut.function.aws.proxy.MicronautLambdaHandler with context-root: /
  • Create a controller responding to /users and return 200 ok.
  • Publish the lambda and go to the AWS Lambda console and "Test" invoke with something like
{
  "path": "/whatever",
  "resource":  "/users",
  "httpMethod": "GET",
  "headers": {
    "Accept": "application/json"
  }
}
  • the result should be 200 ok.
  • Upgrade the Lambda to Micronaut4 and handler io.micronaut.function.aws.proxy.payload1.ApiGatewayProxyRequestEventFunction
  • Publish new version and "Test" invoke again with the same event as above
{
  "path": "/whatever",
  "resource":  "/users",
  "httpMethod": "GET",
  "headers": {
    "Accept": "application/json"
  }
}
  • the response is 404

Environment Information

  • Micronaut 3.8.3 upgrade to Micronaut 4.3.4
  • JDK 17
  • Gradle 8.6

Example Application

No response

Version

4.3.4

dniel avatar Mar 08 '24 10:03 dniel