0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

同名のネストrecordでOpenAPIスキーマが衝突する原因と対策

0
Posted at

問題

フロントエンドでOpenAPIから生成した型を使用したところ、response.itemのフィールドが想定と異なり、productCodeを参照できませんでした。

response.item.productCode;
// productCodeが存在しないという型エラー

バックエンドのレスポンスは正しく、生成された型定義だけが一致していませんでした。

原因

原因は、OpenAPI生成処理がネストrecordを識別する際、外側のクラスを含む完全修飾名ではなく、単純な型名をスキーマ名として使用していたことです。

public record CreateOrderResponse(Item item) {

    public record Item(String productCode) {}
}

public record CancelOrderResponse(Item item) {

    public record Item(String reason) {}
}

Javaではそれぞれ別の型ですが、OpenAPIではどちらも同じItemスキーマとして登録されていました。

["components"]["schemas"]["Item"]

スキーマ名が重複したことで、一方の定義が正しく登録されず、productCodeまたはreasonの片方しかOpenAPIに反映されませんでした。これが、Swagger UIに実際のJavaコードと異なるフィールドが表示された原因です。

対処法

ネストrecordの名前が重複しないよう、それぞれに固有の名前を付けました。

public record CreateOrderResponse(CreateOrderItem item) {

    public record CreateOrderItem(String productCode) {}
}

public record CancelOrderResponse(CancelOrderItem item) {

    public record CancelOrderItem(String reason) {}
}

これにより別々のスキーマとして生成され、各フィールドが正しくOpenAPIへ反映されました。修正後はOpenAPIを再生成し、フロントエンドの型定義も更新しました。

さらに再発を防ぐなら、ネストrecordを独立したファイルに定義する方法も有効です。型名の重複に気づきやすくなり、同様のスキーマ名衝突を防ぎやすくなります。

まとめ

同名のネストrecordはOpenAPI生成時にスキーマの衝突を引き起こすことがあるため、公開する型には固有の名前を付け、生成結果まで確認することが重要です。

0
0
1

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?