web-dev-qa-db-ja.com

Swagger(OpenAPI)で相互に排他的なクエリパラメーターを定義する方法

このようにSwaggerに一連のパラメーターがあります

                    "parameters": [
                    {
                        "name": "username",
                        "description": "Fetch username by username/email",
                        "required": false,
                        "type": "string",
                        "paramType": "query"
                    },
                    {
                        "name": "site",
                        "description": "Fetch username by site",
                        "required": false,
                        "type": "string",
                        "paramType": "query"
                    },
                    {
                        "name": "survey",
                        "description": "Fetch username by survey",
                        "required": false,
                        "type": "string",
                        "paramType": "query"
                    }
                ],

1つのパラメーターを入力する必要がありますが、どちらを指定してもかまいません。他のパラメーターは空白のままにできます。これをSwaggerで表す方法はありますか?

32
lorless

残念ながら、これはSwaggerでは現在不可能です。 「必須」は単なるブール値であり、パラメーター間の相互依存関係を表す方法はありません。

あなたができる最善のことは、パラメータの説明で要件を明確にし、同じ行に沿ってカスタムの400 Bad Requestの説明を入れることです。

https://github.com/swagger-api/swagger-spec/issues/256 でこれをSwaggerの次のバージョンに実装する可能な方法についての議論が少しあります)

11

APIデザインの変更についてはどうですか?現在、1つのメソッド、3つのパラメーターがあります。私がよく理解している場合、ユーザーは常に正確に1つのパラメーターを指定する必要があり、残りの2つは未設定にする必要があります。

私にとって、APIは3つのエンドポイントのように使いやすくなります

/user/byName?name=
/user/bySite?name=
/user/bySurvey?name=
7
Bartosz Bilicki

OpenAPI 3. では、相互に排他的なパラメーターが可能です(一種)。

  • 相互に排他的なパラメーターをオブジェクトプロパティとして定義し、oneOfまたはmaxPropertiesを使用して、オブジェクトを1つのプロパティのみに制限します。
  • パラメータシリアル化メソッドstyle: formおよびexplode: trueを使用して、オブジェクトが?propName=valueとしてシリアル化されるようにします。

minPropertiesおよびmaxProperties制約を使用した例:

openapi: 3.0.0
...
paths:
  /foo:
    get:
      parameters:
        - in: query
          name: filter
          required: true
          style: form
          explode: true
          schema:
            type: object
            properties:
              username:
                type: string
              site:
                type: string
              survey:
                type: string
            minProperties: 1
            maxProperties: 1
            additionalProperties: false

oneOfの使用:

      parameters:
        - in: query
          name: filter
          required: true
          style: form
          explode: true
          schema:
            type: object
            oneOf:
              - properties:
                  username:
                    type: string
                required: [username]
                additionalProperties: false
              - properties:
                  site:
                    type: string
                required: [site]
                additionalProperties: false
              - properties:
                  survey:
                    type: string
                required: [survey]
                additionalProperties: false

oneOfを使用する別のバージョン:

      parameters:
        - in: query
          name: filter
          required: true
          style: form
          explode: true
          schema:
            type: object
            properties:
              username:
                type: string
              site:
                type: string
              survey:
                type: string
            additionalProperties: false
            oneOf:
              - required: [username]
              - required: [site]
              - required: [survey]

Swagger UIおよびSwagger Editorは、上記の例をまだサポートしていません(2018年3月現在)。 この問題 はパラメーターのレンダリング部分をカバーしているようです。


また、OpenAPI仕様リポジトリには クエリパラメータ間の相互依存性をサポートする の提案が公開されているため、仕様の将来のバージョンでは、このようなシナリオを定義するためのより良い方法が提供されるでしょう。

4
Helen

もう1つの方法は、列挙型のフィルタータイプパラメーターと、使用する値のフィルター値を渡すことです。

例: https://app.swaggerhub.com/api/craig_bayley/PublicAPIDemo/v1

必要に応じて、必要な場合とそうでない場合があります。ただし、1つが必要な場合は、両方とも必要です。

1
Craig Bayley