«1. Обзор

В этом руководстве мы узнаем, как работать с объектами JSON в качестве параметров запроса с помощью OpenAPI.

2. Параметры запроса в OpenAPI 2

OpenAPI 2 не поддерживает объекты в качестве параметров запроса; поддерживаются только примитивные значения и массивы примитивов.

Из-за этого мы вместо этого захотим определить наш параметр JSON как строку.

Чтобы увидеть это в действии, давайте определим параметр с именем params в виде строки, даже если мы будем анализировать его как JSON в нашем бэкэнде:

swagger: "2.0"
...
paths:
  /tickets:
    get:
      tags:
      - "tickets"
      summary: "Send an JSON Object as a query param"
      parameters:
      - name: "params"
        in: "path"
        description: "{\"type\":\"foo\",\"color\":\"green\"}"
        required: true
        type: "string"

Таким образом, вместо:

GET http://localhost:8080/api/tickets?type=foo&color=green

мы что я сделаю:

GET http://localhost:8080/api/tickets?params={"type":"foo","color":"green"}

3. Параметры запроса в OpenAPI 3

OpenAPI 3 вводит поддержку объектов в качестве параметров запроса.

Чтобы указать параметр JSON, нам нужно добавить в определение раздел содержимого, который включает тип MIME и схему:

openapi: 3.0.1
...
paths:
  /tickets:
    get:
      tags:
      - tickets
      summary: Send an JSON Object as a query param
      parameters:
      - name: params
        in: query
        description: '{"type":"foo","color":"green"}'
        required: true
        schema:
          type: object
          properties:
            type:
              type: "string"
            color:
              type: "string"

Теперь наш запрос может выглядеть так:

GET http://localhost:8080/api/tickets?params[type]=foo&params[color]=green

И, собственно, он по-прежнему может выглядеть так:

GET http://localhost:8080/api/tickets?params={"type":"foo","color":"green"}

Первый вариант позволяет нам использовать проверки параметров, которые дадут нам знать, если что-то не так, до того, как будет сделан запрос.

Со вторым вариантом мы обмениваем это на больший контроль над серверной частью, а также на совместимость с OpenAPI 2.

4. Кодирование URL

Важно отметить, что, принимая решение о передаче параметров запроса в виде объекта JSON, мы хотим закодировать параметр в URL-адресе, чтобы обеспечить безопасную передачу.

Итак, чтобы отправить следующий URL-адрес:

GET /tickets?params={"type":"foo","color":"green"}

На самом деле мы бы сделали:

GET /tickets?params=%7B%22type%22%3A%22foo%22%2C%22color%22%3A%22green%22%7D

5. Ограничения

Также давайте помнить об ограничениях передачи объекта JSON в качестве набор параметров запроса:

    пониженная безопасность ограниченная длина параметров

Например, чем больше данных мы помещаем в параметр запроса, тем больше данных отображается в журналах сервера и тем выше вероятность раскрытия конфиденциальных данных.

Кроме того, один параметр запроса не может быть длиннее 2048 символов. Конечно, мы все можем представить себе сценарии, в которых наши объекты JSON больше этого размера. Практически говоря, URL-кодирование нашей строки JSON фактически ограничит нас примерно 1000 символами для нашей полезной нагрузки.

Одним из обходных путей является отправка больших объектов JSON в теле. Таким образом, мы устраняем как проблему безопасности, так и ограничение длины JSON.

Фактически, GET или POST поддерживают это. Одной из причин отправки тела через GET является поддержка семантики RESTful нашего API.

Конечно, это немного необычно и не везде поддерживается. Например, некоторые HTTP-библиотеки JavaScript не позволяют запросам GET иметь тело запроса.

Короче говоря, этот выбор является компромиссом между семантикой и универсальной совместимостью.

6. Заключение

Подводя итог, в этой статье мы узнали, как указывать объекты JSON в качестве параметров запроса с помощью OpenAPI. Затем мы наблюдали некоторые последствия для серверной части.

Полные определения OpenAPI для этих примеров доступны на GitHub.