-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
AWS APIgateway: fromRestApiAttributes does not bring all the RestAPI configuration #29079
Comments
And trying to pass the resource directly through the props from one stack to another is not working. Any workaround? |
Ok, escape hatch:
|
Did you mean you just define Can you share your full code here so we can focus on the code. |
No, i did not mean that. My project is composed of on main stack and two nested stacks, as defined in the example of the Apigateway CDK modul doc. MyStack
Common
Business
|
Hi, confirm that behavior has changed. OPTIONS is not propagated to resources created in API. This happens in our project if:
|
+1 I would like to add we experience this issue and are looking for a workaround. Our endpoints created via resources added to the "imported" api (fromRestApiAttributes) do not create OPTIONS endpoints and don't seem to carry over the cors configuration, which breaks them. |
We also "solved" this by passing the resource via props to our nested stack, however this attached our nested stack resources back to the root api stack which defeated the purpose since we wanted to fix our 500 resource limit issue. @wascou Could you provide more detail on your escape hatch fix |
@pahud Adding our code here hoping to help resolve this. Inside our root stack
And inside our ping stack, these methods will NOT deploy with OPTIONS endpoints or with cors config.
The ping endpoints deploy like this And methods that we have attached to the resources created from the standard api deploy like this with config correct. |
Hi This is because the resources from the imported API have no idea if the API is having the If you look at here, behind the scene it's just aws-cdk/packages/aws-cdk-lib/aws-apigateway/lib/resource.ts Lines 480 to 482 in 69cff2e
So it should be very easy to work it around. Check out my full working sample below:
export class ApiStack extends Stack {
readonly api: agw.RestApi;
readonly defaultCorsPreflightOptions?: agw.CorsOptions;
constructor(scope: Construct, id: string, props: StackProps) {
super(scope, id, props);
this.defaultCorsPreflightOptions = {
allowOrigins: [ 'https://amazon.com' ],
allowHeaders: agw.Cors.DEFAULT_HEADERS,
};
this.api = new agw.RestApi(this, 'RestAPI', {
defaultCorsPreflightOptions: this.defaultCorsPreflightOptions,
});
}
}
export interface DeployStackProps extends NestedStackProps {
readonly restApiId: string;
readonly rootResourceId: string;
readonly defaultCorsPreflightOptions?: agw.CorsOptions;
}
export class DeployStack extends NestedStack {
readonly methods: agw.Method[] = [];
readonly resources: agw.Resource[] = [];
constructor(scope: Construct, props: DeployStackProps) {
super(scope, 'integ-restapi-import-DeployStack', props);
const api = agw.RestApi.fromRestApiAttributes(this, 'RestApi', {
restApiId: props.restApiId,
rootResourceId: props.rootResourceId,
});
const abc = api.root.addResource('abc');
this.resources.push(abc);
const dummyIntegration = new agw.Integration({
type: agw.IntegrationType.MOCK,
});
this.methods.push(abc.addMethod('GET', dummyIntegration, {}))
const deployment = new agw.Deployment(this, 'Deployment', { api });
for (const method of this.methods) {
deployment.node.addDependency(method)
}
if(props.defaultCorsPreflightOptions) {
for (const resource of this.resources) {
resource.addCorsPreflight(props.defaultCorsPreflightOptions)
};
}
}
}
const app = new App();
const env = { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT };
const apiStack = new ApiStack(app, 'ApiStack', { env });
new DeployStack(apiStack, {
restApiId: apiStack.api.restApiId,
rootResourceId: apiStack.api.root.resourceId,
defaultCorsPreflightOptions: apiStack.defaultCorsPreflightOptions,
}) You got it :-) I am not sure if there's any good solution for that but this is a good workaround I believe. |
Thanks so much for the example @pahud I appreciate the response. Did we misunderstand the resource limit nested stack workaround with our implementation? I would think the api fromRestApiAttributes would take on the defaultCorsPreflightOptions that we pass to the first API we create. Just want to clarify we are on the right track before I re-organize to enable the workaround. I am going to implement this in one of our nested stacks I will update here. This should be simple to fix if this works, however if this is required for nested stack resources to take on parent stack defaultCorsPreflightOptions we should update the docs here: https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.NestedStack.html However if this isn't the preferred solution to our general problem I would love your thoughts on how we can re-work our exceeding 500 resource limit api created via cdk. Thanks again for the help! And love cdk! |
@pahud Can confirm that in our nested stack resource declaration all we had to do was addCorsPreflight our default options to each resource. thanks so much. The fix is so simple yet was so unintuitive for me based on the docs of fromRestApiAttributes! Thanks again and have a great weekend |
I'm sorry @pahud but this is not the expected behavior. Your answer is just using another API component to fix the issue. A workaround is not enough for the problem I pointed, I asked for a change in this construct. This is not fixing to the fundamental problem of why the settings are not shipped with the object through the different stacks, in a pure OOP style and in ocherence with the constructor of this L2 construct. In clear, you create an object in one file, calling it later in other file is not giving you the same object. Where is the immuability? |
+1 @wascou the workaround solves our immediate problem, but this of course doesn't fix the bug, unless like I said this is the expected way to use the cdk lib. |
Just as I mentioned above this is just a workaround, not a good solution. For all p2 issues with workaround, we welcome and appreciate any ideas and pull requests to help us improve the user experience. |
I would not say it's a bug but we definitely need to improve the user experience. Generally, any imported resource with It might be a solution to add a new prop in RestApiAttributes so when we import that API we can specify This might be an option off the top of my head. We welcome any PR to help us improve this user experience. |
This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled. |
Up |
Please fix. Lost half of the day because of this. |
Have the same problem. When "importing" this.#httpApi = HttpApi.fromHttpApiAttributes(this, "HttpApi", { httpApiId: props.httpApiId }) It doesn't "copy" this.#httpApi = new HttpApi(this, "HttpApi", {
// cut
defaultAuthorizer: this.#cookiesLambdaAuthorizer,
}) |
I think the solution proposed by @pahud makes sense to me. Since it's a |
Hi @GavinZZ , It's an issue we're still discussing what the construct SHOULD do. Being p2 is up to the team, this was not what I asked for and it's really lowering the developper standards. If you build construct for developpers to achieve IaC, you MUST give the best developper experience. Creating an object and making an import function somewhere else MUST retrieve all the properties of the object, not only what you think useful. It's also about ownership. This workaround implies lines of code that are actually under the responsibility of the construct else the construct is not covering the scope properly and breaks its promises. |
Describe the bug
I was following this documentation section, where there's a workaround for multiple stack describing api gateway resources:
Breaking up Methods and Resources across Stacks
It is fairly common for REST APIs with a large number of Resources and Methods to hit the CloudFormation limit of 500 resources per stack.
So I broke my stack in several nested stacks and imported back my api in each nested stack using the ``fromRestApiAttributes``` method. The correct object was found but not all the configuration appeared.
Expected Behavior
I was expecting the full object as set during the API creation in the main stack.
Current Behavior
Dumping the object, I had the following:
instead of:
Reproduction Steps
The following piece of code as mentionned in the documentation:
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway-readme.html#breaking-up-methods-and-resources-across-stacks
Possible Solution
No response
Additional Information/Context
No response
CDK CLI Version
2.127.0 (build 6c90efc)
Framework Version
No response
Node.js Version
v21.1.0
OS
Mac
Language
TypeScript
Language Version
No response
Other information
No response
The text was updated successfully, but these errors were encountered: