Apidog API 設計: Discriminator で型に応じた異なるパラメータ構造をマッチさせる方法

Oliver Kingsley

Oliver Kingsley

6 11月 2025

Apidog API 設計: Discriminator で型に応じた異なるパラメータ構造をマッチさせる方法

以前の記事「APIが複数のパラメータ構造を持つ場合の対処法」では、APIが異なるパラメータ構造を必要とする場合、ApidogでoneOfanyOf、またはallOfを使用してそれらを定義できることを説明しました。

これらのスキーマコンポジションを使用してパラメータ構造を設定し、パラメータにデータ型を識別するフィールドが含まれている場合、OpenAPI仕様のdiscriminator機能を使用することで、スキーマをより直感的に区別し、ドキュメントをさらに明確にすることができます。

Discriminatorとは?

OpenAPIにおいて、discriminatorの役割は、オブジェクト指向プログラミングにおける「ポリモーフィズム(多態性)」を実装することです。

簡単に言えば、共有プロパティとその一意な値を使用して、oneOfまたはanyOfリスト内のどの特定のスキーマを使用すべきかを明確に示します。

例えば、ペットショップでは、ペットを記述するためのスキーマを使用する必要があります。(そして、猫と犬は異なるプロパティを持っています。)

犬のスキーマは次のとおりです。

{

    "name": "Hotdog",

    "age": 3,

    "weight": 25.5,

    "petType": "dog",

    "breed": "Golden Retriever",

    "isVaccinated": true,

    "walkingSchedule": "Morning and Evening",

    "favoriteToys": ["Frisbee", "Tennis Ball"],

    "trainingLevel": "Intermediate"

}

猫のスキーマは次のとおりです。

{

    "name": "Meow",

    "age": 2,

    "weight": 4.2,

    "petType": "cat",

    "isVaccinated": true,

    "isIndoor": true,

    "litterBoxType": "Enclosed",

    "scratchingPostHeight": 120,

    "favoriteSleepingSpot": "Balcony"

}

ご覧のとおり、両方のスキーマにはpetTypenameageなどの共通フィールドがありますが、犬にはbreedwalkingScheduleなどの特定のフィールドがあり、猫にはisIndoorlitterBoxTypeなどの特定のフィールドがあります。

APIドキュメントを設計する際に、これらのスキーマを定義するためにoneOfのみを使用した場合、ドキュメントは技術的にはdogスキーマとcatスキーマを区別できます。しかし、各型の対応関係はあまり明確ではありません。読者は2つのスキーマタブを切り替えて比較する必要があり、パラメータが多い場合には混乱を招きます。

oneOfを使用して複数のスキーマを定義する

discriminatorを追加することで、ドキュメントにはドロップダウンメニューが表示され、読者はpetTypeの値(dogまたはcat)を選択できます。選択すると、ページは関連するフィールドを持つ正しいスキーマを自動的に表示します。これにより、複数のタブを比較する必要がなくなり、各スキーマ間の違いがはるかに明確になります。

discriminatorがスキーマをより明確にする

discriminatorは通常、oneOfまたはanyOfと一緒に使用されます。oneOfは可能なオブジェクトスキーマを定義し、discriminatorは選択されたタイプに基づいてどのスキーマを適用するかをパーサーに伝えます。

これにより、複雑なオブジェクトがより明確になり、ドキュメントのレンダリングやコード生成時にツールがタイプを自動的に区別するのに役立ちます。

discriminatorの設定プロパティ

discriminatorには2つの主要なプロパティが含まれています。

OpenAPIでの設定例:

discriminator:
  propertyName: petType
  mapping:
    dog: '#/components/schemas/Dog'
    cat: '#/components/schemas/Cat'

ApidogでのDiscriminatorの設定

Apidogは、discriminatorを2つの方法で設定することをサポートしています。

  1. GUI + JSON Schema
  2. OpenAPI仕様を直接インポートする

方法1:GUI + JSON Schema

まず、DogCatなどのスキーマをApidogで作成します。

Apidogでスキーマを定義する

これらのスキーマを使用したいエンドポイントを開き、リクエストまたはレスポンスボディエディタに移動します。

スキーマコンポジションとして定義したいフィールドを選択し、Advanced SettingsSchema CompositionsoneOfを選択します。

oneOfで、DogCatなど、必要なスキーマを参照します。

oneOfスキーマコンポジションのスキーマを参照する

これで、oneOfを通じて複数の可能なスキーマを定義しました。次に、これらのスキーマを区別する方法を指定するためにdiscriminatorを追加する必要があります。JSON Schemaをクリックしてコードモードに切り替えます。

ApidogのJSON Schemaエディタ

適切な場所(oneOfと同じ階層)にdiscriminator設定を追加します。例えば、次のようになります。

"discriminator": {
    "propertyName": "petType",
    "mapping": {
        "dog": "#/definitions/190704823",
        "cat": "#/definitions/190704706"
    }
}

mapping内の値(例:#/definitions/190704823)は、Apidogがスキーマ用に内部で生成する一意のIDです。各スキーマに対応するdefinitionsパスは、JSON Schema設定パネルで確認できます。

ApidogのJSON Schema設定パネル

設定が完了したら保存します。APIドキュメントでは、petTypeフィールドの値に基づいてオブジェクトタイプをインテリジェントに切り替えることができます。

方法2:OpenAPI仕様を直接インポートする

これはより標準的なアプローチであり、「デザインファースト」のワークフローに慣れているチームに特に適しています。

discriminatorを含んだOpenAPI仕様を作成し、それをApidogにインポートします。

例えば、OpenAPI仕様におけるdiscriminatorの定義は次のとおりです。

Pet:
  oneOf:
    - $ref: '#/components/schemas/Dog'
    - $ref: '#/components/schemas/Cat'
  discriminator:
    propertyName: petType
    mapping:
      dog: '#/components/schemas/Dog'
      cat: '#/components/schemas/Cat'

この定義は明確に以下のことを示しています。

完全なOpenAPI仕様は次のとおりです。

openapi: 3.0.3
info:
  title: Pet Shop API
  version: 1.0.0

components:
  schemas:
    Dog:
      type: object
      properties:
        petType:
          type: string
          enum: [dog]
        name:
          type: string
        age:
          type: integer
        weight:
          type: number
        breed:
          type: string
        isVaccinated:
          type: boolean
        walkingSchedule:
          type: string
        favoriteToys:
          type: array
          items:
            type: string
        trainingLevel:
          type: string
      required:
        - petType
        - name
        - age

    Cat:
      type: object
      properties:
        petType:
          type: string
          enum: [cat]
        name:
          type: string
        age:
          type: integer
        weight:
          type: number
        isVaccinated:
          type: boolean
        isIndoor:
          type: boolean
        litterBoxType:
          type: string
        scratchingPostHeight:
          type: integer
        favoriteSleepingSpot:
          type: string
      required:
        - petType
        - name
        - age

    Pet:
      oneOf:
        - $ref: '#/components/schemas/Dog'
        - $ref: '#/components/schemas/Cat'
      discriminator:
        propertyName: petType
        mapping:
          dog: '#/components/schemas/Dog'
          cat: '#/components/schemas/Cat'

paths:
  /pets:
    get:
      summary: Get pet information
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pet'

OpenAPI仕様が完成したら、Apidogのimport機能を使用します。Apidogはすべての仕様を解析し、対応するスキーマとエンドポイントを自動的に作成し、discriminator設定を正しく認識します(ここではパラメータ値を固定するためにenumが追加されています)。

OpenAPIをインポートして複数のスキーマを区別するdiscriminatorを追加する

よくある質問

1. Discriminatorはいつ使用すべきですか?

discriminatorは、エンドポイントにすでにスキーマを識別するフィールドが含まれている場合にのみ使用すべきです。上記の例では、API設計にpetTypeフィールドが存在し、ペットの種類を区別するために使用されています。

discriminatorは、そのフィールドの値に基づいて正しいスキーマを選択する方法をツールに伝えるだけです。

エンドポイントにそのような型識別フィールドが含まれていない場合、discriminatorは適切ではありません。その場合はoneOfのみで十分です。

また、スキーマがシンプルであるか、バリエーションが少ない場合は、そもそもdiscriminatorは必要ないかもしれません。

2. DiscriminatorはoneOfと一緒に使用する必要がありますか?

はい。discriminatorはoneOfanyOf、またはallOfと一緒に使用する必要があります。それ自体でスキーマを定義することはできず、複数の可能なスキーマを区別する方法を説明するだけです。

結論

discriminatorは、oneOf/anyOf/allOfのユーザーエクスペリエンスを向上させるために使用されるOpenAPI仕様のオプション機能です。

エンドポイントの仕様にすでにタイプを識別するために使用されるフィールドが含まれている場合、Apidogでdiscriminatorを設定することで、APIドキュメントをより明確でインテリジェントにすることができます。

もちろん、設定が面倒だと感じる場合や、スキーマが比較的シンプルな場合は、oneOfのようなスキーマコンポジションのみを完全に利用することも可能です。

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる