| Шаг 1: объект openapi
| --> | Шаг 2: объект info
| --> | Шаг 3: объект servers
| --> | Шаг 4: объект paths
| --> | Шаг 5: объект components
| --> | Шаг 6: объект security
| --> | Шаг 7: объект tags
| --> | Шаг 8: объект externalDocs
|
Объект paths
содержит соль информации нашей API. Объект paths
имеет несколько подобъектов: объект Элемент пути
, объект Operation
и многое другое.
Мы двигались со скоростью около 5 км/ч на предыдущих этапах, но здесь мы собираемся разогнаться до 100 км/ч. Ничего страшного, если нет полного понимания следующего контента. Можно вставить пример кода, из этого раздела в Swagger UI, и позже вернуться, чтобы изучить его более подробно.
Примечание о зависимостях параметров
Объект
paths
- это та же «конечная точка» в соответствии с терминологии спецификации OpenAPI.
Каждый элемент в объекте path
содержит объект operations
. (operations
- это методы GET, POST, PUT и DELETE, которые мы изучали в разделе Конечные точки руководства по API.)
Начинаем с перечисления путей (конечных точек) и их разрешенных операций (методов). Для конечной точки weather
в API OpenWeatherMap есть только один путь (/weather
) и одна операция (get
) для этого пути:
paths:
/weather:
get:
Объект операции ( get
приведенный выше в коде) содержит различные свойства и объекты:
tags
: групповое имя для организации путей в интерфейсе Swagger. Swagger UI сгруппирует конечные точки под заголовками тегов.summary
: краткое описание пути. Swagger UI показывает описание рядом с именем пути. Ограничивают описание только 5-10 словами. Описание отображается и при свернутом разделе.description
: Полное описание пути. Может содержать неограниченное количество деталей. В Swagger UI достаточно места для полного описания. CommonMark Markdown разрешен.externalDocs
(объект): ссылка на документацию с доп.информацией о пути.operationId
: уникальный идентификатор пути.parameters
(объект): Параметры, принимаемые путем. Не включает параметры тела запроса, которые подробно описаны в объектеrequestBody
. Объектparameters
также может включать в себя объектreference
, который содержит указатель на описание в объектеcomponents
(этот объект описан на шаге 5: Объектcomponents
).requestBody
(объект): детали параметра тела запроса для этого пути. ОбъектrequestBody
также может включать в себя объектreference
, который содержит указатель на описание в объектеcomponents
(описание в шаге 5: Объектcomponents
).response
(объект): ответы, предоставленные на запросы по этому пути. Объектresponse
также может включать в себя объектreference
, который содержит указатель на описание в объектеcomponents
. Ответы используют стандартные коды состояния.callbacks
(объект): детали обратного вызова могут быть инициированы сервером при желании. Callbacks - это операции, выполняемые после завершения выполнения функции. Объектcallbacks
также может включать в себя объектreference
, который содержит указатель на описание в объектеcomponents
.deprecated
: Является ли путь устаревшим. Можно опустить, если вы не хотите указать устаревшее поле. Boolean.security
(объект): Метод безопасной авторизации, используемый с операцией. Этот объект добавляется на уровне пути, только если нужно перезаписать объектsecurity
на корневом уровне. Имя определяется объектомsecuritySchemes
в объектеcomponents
. Более подробная информация об этом представлена в шаге 6: объектsecurity
.servers
(объект): Объектservers
, который может отличаться от глобального объектаservers
для этого пути.
Каждое из вышеупомянутых свойств, имеющих гиперссылку и «(объект)», содержат дополнительные уровни. Их значения не просто типы данных, такие как строки, а скорее объекты, которые содержат свои собственные свойства.
Несомненно, нужно обращаться к спецификации OpenAPI, чтобы узнать, какие детали требуются для каждого из значений и объектов. На курсе нет возможности воспроизвести все нужные детали. Здесь просто поверхностное знакомство со свойствами OpenAPI.
Давайте добавим скелет объекта operations
к нашему коду:
paths:
/weather:
get:
tags:
summary:
description:
operationId:
externalDocs:
parameters:
responses:
deprecated:
security:
servers:
requestBody:
callbacks:
И удалим несколько ненужных полей, которые нам не нужны для нашей документации по API OpenWeatherMap:
- Нет необходимости включать объект
requestBody
потому что ни один путь API OpenWeatherMap не содержит параметров тела запроса. - Нет необходимости включать объект
servers
потому что используется тот же URL глобальныхservers
, который мы определили глобально на корневом уровне - Нет необходимости включать security потому что используется один и тот же объект
security
, который мы определим глобально на корневом уровне позже (см. Шаг 6: объектsecurity
). - Нет необходимости включать
deprecated
потому что ни один из путей не устарел. - Нет необходимости включать
callbacks
потому что ни один из путей не использует колбэки.
В результате мы можем уменьшить количество соответствующих полей до следующего:
paths:
/weather:
get:
tags:
summary:
description:
operationId:
externalDocs:
parameters:
responses:
Большинство свойств для объектов операции либо требуют простых строк, либо содержат относительно простые объекты. Наиболее подробные объекты здесь - это объект parameters
и объект responses
.
Объект parameters
содержит массив со следующими свойствами:
name
: имя параметра.in
: место параметра. Возможные значения:header
,path
,query
, илиcookie
. (Параметры тела запроса здесь не описаны.).description
: описание параметра.required
: требуется ли параметр.deprecated
: является ли параметр устаревшим.allowEmptyValue
: позволяет ли параметр передавать пустое значение.style
: как данные параметра сериализуются (преобразуются в байты во время передачи данных).explode
: расширенный параметр, связанный с массивами.allowReserved
: разрешены ли зарезервированные символы.schema
(объект): Схема или модель для параметра. Схема определяет структуру входных или выходных данных. Обратите внимание, чтоschema
также может содержать объектexample
.example
: пример типа носителя. Если объектexample
содержит примеры, эти примеры появляются в Swagger UI, а не в содержимом объектаexample
.examples
(объект): Пример типа носителя, включающий схему.
Вот объект paths
, который включает детали parameters
:
paths:
/weather:
get:
tags:
- Current Weather Data
summary: "Call current weather data for one location."
description: "Access current weather data for any location on Earth including over 200,000 cities! Current weather is frequently updated based on global models and data from more than 40,000 weather stations."
operationId: CurrentWeatherData
parameters:
- name: q
in: query
description: "**City name**. *Example: London*. You can call by city name, or by city name and country code. The API responds with a list of results that match a searching word. For the query value, type the city name and optionally the country code divided by a comma; use ISO 3166 country codes."
schema:
type: string
- name: id
in: query
description: "**City ID**. *Example: `2172797`*. You can call by city ID. The API responds with the exact result. The List of city IDs can be downloaded [here](http://bulk.openweathermap.org/sample/). You can include multiple cities in this parameter — just separate them by commas. The limit of locations is 20. *Note: A single ID counts as a one API call. So, if you have city IDs, it's treated as 3 API calls.*"
schema:
type: string
- name: lat
in: query
description: "**Latitude**. *Example: 35*. The latitude coordinate of the location of your interest. Must use with `lon`."
schema:
type: string
- name: lon
in: query
description: "**Longitude**. *Example: 139*. Longitude coordinate of the location of your interest. Must use with `lat`."
schema:
type: string
- name: zip
in: query
description: "**Zip code**. Search by zip code. *Example: 95050,us*. Please note that if the country is not specified, the search uses USA as a default."
schema:
type: string
- name: units
in: query
description: '**Units**. *Example: imperial*. Possible values: `standard`, `metric`, and `imperial`. When you do not use the `units` parameter, the format is `standard` by default.'
schema:
type: string
enum: [standard, metric, imperial]
default: "imperial"
- name: lang
in: query
description: '**Language**. *Example: en*. You can use lang parameter to get the output in your language. We support the following languages that you can use with the corresponded lang values: Arabic - `ar`, Bulgarian - `bg`, Catalan - `ca`, Czech - `cz`, German - `de`, Greek - `el`, English - `en`, Persian (Farsi) - `fa`, Finnish - `fi`, French - `fr`, Galician - `gl`, Croatian - `hr`, Hungarian - `hu`, Italian - `it`, Japanese - `ja`, Korean - `kr`, Latvian - `la`, Lithuanian - `lt`, Macedonian - `mk`, Dutch - `nl`, Polish - `pl`, Portuguese - `pt`, Romanian - `ro`, Russian - `ru`, Swedish - `se`, Slovak - `sk`, Slovenian - `sl`, Spanish - `es`, Turkish - `tr`, Ukrainian - `ua`, Vietnamese - `vi`, Chinese Simplified - `zh_cn`, Chinese Traditional - `zh_tw`.'
schema:
type: string
enum: [ar, bg, ca, cz, de, el, en, fa, fi, fr, gl, hr, hu, it, ja, kr, la, lt, mk, nl, pl, pt, ro, ru, se, sk, sl, es, tr, ua, vi, zh_cn, zh_tw]
default: "en"
- name: mode
in: query
description: "**Mode**. *Example: html*. Determines the format of the response. Possible values are `xml` and `html`. If the mode parameter is empty, the format is `json` by default."
schema:
type: string
enum: [json, xml, html]
default: "json"
Другое существенное свойство в объекте операций - это объект responses
. Для свойства responses
обычно ссылаются на полное определение в объекте components
, поэтому рассказ об объекте responses
в следующем разделе - Шаг 5. Объект components
. (На этом шаге уже слишком много информации.)
На данный момент, чтобы редактор Swagger проверил и показал наш путь, давайте просто добавим некоторый контент-заполнитель для responses
:
responses:
200:
description: Successful response
content:
application/json:
schema:
title: Sample
type: object
properties:
placeholder:
type: string
description: Placeholder description
404:
description: Not found response
content:
text/plain:
schema:
title: Weather not found
type: string
example: Not found
См. Describing Parameters в документации OpenAPI Swagger для более подробной информации.
Теперь давайте объединим два вышеупомянутых блока кода (и parameters
, и responses
) для нашего объекта paths
. Можем вставить этот код в редактор Swagger, добавляем наш объект paths
под кодом openapi
, info
и server
, которые мы добавили в предыдущих уроках.
paths:
/weather:
get:
tags:
- Current Weather Data
summary: "Call current weather data for one location."
description: "Access current weather data for any location on Earth including over 200,000 cities! Current weather is frequently updated based on global models and data from more than 40,000 weather stations."
operationId: CurrentWeatherData
parameters:
- name: q
in: query
description: "**City name**. *Example: London*. You can call by city name, or by city name and country code. The API responds with a list of results that match a searching word. For the query value, type the city name and optionally the country code divided by a comma; use ISO 3166 country codes."
schema:
type: string
- name: id
in: query
description: "**City ID**. *Example: `2172797`*. You can call by city ID. The API responds with the exact result. The List of city IDs can be downloaded [here](http://bulk.openweathermap.org/sample/). You can include multiple cities in this parameter — just separate them by commas. The limit of locations is 20. *Note: A single ID counts as a one API call. So, if you have city IDs, it's treated as 3 API calls.*"
schema:
type: string
- name: lat
in: query
description: "**Latitude**. *Example: 35*. The latitude coordinate of the location of your interest. Must use with `lon`."
schema:
type: string
- name: lon
in: query
description: "**Longitude**. *Example: 139*. Longitude coordinate of the location of your interest. Must use with `lat`."
schema:
type: string
- name: zip
in: query
description: "**Zip code**. Search by zip code. *Example: 95050,us*. Please note that if the country is not specified, the search uses USA as a default."
schema:
type: string
- name: units
in: query
description: '**Units**. *Example: imperial*. Possible values: `standard`, `metric`, and `imperial`. When you do not use the `units` parameter, the format is `standard` by default.'
schema:
type: string
enum: [standard, metric, imperial]
default: "imperial"
- name: lang
in: query
description: '**Language**. *Example: en*. You can use lang parameter to get the output in your language. We support the following languages that you can use with the corresponded lang values: Arabic - `ar`, Bulgarian - `bg`, Catalan - `ca`, Czech - `cz`, German - `de`, Greek - `el`, English - `en`, Persian (Farsi) - `fa`, Finnish - `fi`, French - `fr`, Galician - `gl`, Croatian - `hr`, Hungarian - `hu`, Italian - `it`, Japanese - `ja`, Korean - `kr`, Latvian - `la`, Lithuanian - `lt`, Macedonian - `mk`, Dutch - `nl`, Polish - `pl`, Portuguese - `pt`, Romanian - `ro`, Russian - `ru`, Swedish - `se`, Slovak - `sk`, Slovenian - `sl`, Spanish - `es`, Turkish - `tr`, Ukrainian - `ua`, Vietnamese - `vi`, Chinese Simplified - `zh_cn`, Chinese Traditional - `zh_tw`.'
schema:
type: string
enum: [ar, bg, ca, cz, de, el, en, fa, fi, fr, gl, hr, hu, it, ja, kr, la, lt, mk, nl, pl, pt, ro, ru, se, sk, sl, es, tr, ua, vi, zh_cn, zh_tw]
default: "en"
- name: mode
in: query
description: "**Mode**. *Example: html*. Determines the format of the response. Possible values are `xml` and `html`. If the mode parameter is empty, the format is `json` by default."
schema:
type: string
enum: [json, xml, html]
default: "json"
responses:
200:
description: Successful response
content:
application/json:
schema:
title: Sample
type: object
properties:
placeholder:
type: string
description: Placeholder description
404:
description: Not found response
content:
text/plain:
schema:
title: Weather not found
type: string
example: Not found
Отображение paths
в Swagger UI будет таким:
Чтобы увидеть подробности развернем наш раздел «Current Weather Data». Когда нажмем Try it out, вы увидите, что поле заполняется описанием. Если вы хотите, чтобы поле заполнялось значением, добавьте свойство default
в схему (как показано с параметром mode
в приведенном выше коде).
Однако, все параметры не могут быть переданы с одним и тем же запросом - вы используете только те параметры, которые вам нужны для запроса, который вы делаете. (Например, вы не можете передавать почтовый индекс и название города, а также широту / долготу и т.д. в одном запросе.) Поэтому не имеет смысла использовать значения по умолчанию для каждого параметра, поскольку тогда пользователю потребуется удалить большинство из них.
Swagger UI сворачивает каждый путь по умолчанию. Можно установить, будет ли начальное отображение свернуто или открыто, используя параметр
docExpansion
в Swagger UI. Этот параметрdocExpansion
предназначен для Swagger UI и не является частью спецификации OpenAPI. Swagger UI имеет более 20 различных параметров, которые управляют дисплеем. Например, если не хотите, чтобы отображался раздел "Models", нужно добавить параметрdefaultModelsExpandDepth: -1
в файл Swagger UI.
Спецификация OpenAPI не позволяет объявлять зависимости с параметрами или взаимоисключающими параметрами. В документации Swagger OpenAPI указано:
OpenAPI 3.0 не поддерживает зависимости параметров и взаимоисключающие параметры. Существует открытый запрос функции по адресу OAI/OpenAPI-Specification#256. Можно задокументировать ограничения в описании параметра и определить логику в ответе 400 Bad Request. (Parameter Dependencies)
В случае конечной точки погоды с OpenWeatherMap большинство параметров являются взаимоисключающими. Мы не можем выполнять поиск по идентификатору города и почтовому индексу одновременно. Хотя параметры являются необязательными, мы должны использовать хотя бы один параметр. Кроме того, при использовании параметра lat
, нужно использовать и параметр lon
, потому что это парные параметры. Спецификация OpenAPI не может программно отражать эту структурированную логику, поэтому мы должны объяснить это в свойстве description
или в другой, более концептуальной документации.