Define your API via OpenAPI definition on AWS
Application Programming Interfaces(APIs) is a critical part of the web service, Werner Vogel, the CTO of AWS had a great 6 Rules for Good API Design presentation in 2021 re:Invent keynote.
In AWS the developers could manage and proxy the APIs via Amazon API Gateway. The developers can use console, CLI, API or IaC code(for example, Terraform/CloudFormation/CDK) to provisioning the API resources on AWS. However some developers might flavor with using OpenAPI specification to define the APIs. It enables multiple services/tools to understand the APIs' specification, such as Postman. Amazon API Gateway supports this use case, you can import the existing OpenAPI definition as API.
Amazon API Gateway offers two RESTful API products, REST API and HTTP API. Both of those two APIs support importing OpenAPI definition, but they might use different OpenAPI extensions to support different features.
And below example will use infrastructure as code(AWS CDK) to import the OpenAPI definition to the API Gateway APIs.
While importing OpenAPI definition, the most challenge is updating the OpenAPI definition with
dynamic resources information(for example, IAM role for calling downstream resources of integration) before importing the OpenAPI definition.
For AWS CDK(on top of AWS CloudFormation) uses the intrinsic functions of CloudFormation(Fn::Join
) to archive it.
- REST API
1 const deployOptions = {
2 stageName: '',
3 loggingLevel: MethodLoggingLevel.ERROR,
4 dataTraceEnabled: false,
5 metricsEnabled: true,
6 tracingEnabled: false,
7 };
8 const restOpenAPISpec = this.resolve(Mustache.render(
9 fs.readFileSync(path.join(__dirname, './rest-sqs.yaml'), 'utf-8'),
10 variables));
11 new SpecRestApi(this, 'rest-to-sqs', {
12 apiDefinition: ApiDefinition.fromInline(restOpenAPISpec),
13 endpointExportName: 'APIEndpoint',
14 deployOptions,
15 });
- HTTP API
But above solution does not work with HTTP API
, because the CloudFormation of HTTP API
does not support intrinsic functions of CFN. 😥
The workaround is putting the OpenAPI definition to Amazon S3 firstly, then import it from S3 bucket via CloudFormation.
It involves putting the OpenAPI definition with dynamic resource information to S3 bucket before importing the OpenAPI definition from S3.
Here I leveage the CDK built-in custom resource to call S3 API to put the OpenAPI definition file to S3.
22/11/09 UPDATE: The Body of AWS::ApiGatewayV2::Api only supports the json object. It works after converting the Yaml OpenAPI definition to JSON!
1const yaml = require('js-yaml');
2
3...
4
5 // import openapi as http api
6 const variables = {
7 integrationRoleArn: apiRole.roleArn,
8 queueName: bufferQueue.queueName,
9 queueUrl: bufferQueue.queueUrl,
10 };
11 const openAPISpec = this.resolve(yaml.load(Mustache.render(
12 fs.readFileSync(path.join(__dirname, './http-sqs.yaml'), 'utf-8'), variables)));
13
14 const httpApi = new CfnApi(this, 'http-api-to-sqs', {
15 body: openAPISpec,
16 failOnWarnings: false,
17 });
The example code creates both REST API
and HTTP API
,
both of them forwards the events to Amazon SQS queue that are sent by HTTP POST requests.
See OpenAPI definition of HTTP to SQS, OpenAPI definition of REST to SQS
or complete source for further reference.
Posts in this series
- Build serverless web application with AWS Lambda web adapter
- Define your API via OpenAPI definition on AWS
- Setup DevOps pipeline with few code
- Federated OIDC login with Cognito and Amplify
- Protect website with Cognito
- Distribute the website globally
- Build no code restful HTTP API with API Gateway and DynamoDB
- Build serverless web application with AWS Serverless
- 无服务器架构的Docker镜像数据分析应用
- 无服务器架构的域名重定向服务
- Spring Cloud Function -- 跨Serverless平台的函数计算框架
- 基于函数计算的钉钉回调函数接口