Closed Chriscbr closed 3 months ago
One solution to break up the dependency cycle could be to store the API Gateway URL in some kind of SSM parameter which is then retrieved dynamically at runtime perhaps?
Actually, maybe it makes sense to just lift and mirror this dependency cycle error in preflight (through the addDependency
feature of constructs) so it's detected at compile time, and then force the user to resolve this (either remove api.url
from their code, or avoid the cycle using a workaround like the one suggested above).
I'd be curious if this problem is the same in AWS CDK / CloudFormation / SST
The API Gateway rest api has the OpenAPI spec for the all endpoints, which refers to the ARN of the AWS Lambda function
Why does the openApi spec needs to have a reference to the AWS lambda ARN?
The API Gateway rest api has the OpenAPI spec for the all endpoints, which refers to the ARN of the AWS Lambda function
Why does the openApi spec needs to have a reference to the AWS lambda ARN?
That's a good question... it looks like it's needed to specify the integration between the API endpoint and the lambda function, so that AWS can configure all requests to a particular route (like GET /hello) go to that lambda. This is the code I found in our SDK:
Actually, maybe it makes sense to just lift and mirror this dependency cycle error in preflight (through the addDependency feature of constructs) so it's detected at compile time, and then force the user to resolve this (either remove api.url from their code, or avoid the cycle using a workaround like the one suggested above).
I like this approach, but will the user have indication for this problem when he compiles to sim as well ?
It seems that what is causing trouble in capturing the URL when the destination is AWS is that the gateway is only created after the lambda is deployed, so we don't have the URL reference in the lambda.
The OpenAPI is generating the problem since it creates the integration between the gateway and the lambda, and it requires the lambda's reference.
To fix it, we would probably have to remove the OpenAPI and first create the Gateway, then the lambda, and finally create the integration between them.
This code works, the function that doesn't have integration with the gateway can retrieve the URL
bring cloud;
let api = new cloud.Api();
api.get("/route", inflight (req: cloud.ApiRequest): cloud.ApiResponse => {
return cloud.ApiResponse {
status: 200,
body: Json "ok"
};
});
new cloud.Function(inflight(e:str) => {
log("${api.url}");
});
Hi,
This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. Feel free to re-open this issue when there's an update or relevant information to be added. Thanks!
I don't think think this should be p1
Do you have an estimated hard is it to show the error of tf-aws
compilation
Moved to p2
Hi,
This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. Feel free to re-open this issue when there's an update or relevant information to be added. Thanks!
I figured I'd try one more time to see if there's any way to unravel this cycle cleanly, on AWS at least (since it's not an inherent modeling problem).
I went down the route of SSM parameters initially (as it's a general solution to the problem of runtime code referencing deploy-time information), but it requires more work to build out, so I've put a pin on it for now. But the idea would be to have dependencies generated like so:
This looks like it's just a longer cycle, but the trick is that in step (2), the SSM parameter name can be computed at compile time through the construct ID. So the AWS Lambda doesn't need to take any dependencies on the API Gateway nor the SSM parameter in the Terraform configuration.
The issue implementing this is that it requires the inflight code to change. Instead of the Lambda reading the environment variable directly, it would have to call the SSM service to obtain the parameter value at runtime. Maybe this logic is handled as part of the cloud.Api
inflight client? Or maybe it's a responsibility of the Wing compiler / framework? I'm not totally sure yet.
For now I came up with another possible workaround: https://github.com/winglang/wing/pull/5637
Maybe I'm mistaken since I haven't done much with API gateway, but could we use https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/api_gateway_integration instead of the openapi body at the API level to define the routes? This should remove the circular dep.
instead of (->
is depends on
)
lambda -> stage -> deployment -> api -> (X)lambda
we'd get
integration -> api + integration -> lambda -> stage -> deployment -> api
Congrats! :rocket: This was released in Wing 0.57.11.
I tried this:
This happened:
wing test -t sim api_url.w
passes (it simulates the app, and runs all 0 of 0 tests)But
wing test -t tf-aws api_url.w
fails when it tries to runterraform apply
:Error: Cycle: aws_api_gateway_deployment.root_env0_cloudApi_api_deployment_FABCA7C9, aws_api_gateway_rest_api.root_env0_cloudApi_api_3A5A95BE, aws_api_gateway_stage.root_env0_cloudApi_api_stage_0D945F2C, aws_lambda_function.root_env0_cloudApi_cloudApiOnRequest3915c5ec_DC2C0B9C
I expected this:
Either the app should deploy, or I should get some error at compile time
Is there a workaround?
No response
Component
SDK
Wing Version
0.18.1
Wing Console Version
No response
Node.js Version
18.14.1
Platform(s)
MacOS
Anything else?
Here's a breakdown of the dependency cycle:
api.url
, the AWS Lambda function that is created has an environment variable which depends on the API Gateway stage invoke url:Community Notes