@alma-cdk/openapix

中文文档
2.0.1发布于 2026/08/10Apache-2.0TypeScriptCommonJS构建来源已验证近 30 天下载 1.5万

Combine the power of AWS CDK & OpenAPI YAML Schema Definitions

原始使用文档
文档目录14 节
  1. 🚧 Project Stability
  2. Getting Started
  3. HTTP Integration
  4. Lambda Integration
  5. AWS Service Integration
  6. Mock Integration
  7. Validators
  8. Authorizers
  9. Cognito Authorizers
  10. Lambda Authorizers
  11. Inject/Reject
  12. CORS
  13. Default CORS
  14. API Gateway EndpointType


Alma CDK OpenApiX

npm i -D @alma-cdk/openapix

Generate AWS Api Gateway REST APIs via OpenAPI (formely known as “Swagger”) Schema Definitions by consuming "clean" OpenAPI schemas and inject x-amazon-apigateway- extensions with type-safety.



diagram


🚧   Project Stability

experimental

This construct is still versioned with v0 major version and breaking changes might be introduced if necessary (without a major version bump), though we aim to keep the API as stable as possible (even within v0 development). We aim to publish v1.0.0 soon and after that breaking changes will be introduced via major version bumps.

There are also some incomplete or buggy features, such as CORS and CognitoUserPoolsAuthorizer.


Getting Started

  1. Install npm i -D @alma-cdk/openapix

  2. Define your API OpenApi Schema Definition in a .yaml file
    without any x-amazon-apigateway- extensions

  3. Use openapix constructs in CDK to consume the .yaml file and then assign API Gateway integrations using CDK


HTTP Integration

Given the following http-proxy.yaml OpenApi schema definition, without any AWS API Gateway OpenApi extensions:

openapi: 3.0.3
info:
  title: HTTP Proxy
  description: Proxies requests to example.com
  version: "0.0.1"
paths:
  "/":
    get:
      summary: proxy
      description: Proxies example.com

You may then define API Gateway HTTP integration (within your stack):

new openapix.Api(this, 'HttpProxy', {
  source: path.join(__dirname, '../schema/http-proxy.yaml'),

  paths: {
    '/': {
      get: new openapix.HttpIntegration(this, 'http://example.com', {
          httpMethod: 'get',
      }),
    },
  },
});

See /examples/http-proxy for full OpenApi definition (with response models) and an example within a CDK application.


Lambda Integration

Given the following hello-api.yaml OpenApi schema definition, without any AWS API Gateway OpenApi extensions:

openapi: 3.0.3
info:
  title: Hello API
  description: Defines an example “Hello World” API
  version: "0.0.1"
paths:
  "/":
    get:
      operationId: sayHello
      summary: Say Hello
      description: Prints out a greeting
      parameters:
      - name: name
        in: query
        required: false
        schema:
          type: string
          default: "World"
      responses:
        "200":
          description: Successful response
          content:
            "application/json":
              schema:
                $ref: "#/components/schemas/HelloResponse"

components:
  schemas:
    HelloResponse:
      description: Response body
      type: object
      properties:
        message:
          type: string
          description: Greeting
          example: Hello World!

You may then define API Gateway AWS Lambda integration (within your stack):

const greetFn = new NodejsFunction(this, 'greet');

new openapix.Api(this, 'HelloApi', {
  source: path.join(__dirname, '../schema/hello-api.yaml'),
  paths: {
    '/': {
      get: new openapix.LambdaIntegration(this, greetFn),
    },
  },
})

See /examples/hello-api for full OpenApi definition (with response models) and an example within a CDK application.


AWS Service Integration

Given books-api.yaml OpenApi schema definition, without any AWS API Gateway OpenApi extensions, You may then define API Gateway AWS service integration such as DynamoDB (within your stack):

new openapix.Api(this, 'BooksApi', {
  source: path.join(__dirname, '../schema/books-api.yaml'),
  paths: {
    '/': {
      get: new openapix.AwsIntegration(this, {
        service: 'dynamodb',
        action: 'Scan',
        options: {
          credentialsRole: role, // role must have access to DynamoDB table
          requestTemplates: {
            'application/json': JSON.stringify({
              TableName: table.tableName,
            }),
          },
          integrationResponses: [
            {
              statusCode: '200',
              responseTemplates: {
                // See /examples/http-proxy/lib/list-books.vtl
                'application/json': readFileSync(__dirname+'/list-books.vtl', 'utf-8'),
              },
            }
          ],
        },
      }),
    },
    '/{isbn}': {
      get: new openapix.AwsIntegration(this, {
        service: 'dynamodb',
        action: 'GetItem',
        options: {
          credentialsRole: role, // role must have access to DynamoDB table
          requestTemplates: {
            'application/json': JSON.stringify({
              TableName: table.tableName,
              Key: {
                item: {
                  "S": "$input.params('isbn')"
                }
              }
            }),
          },
          integrationResponses: [
            {
              statusCode: '200',
              responseTemplates: {
                // See /examples/http-proxy/lib/get-book.vtl
                'application/json': readFileSync(__dirname+'/get-book.vtl', 'utf-8'),
              },
            }
          ],
        },
      }),
    },
  },
});

See /examples/books-api for full OpenApi definition (with response models) and an example within a CDK application.


Mock Integration

Given the following mock-api.yaml OpenApi schema definition, without any AWS API Gateway OpenApi extensions:

openapi: 3.0.3
info:
  title: Hello API
  description: Defines an example “Hello World” API
  version: "0.0.1"
paths:
  "/":
    get:
      operationId: sayHello
      summary: Say Hello
      description: Prints out a greeting
      parameters:
      - name: name
        in: query
        required: false
        schema:
          type: string
          default: "World"
      responses:
        "200":
          description: Successful response
          content:
            "application/json":
              schema:
                $ref: "#/components/schemas/HelloResponse"

components:
  schemas:
    HelloResponse:
      description: Response body
      type: object
      properties:
        message:
          type: string
          description: Greeting
          example: Hello World!

You may then define API Gateway Mock integration (within your stack):

new openapix.Api(this, 'MockApi', {
  source: path.join(__dirname, '../schema/mock-api.yaml'),
  paths: {
    '/': {
      get: new openapix.MockIntegration(this, {
        requestTemplates: {
          "application/json": JSON.stringify({ statusCode: 200 }),
        },
        passthroughBehavior: apigateway.PassthroughBehavior.NEVER,
        requestParameters: {
          'integration.request.querystring.name': 'method.request.querystring.name',
        },
        integrationResponses: [
          {
            statusCode: '200',
            responseTemplates: {
              // see /examples/mock-api/lib/greet.vtl
              'application/json': readFileSync(__dirname+'/greet.vtl', 'utf-8'),
            },
            responseParameters: {},
          },
        ],
      }),
    },
  },
});

See /examples/mock-api for full OpenApi definition (with response models) and an example within a CDK application.


Validators

API Gateway REST APIs can perform request parameter and request body validation. You can provide both default validator and integration specific validator (which will override the default for given integration).

See /examples/todo-api for complete example within a CDK application.

Given todo-api.yaml OpenApi schema definition you may define the API Gateway validators for your integration in CDK:

new openapix.Api(this, 'MyApi', {
  source: path.join(__dirname, '../schema/todo-api.yaml'),

  validators: {
    'all': {
      validateRequestBody: true,
      validateRequestParameters: true,
      default: true, // set this as the "API level" default validator (there can be only one)
    },
    'params-only' : {
      validateRequestBody: false,
      validateRequestParameters: true,
    },
  },

  paths: {
    '/todos': {
      // this one uses the default 'all' validator
      post:  new openapix.HttpIntegration(this, baseUrl, { httpMethod: 'post' }),
    },
    '/todos/{todoId}': {
      // this one has validator override and uses 'params-only' validator
      get: new openapix.HttpIntegration(this, `${baseUrl}/{todoId}`, {
        validator: 'params-only',
        options: {
          requestParameters: {
            'integration.request.path.todoId': 'method.request.path.todoId',
          },
        },
      }),
    },
  },
})

Authorizers

🚧 Work-in-Progress

There are multiple ways to control & manages access to API Gateway REST APIs such as resource policies, IAM permissions and usage plans with API keys but this section focuses on Cognito User Pools and Lambda authorizers.


Cognito Authorizers

In this example we're defining a Congito User Pool based authorizer.

Given the following schema.yaml OpenApi definition:

openapi: 3.0.3
paths:
  /:
    get:
      security:
        - MyAuthorizer: ["test/read"] # add scope
components:
  securitySchemes:
    MyCognitoAuthorizer:
      type: apiKey
      name: Authorization
      in: header

You can define the Cognito Authorizer in CDK with:

const userPool: cognito.IUserPool;

new openapix.Api(this, 'MyApi', {
  source: './schema.yaml',

  authorizers: [
    new openapix.CognitoUserPoolsAuthorizer(this, 'MyCognitoAuthorizer', {
      cognitoUserPools: [userPool],
      resultsCacheTtl: Duration.minutes(5),
    })
  ],
})

Lambda Authorizers

In this example we're defining a custom Lambda authorizer. The authorizer function code is not relevant for the example but the idea in the example is that an API caller sends some "secret code" in query parameters (?code=example123456) which then the authorizer function somehow evaluates.

Given the following schema.yaml OpenApi definition:

openapi: 3.0.3
paths:
  /:
    get:
      security:
        - MyAuthorizer: [] # note the empty array
components:
  securitySchemes:
    MyCustomAuthorizer:
      type: apiKey
      name: code
      in: query

You can define the custom Lambda Authorizer in CDK with:

const authFn: lambda.IFunction;

new openapix.Api(this, 'MyApi', {
  source: './schema.yaml',

  authorizers: [

    new openapix.LambdaAuthorizer(this, 'MyCustomAuthorizer', {
      fn: authFn,
      identitySource: apigateway.IdentitySource.queryString('code'),
      type: 'request',
      authType: 'custom',
      resultsCacheTtl: Duration.minutes(5),
    }),
  ],


})

Inject/Reject

You may modify the generated OpenAPI definition (which is used to define API Gateway REST API) by injecting or rejecting values from the source OpenAPI schema definition:

new openapix.Api(this, 'MyApi', {
  source: './schema.yaml',

  // Add any OpenAPI v3 data.
  // Can be useful for passing values from CDK code.
  // See https://swagger.io/specification/
  injections: {
    "info.title": "FancyPantsAPI"
  },

  // Reject fields by absolute object path from generated definition
  rejections: ['info.description'],

  // Reject all matching fields from generated definition
  rejectionsDeep: ['example', 'examples'],
});

CORS

🚧 Work-in-Progress

Using openapix.CorsIntegration creates a Mock integration which responds with correct response headers:

new openapix.Api(this, 'MyApi', {
  source: './schema.yaml',

  paths: {
    '/foo': {
      options: new openapix.CorsIntegration(this, {
        // using helper method to define explicit values:
        headers: CorsHeaders.from(this, 'Content-Type', 'X-Amz-Date', 'Authorization'),
        origins: CorsOrigins.from(this, 'https://www.example.com'),
        methods: CorsMethods.from(this, 'options','post','get'),
      }),
    },
    '/bar': {
      options: new openapix.CorsIntegration(this, {
        // using regular string values:
        headers: 'Content-Type,X-Amz-Date,Authorization',
        origins: '*',
        methods: 'options,get',
      }),
    },
    '/baz': {
      options: new openapix.CorsIntegration(this, {
        // using helper constant for wildcard values:
        headers: CorsHeaders.ANY,
        origins: CorsOrigins.ANY,
        methods: CorsMethods.ANY,
      }),
    },
  },
});

When specifying multiple origins the mock integration uses VTL magic to respond with the correct Access-Control-Allow-Origin header.

Default CORS

If you wish to define same CORS options to every path, you may do so by providing a default cors value:

new openapix.Api(this, 'MyApi', {
  source: './schema.yaml',

  defaultCors: new openapix.CorsIntegration(this, {
    headers: CorsHeaders.ANY,
    origins: CorsOrigins.ANY,
    methods: CorsMethods.ANY,
  }),

  paths: {/*...*/},
});

This will apply the given cors configuration to every path as options method. You may still do path specific overrides by adding an options method to specific paths.


API Gateway EndpointType

AWS CDK API Gateway constructs default to Edge-optimized API endpoints by using EndpointType.EDGE as the default.

This construct @alma-cdk/openapix instead defaults to using Regional API endpoints by setting EndpointType.REGIONAL as the default value. This is because we believe that in most cases you're better of by configuring your own CloudFront distribution in front the API. If you do that, you might also be interested in @alma-cdk/origin-verify construct.

You MAY override this default in @alma-cdk/openapix by providing your preferred endpoint types via restApiProps:

new openapix.Api(this, 'MyApi', {
  source: './schema.yaml',

  paths: {/*...*/},

  restApiProps: {
    endpointConfiguration: {
      types: [ apigateway.EndpointType.EDGE ],
    },
  },
});

版本与发布记录

@alma-cdk/openapix 共发布 54 个版本,首次发布于 2022/05/21;过去 12 个月发布了 8 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.0.1latest2026/08/102 个月前
2.0.02026/08/102 个月前
1.0.42026/08/102 个月前
1.0.32026/04/076 个月前
1.0.22026/04/027 个月前
1.0.12026/04/027 个月前

其他发布通道:beta → 1.0.0-beta.4。

关于 @alma-cdk/openapix 的常见问题

@alma-cdk/openapix 是什么?

Combine the power of AWS CDK & OpenAPI YAML Schema Definitions

如何安装 @alma-cdk/openapix?

在项目目录运行 npm install @alma-cdk/openapix,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:aws-cdk-lib(^2.260.0)、constructs(^10.7.2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@alma-cdk/openapix 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@alma-cdk/openapix 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@alma-cdk/openapix 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >= 22 <= 26。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@alma-cdk/openapix 可以商用吗?

@alma-cdk/openapix 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@alma-cdk/openapix 的下载量有多少?

根据 npm 官方下载统计,@alma-cdk/openapix 在 2026/10/06 – 2026/11/04 这 30 天内被下载 14,803 次,日均约 493 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@alma-cdk/openapix 还在维护吗?

最新版本 2.0.1 发布于 2026/08/10(2 个月前);至今共发布 54 个版本,其中过去 12 个月发布了 8 个;首次发布于 2022/05/21。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。