如何将不同项目的多个基本路径映射添加到同一个AWS API网关中?

问题描述 投票:0回答:1

我们针对不同的 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);

  }
}

我感谢您的帮助。谢谢!

amazon-web-services aws-api-gateway aws-cdk amazon-route53
1个回答
3
投票

我必须首先创建一个

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时用到了三个属性;

  • domainName:我们之前创建的domainName。
  • domainNameAliasHostedZoneId:定义域的托管 ZoneId。
  • domainNameAliasTarget:AWS 文档没有明确说明它是什么。基本上,它是我们首先创建的
    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,
});
© www.soinside.com 2019 - 2024. All rights reserved.