diff --git a/.mergify.yml b/.mergify.yml index 39b3444ef627f..1aeba69346865 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -61,7 +61,7 @@ pull_request_rules: comment: message: Once all the requested changes have been addressed, and the PR is ready for another review, remember to [dismiss the review](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/dismissing-a-pull-request-review). conditions: - - changes-requested-reviews-by=@aws/aws-cdk-team + - "#changes-requested-reviews-by>=1" - name: remove stale reviews actions: dismiss_reviews: diff --git a/packages/@aws-cdk/aws-apigateway/README.md b/packages/@aws-cdk/aws-apigateway/README.md index a701e4744f604..f7ac9755270c1 100644 --- a/packages/@aws-cdk/aws-apigateway/README.md +++ b/packages/@aws-cdk/aws-apigateway/README.md @@ -619,10 +619,18 @@ domain.addBasePathMapping(api1, { basePath: 'go-to-api1' }); domain.addBasePathMapping(api2, { basePath: 'boom' }); ``` -NOTE: currently, the mapping will always be assigned to the APIs -`deploymentStage`, which will automatically assigned to the latest API -deployment. Raise a GitHub issue if you require more granular control over -mapping base paths to stages. +You can specify the API `Stage` to which this base path URL will map to. By default, this will be the +`deploymentStage` of the `RestApi`. + +```ts +const betaDeploy = new Deployment(this, 'beta-deployment', { + api: restapi, +}); +const betaStage = new Stage(this, 'beta-stage', { + deployment: betaDeploy, +}); +domain.addBasePathMapping(restapi, { basePath: 'api/beta', stage: betaStage }); +``` If you don't specify `basePath`, all URLs under this domain will be mapped to the API, and you won't be able to map another API to the same domain: diff --git a/packages/@aws-cdk/aws-apigateway/lib/base-path-mapping.ts b/packages/@aws-cdk/aws-apigateway/lib/base-path-mapping.ts index 4a307db43d90c..6758834324d77 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/base-path-mapping.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/base-path-mapping.ts @@ -2,6 +2,7 @@ import { Construct, Resource, Token } from '@aws-cdk/core'; import { CfnBasePathMapping } from './apigateway.generated'; import { IDomainName } from './domain-name'; import { IRestApi, RestApi } from './restapi'; +import { Stage } from './stage'; export interface BasePathMappingOptions { /** @@ -13,6 +14,13 @@ export interface BasePathMappingOptions { * is undefined, no additional mappings will be allowed on this domain name. */ readonly basePath?: string; + + /** + * The Deployment stage of API + * [disable-awslint:ref-via-interface] + * @default - map to deploymentStage of restApi otherwise stage needs to pass in URL + */ + readonly stage?: Stage; } export interface BasePathMappingProps extends BasePathMappingOptions { @@ -44,17 +52,17 @@ export class BasePathMapping extends Resource { } } - // if this is an owned API and it has a deployment stage, map all requests + // if restApi is an owned API and it has a deployment stage, map all requests // to that stage. otherwise, the stage will have to be specified in the URL. - const stage = props.restApi instanceof RestApi + const stage = props.stage ?? (props.restApi instanceof RestApi ? props.restApi.deploymentStage - : undefined; + : undefined); new CfnBasePathMapping(this, 'Resource', { basePath: props.basePath, domainName: props.domainName.domainName, restApiId: props.restApi.restApiId, - stage: stage && stage.stageName, + stage: stage && stage.stageName }); } } diff --git a/packages/@aws-cdk/aws-apigateway/test/test.domains.ts b/packages/@aws-cdk/aws-apigateway/test/test.domains.ts index fd7d3e7e85c2a..3338290ab76d9 100644 --- a/packages/@aws-cdk/aws-apigateway/test/test.domains.ts +++ b/packages/@aws-cdk/aws-apigateway/test/test.domains.ts @@ -330,6 +330,58 @@ export = { } })); + test.done(); + }, + + '"addBasePathMapping" can be used to add base path mapping to the domain with specific stage'(test: Test) { + // GIVEN + const stack = new Stack(); + const api1 = new apigw.RestApi(stack, 'api1'); + const api2 = new apigw.RestApi(stack, 'api2'); + const domain = new apigw.DomainName(stack, 'my-domain', { + domainName: 'example.com', + certificate: acm.Certificate.fromCertificateArn(stack, 'cert', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'), + endpointType: apigw.EndpointType.REGIONAL + }); + api1.root.addMethod('GET'); + api2.root.addMethod('GET'); + + const testDeploy = new apigw.Deployment(stack, 'test-deployment', { + api: api1 + }); + + const testStage = new apigw.Stage(stack, 'test-stage', { + deployment : testDeploy + }); + + // WHEN + domain.addBasePathMapping(api1, { basePath: 'api1', stage: testStage }); + domain.addBasePathMapping(api2, { basePath: 'api2' }); + + // THEN + expect(stack).to(haveResource('AWS::ApiGateway::BasePathMapping', { + "DomainName": { + "Ref": "mydomain592C948B" + }, + "BasePath": "api1", + "RestApiId": { + "Ref": "api1A91238E2" + }, + "Stage": stack.resolve(testStage.stageName) + })); + + expect(stack).to(haveResource('AWS::ApiGateway::BasePathMapping', { + "DomainName": { + "Ref": "mydomain592C948B" + }, + "BasePath": "api2", + "RestApiId": { + "Ref": "api2C4850CEA" + }, + "Stage": { + "Ref": "api2DeploymentStageprod4120D74E" + } + })); test.done(); } };