(apiGateway): path may have some resources are already exist in api_gateway, the CDK still will create all resources for the path. #31093
Labels
@aws-cdk/aws-apigateway
Related to Amazon API Gateway
effort/medium
Medium work item – several days of effort
feature-request
A feature should be added or improved.
p2
Describe the bug
Hi team, there are some very tricky errors when we use
RestApi.from_rest_api_attributes
and 'resource.resource_for_path(path)'.We are using Python lib.
Our team wants to add methods and resources to an existing API on several stacks.
First, we are using
from_rest_api_attributes
to get an existing restApi:api = aws_apigateway.RestApi.from_rest_api_attributes( scope=scope, id='Api', rest_api_id=api_id, root_resource_id=root_resource_id )
then we want to add those resources on the A stack:
res = api.root.resource_for_path('/api/test/list') res.add_method("get") res = api.root.resource_for_path('/api/test/get') res.add_method("get")
and add resources on the B stack:
res = api.root.resource_for_path('/api/test/update') res.add_method("get") res = api.root.resource_for_path('/api/test/delete') res.add_method("get")
Result: The A stack was deployed successfully, but the B stack was deployed failed by '/api, /test resource already exists'.
The reason was that in resourceForPath, CDK is using getResource to determine if
api
resource is a child of/
, and recursive execute each part of the path. but how each resource knows their children, is when resource init they will add themselves to the parent resoure's child list. like: https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/aws-apigateway/lib/resource.ts#L446. because this, if we only know the root resource, we can't know the all children of the root resource.So to fix this we found two solutions, but only one is working.
Solution One:
create our customized resourceForPath method like:
But this solution failed when we try updated the path resources on the stack, for example:
In the first deployment, we create path
/test/v1
, and this stack newly creates and manages each resource.second deployment, we update
/test/v1
totest/v2
, and the code will think the/test
resource already exists, so will remove this resource from the stack, so all resources belonging to/test/v2
will disappear.We try to use the
resource. stack
to confirm if this resource is managed by this stack so we can re-handler it, but thisstack
param doesn't work as we expect, so we don't know how to fix it.Solution Two(accepted):
we consider maybe we can use a separate stack to create and manage all path resources and apigateway, so in our deployment stack, we can just import an existing path and add a method for it.
for example, we have an existing path
/test/v1
resource id is545etf
, and we use545etf
as the root_resourse_id set onfrom_rest_api_attributes
to get API gateway, so we can add method directly to the root resource, code is like:But, this solution also failed, because even if we set the root_resource to
545etf
, we can get the correct resource id on theapi.root.resource_id
, but theapi.root.path
result is just/
. so the method was added succeed on the apigateway side, but the lambda will trigger by a wrong apigateway path and cause the error.The reason is in CDK we just create new resource for this root_resource_id, not to find exist one.
we found a complex way to avoid this error, the final workaround is like:
Option 2 is working normally for me now, but we think it's valuable to raise an issue with your team and see if you have a better solution, or if these two errors can be fixed by the CDK side.
Regression Issue
Last Known Working CDK Version
No response
Expected Behavior
Resource.resource_for_path
method can GETS or create all resources leading up to the specified path.when we set a different root resource id on from_rest_api_attributes, we can get the correct path when calling
api. root.path
.Current Behavior
Resource.resource_for_path
method will creates all resources leading up to the specified path, even some resources are already existed.when we set a different root resource id on from_rest_api_attributes, the
api.root.path
always return/
.Reproduction Steps
follow the code on the bug description.
Possible Solution
No response
Additional Information/Context
No response
CDK CLI Version
2.113.0
Framework Version
No response
Node.js Version
v20.12.2
OS
mac 14.6
Language
Python
Language Version
python 3.10
Other information
No response
The text was updated successfully, but these errors were encountered: