-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Description
Describe the feature
The DomainName construct in aws-apigateway supports base path mappings and API mappings, but there's no L2 for Routing Rules (AWS::ApiGatewayV2::RoutingRule). To use routing rules today, you have to drop down to L1 constructs, manually build domain name ARNs, and give up synth-time validation entirely.
This proposal adds
- A
RoutingRuleL2 construct inaws-apigateway - A
RoutingModeenum androutingModeproperty onDomainName - An
addRoutingRule()method onDomainName
Use Case
A common pattern with routing rules is putting multiple REST APIs behind a single custom domain and splitting traffic by path or header.
/users/*→ Users Service API/orders/*→ Orders Service API- Header
x-api-version: v2→ New Orders Service API - Everything else → Default API (catch-all)
Current workaround (L1)
const cfnDomainName = new apigw.CfnDomainName(this, 'CustomDomain', {
domainName: 'api.example.com',
regionalCertificateArn: certificate.certificateArn,
endpointConfiguration: { types: ['REGIONAL'] },
routingMode: 'ROUTING_RULE_ONLY',
});
const domainNameArn = cdk.Arn.format(
{
service: 'apigateway',
resource: '/domainnames',
resourceName: 'api.example.com',
},
cdk.Stack.of(this),
);
new apigwv2.CfnRoutingRule(this, 'UsersRule', {
domainNameArn,
priority: 100,
conditions: [{ matchBasePaths: { anyOf: ['users'] } }],
actions: [
{
invokeApi: {
apiId: usersApi.restApiId,
stage: usersApi.deploymentStage.stageName,
stripBasePath: true,
},
},
],
});
// ... and repeat for every ruleThe main pain points with this approach
- You have to know the ARN format for API Gateway domain names and build it yourself with
cdk.Arn.format() - You need to import
aws-apigatewayv2even though routing rules are a REST API feature, which is just confusing - The CloudFormation structure is deeply nested (
matchBasePaths.anyOf,invokeApi.apiId, etc.) and easy to get wrong - There's zero validation until deploy time, so typos in header names, out-of-range priorities, or routing mode mismatches all turn into slow CloudFormation rollbacks
- Nothing prevents you from mixing
addBasePathMapping()withROUTING_RULE_ONLYmode or vice versa
Proposed Solution
Proposed API
import { DomainName, RoutingMode } from 'aws-cdk-lib/aws-apigateway';
const domain = new DomainName(this, 'Domain', {
domainName: 'api.example.com',
certificate: certificate,
routingMode: RoutingMode.ROUTING_RULE_ONLY,
});
// Path-based routing
domain.addRoutingRule('UsersRule', {
priority: 100,
conditions: {
basePaths: ['users'],
},
action: {
restApi: usersApi,
stripBasePath: true,
},
});
// Header-based routing
domain.addRoutingRule('HeaderV2Rule', {
priority: 50,
conditions: {
headers: [{ header: 'x-api-version', valueGlob: 'v2' }],
},
action: {
restApi: ordersApiV2,
},
});
// Combined conditions (headers AND basePaths)
domain.addRoutingRule('V2OrdersRule', {
priority: 75,
conditions: {
basePaths: ['orders'],
headers: [{ header: 'x-api-version', valueGlob: 'v2' }],
},
action: {
restApi: ordersApiV2,
stripBasePath: true,
},
});
// Catch-all (no conditions)
domain.addRoutingRule('CatchAllRule', {
priority: 999999,
action: {
restApi: defaultApi,
},
});Design Decisions
addRoutingRule() on DomainName with RoutingMode enforcement
addRoutingRule() sits alongside the existing addBasePathMapping() and addApiMapping(). The construct checks that the method matches the configured routing mode — calling addRoutingRule() on a BASE_PATH_MAPPING_ONLY domain (the default) gives a clear error telling you to set the mode. Same in the other direction.
Synth-time validation
The construct validates all the constraints from the Routing rules restrictions docs at synth time, so you don't have to wait for a deploy to find out your header name is restricted or your priority is out of range. Unresolved tokens skip validation as usual.
RoutingRule also works as a standalone construct
For cross-stack scenarios, RoutingRule can be instantiated directly with a domainName: IDomainName prop, same pattern as BasePathMapping.
new RoutingRule(this, 'UsersRule', {
domainName: importedDomain,
priority: 100,
conditions: {
basePaths: ['users'],
},
action: {
restApi: usersApi,
stage: usersApi.deploymentStage,
stripBasePath: true,
},
});Other Information
- Under the hood this uses
AWS::ApiGatewayV2::RoutingRule. It's a REST API feature but lives in the v2 namespace on the CloudFormation side. The existingDomainNameL2 already usesapigwv2.CfnApiMappinginternally, so this isn't a new pattern. - Routing rules only work with REGIONAL endpoints.
- AWS docs
Acknowledgements
- I may be able to implement this feature request
- This feature might incur a breaking change
AWS CDK Library version (aws-cdk-lib)
2.x
AWS CDK CLI version
2.x
Environment details (OS name and version, etc.)
all