LoginSignup
0
0

APIGatewayを作成するときにOpenAPIから型情報を読み込み補完がきくようにしたメモ

Last updated at Posted at 2024-02-15

概要

API Gatewayの設定にOpenAPIを連携できないか検討した。
OpenAPIのJSONから型情報を読み込む形で実装してみたメモを残す。

検討

cdk - openapi-definitionを読むと、定義はすべてOpenAPIのほうに書く必要があるもよう。また、OpenAPIは3.1は使えず3.0か2.0を使う必要がある。

すべてのリソースとメソッドは OpenAPI 仕様ファイルの一部として定義する必要があり、CDK を介して追加することはできません。これは、これらのプロパティの重複や潜在的な混乱を防ぐためです。

こちらの記事で「OpenAPI定義にAWS用の設定値を記載するのが嫌だ」と言っているように、OpenAPIとAWSの設定は分けて管理したい。
記事中ではopenapixを使用しているが、1年更新がないのが不安。
型定義をOpenAPIから取り込む方法を考える。

構造

OpenAPIのフォルダとcdkのフォルダを分けて作成する。
以下はイメージ。

- openAPI
  - openapi.yaml # ... OpenAPIの定義ファイル
- cdk
  - data
    - openapi.json # ... OpenAPIの定義ファイルをJSONとしてエクスポートした生成ファイル
  - lib
    - stack.ts

StackファイルにOpenAPIの定義を適用する

yaml

OpenAPIから、Stackで使いたい情報をピックアップして記載する。

openapi: 3.1.0
paths:
  /tags:
    put:
      summary: タグ情報永続化
  /scenario/{scenarioId}/tags:
    get:
      summary: シナリオタグサマリー取得
  /scenario:
    get:
      summary: シナリオ一覧取得

これをもとに、下記のように補完が効くようにする。
yamlからjsonへの変換は、package.jsonでスクリプトにしている。(openapi-init)。
Stackを書く前に実行し、OpenAPIの情報を反映する必要がある。

image.png
image.png

rest-stack.ts

rest-stack.ts
// 省略
import openApi from '../data/openapi.json';

type OpenAPI = typeof openApi;
type Paths = OpenAPI['paths'];

export class KartaGraphRESTAPIStack extends core.Stack {
  private apiRoot: apigateway.Resource;
  // 省略

  private createAPILambdaResource<T extends keyof Paths>(path: T, method: keyof Paths[T], props: Partial<NodejsFunctionProps>) {
    const methodStr = method as string; // 型が合わない(string | number | Symbol とみなされる)ので本来の型であるstringキャスト
    const lambda = this.createLambda(
      {
        ...props,
        // summary は 必ず入力するものとして、 any で逃げる
        description: (openApi as any).paths[path][method].summary,
      },
      `${methodStr}-${path}`,
    );
    const methodOptions = this.createMethodOptions({
      'method.request.header.Content-Type': true,
    });

    this.getResource(path).addMethod(methodStr.toUpperCase(), new LambdaIntegration(lambda), methodOptions);
  }

  // 省略

上記のようにジェネリックを使って、補完をできるようにした。
ただ、メソッドの中ではas stringas anyを使っているのが分かるように、うまく型予測することはできなかった。

パスからリソースを作る部分については、パスを分割しマップでキャッシュするヘルパー関数を作っている。(同じリソースは2回作ろうとするとエラーとなるため、すでにあるリソースは再利用する必要がある)

これでデプロイした結果が下記。
OpenAPIの情報をStackに反映することができた。

image.png

image.png

参考

cdk - openapi-definition
cdk - SpecRestApi
openapi-down-convert
OpenAPI を使用した REST API の設定
OpenAPI × AWS CDK × APIGateway でRest APIを管理する
AWS CDKで作ったAPI Gateway + LambdaからOpenAPIドキュメントを生成してみた
AWS CDKを使ってAPI Gateway(HTTPAPI)+LambdaをOpenAPIで定義してデプロイする
APIGatewayをCDKで構築するコツ
【TypeScript】Utility Typesをまとめて理解する
【TypeScript】Yaml を読み込んで(無理やり)型付けする

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0