我们为不同的 API 提供了单独的 AWS CDK 项目。我们希望对同一 API 网关资源使用相同的子域和不同的基本路径映射。例如;假设我们有两个 APItenantApi
和invoiceApi
映射到test.example.com/tenant
和test.example.com/invoice
.这可以从一个存储库中实现,只需创建一个 RestApi 并为其定义多个基本路径映射即可。但是,我找不到从不同的存储库执行此操作的方法,因为我只需要为子域创建一个 ARecord。我的想法是在我们管理共享资源的存储库中创建ARecord
,并从我们将使用相同的 API 网关的存储库导入该记录。
以下是关于我如何创建 API 网关的简单 aws cdk 代码。如您所见,我们必须将 RestApi 实例传递到route53.RecordTarget.fromAlias
所以我不确定我们是否可以在创建 API 网关之前创建 ARecord。
export class ApiGatewayStack extends Stack {
constructor(scope: Construct, id: string, props: StackEnvProps) {
super(scope, id, props);
const tenantApi = new apigateway.RestApi(this, 'tenantApi', {
domainName: {
domainName: props.context['domainName'],
certificate: acm.Certificate.fromCertificateArn(this, 'certificateArn', props.context['certificateArn']),
basePath: 'tenant'
},
deploy: true,
deployOptions: {
stageName: 'prod',
},
defaultCorsPreflightOptions: {
allowMethods: apigateway.Cors.ALL_METHODS,
allowOrigins: apigateway.Cors.ALL_ORIGINS,
}
});
const zone = route53.HostedZone.fromLookup(this, 'Zone', { domainName: 'example.com' });
// create an alias for mapping
new route53.ARecord(this, 'domainAliasRecord', {
zone: zone,
recordName: "test",
target: route53.RecordTarget.fromAlias(new ApiGateway(tenantApi)),
});
const methodOptions: apigateway.MethodOptions = {
methodResponses: [
{
statusCode: '200',
responseParameters: {
'method.response.header.Content-Type': true,
},
},
{
statusCode: '400',
responseParameters: {
'method.response.header.Content-Type': true,
},
},
],
};
const postPaymentsLambda = new NodejsFunction(this, 'postTenantLambda', {
entry: './lambda/rest/tenant-api/post-tenant-api.ts',
handler: 'handler',
memorySize: 512,
runtime: lambda.Runtime.NODEJS_14_X,
});
// tenant/v1
const tenantV1 = tenantApi.root.addResource('v1');
tenantV1.addMethod('POST', new apigateway.LambdaIntegration(postPaymentsLambda), methodOptions);
}
}
我感谢任何帮助。谢谢!
我必须首先创建一个domainName
,然后创建一个ARecord
,其目标domainName
可以从我想附加的不同 API 导入。
// create domain name for api gateway
const domainName = new apigateway.DomainName(this, 'domainName', {
domainName: `test.${props.domainName}`,
certificate: acm.Certificate.fromCertificateArn(this, 'certificateArn', props.certificateArn),
endpointType: apigateway.EndpointType.REGIONAL,
securityPolicy: apigateway.SecurityPolicy.TLS_1_2,
});
const zone = route53.HostedZone.fromLookup(this, 'hostedZone', {
domainName: props.context['domainName']
});
// create an alias for mapping
new route53.ARecord(this, 'apiGatewayDomainAliasRecord', {
zone: zone,
recordName: 'test',
target: route53.RecordTarget.fromAlias(new r53target.ApiGatewayDomain(domainName)),
});
new CfnOutput(this, 'apiGatewayDomainNameAliasTarget', {
value: domainName.domainNameAliasDomainName,
description: 'domainNameAliasTarget attribute used when importing domain name',
exportName: 'apiGatewayDomainNameAliasTarget'
});
稍后,我将导入此domainName
以创建一个BasePathMapping
。导入域名时使用了三个属性;
- :我们之前创建的域名。
- domainNameAliasHostedZoneId:定义域的托管区域 ID。
- domainNameAliasTarget:AWS 文档没有明确说明它是什么。基本上,这是我们最初创建的
domainName
的domainNameAliasDomainName
价值。
const tenantApi = new apigateway.RestApi(this, 'tenantApi', {
deployOptions: {
stageName: 'dev',
},
deploy: true,
defaultCorsPreflightOptions: {
allowMethods: apigateway.Cors.ALL_METHODS,
allowOrigins: apigateway.Cors.ALL_ORIGINS,
}
});
const domainName = apigateway.DomainName.fromDomainNameAttributes(this, 'domainName', {
domainName: `test.${props.domainName}`,
domainNameAliasHostedZoneId: props.hostedZoneId,
domainNameAliasTarget: Fn.importValue(props.apiGatewayDomainNameAliasTarget),
});
const nodeBasePathMapping = new apigateway.BasePathMapping(this, 'nodeBasePathMapping', {
basePath: 'node',
domainName,
restApi: tenantApi,
});