Как определить взаимоисключающие параметры запроса в 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"
}
],
Один параметр ДОЛЖЕН быть заполнен, но неважно, какой из них, остальные могут быть оставлены пустыми. Есть ли способ представить это в Swagger?
Ответы
Ответ 1
К сожалению, в настоящее время это невозможно в Swagger. "required" - это просто логическое выражение, и нет возможности представлять взаимозависимости между параметрами.
Лучшее, что вы можете сделать, это сделать четкие требования в описаниях параметров, а также добавить пользовательское описание 400 Bad Request в тех же строках.
(Там немного обсуждается https://github.com/swagger-api/swagger-spec/issues/256 о возможных способах реализации этого в следующей версии Swagger)
Ответ 2
Как насчет изменения дизайна API?
В настоящее время у вас есть один метод, 3 параметра. Если я хорошо понимаю, пользователь должен всегда предоставлять только один параметр, а два оставшихся должны быть отменены.
Для меня API будет более удобным для использования с тремя конечными точками, такими как
/user/byName?name=
/user/bySite?name=
/user/bySurvey?name=
Ответ 3
В OpenAPI 3.0 возможны взаимозависимые параметры (вид):
- Определите взаимоисключающие параметры как свойства объекта и используйте
oneOf
или maxProperties
чтобы ограничить объект только maxProperties
свойством. - Используйте
style: form
метода сериализации параметров 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 и редактор Swagger не поддерживают приведенные выше примеры (по состоянию на март 2018 года). Эта проблема, похоже, охватывает часть рендеринга параметров.
Кроме того, в репозитории OpenAPI Specification открыто предложение для поддержки взаимозависимостей между параметрами запроса, поэтому, возможно, будущие версии Спецификации будут иметь лучший способ определить такие сценарии.
Ответ 4
Альтернативой является передача в параметре типа фильтра с перечислением и значение фильтра со значением, которое будет использоваться.
Пример: https://app.swaggerhub.com/api/craig_bayley/PublicAPIDemo/v1
Это может потребоваться или нет, по вашему выбору. Однако, если требуется, они оба должны быть.