我们针对不同的 API 有单独的 AWS CDK 项目。我们希望对同一 API 网关资源使用具有不同基本路径映射的相同子域。例如;假设我们有两个 API,分别是
tenantApi
和 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
。导入domainName时用到了三个属性;
domainNameAliasDomainName
的 domainName
值。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,
});