Swagger Mock - сервер для генерирования фиктивных ответов API
Уже довольно продолжительное время я практикую подход Design First в web-разработке. Одним из удобных инструментов этого подхода является ведение документации в формате OpenAPI / Swagger. Обычно при поступлении задачи от бизнеса собираются front-end и back-end разработчики и составляют контракт в виде описания API endpoint’ов. Затем разработка разделяется и каждый работает со своей частью.
На пути разработки front-end части кроется трудность в том, что нельзя делать обращения к API в это время, т.к. оно не готово. На помощь могут придти различные mock-библиотеки для локальной разработки (без обращения к серверу) или серверные приложения, которые могут отдавать “фейковые” данные.
Где-то полгода назад мы начали активно описывать документацию в новой версии формата OpenAPI v3.0. В этот момент я столкнулся с неожиданной для себя ситуацией - не нашел ни одного удовлетворяющего наши требования mock-сервера. Большинство решений (см. Mock Servers) либо поддерживало только вторую версию спецификации, либо основывалось на выдаче ответов по примерам (examples). Постоянно расписывать и поддерживать примеры для 100+ endpoint’ов занятие довольно неприятное. Хотелось бы иметь какой-то инструмент, который мог бы генерировать данные хотя бы по указанным типам и форматам. Поэтому я решил написать свое решение.
Основные возможности
Исходный код mock-сервера https://github.com/swagger-mock/swagger-mock
Docker-образ https://hub.docker.com/r/swaggermock/swagger-mock
Ключевые особенности Swagger Mock Server
- Поддержка спецификации OpenAPI v3.0
- Загрузка спецификации по URL или из локального файла
- Поддержка файлов в формате JSON и YAML
- Генерирование фиктивных данных по указанным схемам
- Выбор возвращаемого ответа по HTTP-заголовку Accept
- Запуск в Docker-контейнере
Ограничения на текущий момент
- Не поддерживаются теги xml - генерирование данных в xml производится только по минимальной схеме
- Не поддерживается разрешение ссылок $ref по файлам и URL
- Входные данные из тела запроса не валидируются
Инструкция по запуску
Docker-контейнер + консольные команды
Наиболее простой способ запуска сервера - запуск с помощью Docker контейнера. Документацию по установке и настройке докера можно найти по ссылке https://docs.docker.com/install/.
docker pull swaggermock/swagger-mock
# загрузка спецификации по URL-ссылке
docker run -p 8080:8080 -e "SWAGGER_MOCK_SPECIFICATION_URL=https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml" --rm swaggermock/swagger-mock
# загрузка спецификации из локального файла, проброшенного через volume
docker run -p 8080:8080 -v $PWD/examples/petstore.yaml:/openapi/petstore.yaml -e "SWAGGER_MOCK_SPECIFICATION_URL=/openapi/petstore.yaml" --rm swaggermock/swagger-mock
Docker-контейнер + Docker Compose
Также, довольно удобно использовать Docker Compose. Инструкция по установке - https://docs.docker.com/compose/install/. Пример файла docker-compose.yml
для загрузки спецификации по URL-ссылке.
version: '3.0'
services:
swagger_mock:
container_name: swagger_mock
image: swaggermock/swagger-mock
environment:
SWAGGER_MOCK_SPECIFICATION_URL: 'https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml'
ports:
- "8080:8080"
Пример файла docker-compose.yml
для загрузки спецификации по из локального файла.
version: '3.0'
services:
swagger_mock:
container_name: swagger_mock
image: swaggermock/swagger-mock
environment:
SWAGGER_MOCK_SPECIFICATION_URL: '/openapi/petstore.yaml'
volumes:
- ./examples/petstore.yaml:/openapi/petstore.yaml
ports:
- "8080:8080"
Запуск локально сервера осуществляется консольной командой
docker-compose up -d
Пример использования
Если отправить HTTP-запрос GET http://localhost:8080/pets
при использовании указанной выше спецификации (petstore.yaml), то можно будет увидеть примерно такой ответ:
HTTP/1.1 200 OK
Cache-Control: no-cache, private
Content-Type: application/json; charset=utf-8
Date: Fri, 22 Feb 2019 18:36:27 GMT
Transfer-Encoding: chunked
[
{
"id": 1879967382,
"name": "Rerum omnis quisquam aut consectetur velit. Dolore non molestiae excepturi veritatis soluta inventore. Delectus minima quis quaerat veniam earum molestiae.",
"tag": "Qui aliquid ut quia voluptas. Dolorum aut tenetur eligendi delectus et omnis non."
},
...
]
Как видно, качество генерируемых данных зависит напрямую от точности спецификации. Если у вас есть ограничения по длине строк, формату, размеру массивов, то их необходимо указывать в спецификации. В качестве примера возьмем другую модель (полный текст по ссылке).
components:
schemas:
Person:
required:
- id
- email
- name
- birthDate
properties:
id:
type: string
format: uuid
email:
type: string
format: email
name:
type: string
maxLength: 20
birthDate:
type: string
format: date
tags:
type: array
minItems: 0
maxItems: 3
items:
type: string
maxLength: 10
При HTTP-запросе GET http://localhost:8080/persons
получится такой ответ.
HTTP/1.1 200 OK
Cache-Control: no-cache, private
Content-Type: application/json; charset=utf-8
Date: Fri, 22 Feb 2019 18:56:35 GMT
Content-Length: 1392
[
{
"id": "09e5561c-eee7-3c4e-9ac8-780eae82eb08",
"email": "joaquin73@hotmail.com",
"name": "Sit id nam veniam.",
"birthDate": "2005-02-04",
"tags": [
"Nesciunt.",
"Enim est.",
"Non."
]
},
...
]
Настройки
Переменные окружения
Mock-сервер настраивается через переменные окружения.
SWAGGER_MOCK_SPECIFICATION_URL
- Путь к файлу спецификации OpenAPI v3 (обязательный)
- Возможные значения: любой правильный URL-адрес или путь к файлу
SWAGGER_MOCK_LOG_LEVEL
- Уровень логирования
- Значение по умолчанию:
warning
- Возможные значения:
error
,warning
,info
,debug
SWAGGER_MOCK_CACHE_DIRECTORY
- Директория для хранения кеша спецификации
- Значение по умолчанию:
/dev/shm/openapi-cache
- Возможные значения: любой правильный путь к существующей директории
SWAGGER_MOCK_CACHE_TTL
- Время жизни кеша спецификации в секундах
- Значение по умолчанию: 0
- Возможные значения: любое положительное целое число
SWAGGER_MOCK_CACHE_STRATEGY
- Стратегия кеширования спецификации OpenAPI
- Значение по умолчанию:
disabled
- Возможные значения:
disabled
,url_md5
,url_and_timestamp_md5
Кеш спецификации
При поведении по умолчанию на каждый запрос к серверу происходит парсинг файла спецификации и преобразование его в набор объектов, используемых для генерирования ответа API. Для спецификаций с большим количеством endpoint’ов парсинг может занимать ощутимое время. Для улучшения производительности предусмотрено кеширование результатов парсинга исходя из различных стратегий. Стратегия кеширования задается с помощью переменной окружения SWAGGER_MOCK_CACHE_STRATEGY
.
- При использовании значения
url_md5
сервер вычисляет md5-хеш по URL и если он не изменился, то используются объекты из кеша. - При использовании
url_and_timestamp_md5
сервер составляет md5-хеш по URL и временной метке (время последнего изменения файла или значение заголовкаLast-Modified
при обращении по URL к удаленному ресурсу). Если вы используете файл на удаленном сервере, то при выборе данной стратегии необходимо убедиться, что сервер добавляет правильный заголовокLast-Modified
к ответу за запрос.
Рекомендуемые значения при использовании файла на удаленном сервере, доступном по URL.
SWAGGER_MOCK_CACHE_STRATEGY='url_md5'
SWAGGER_MOCK_CACHE_TTL=3600
Рекомендуемые значения при использовании локального файла.
SWAGGER_MOCK_CACHE_STRATEGY='url_and_timestamp_md5'
SWAGGER_MOCK_CACHE_TTL=3600
Предложения, пожелания, замечания
Буду рад увидеть любые предложения, пожелания или замечания, а так же баг-репорты. В случае возникновения проблем, пожалуйста, заведите issue на GitHub’е https://github.com/swagger-mock/swagger-mock/issues.
При обнаружении бага, запустите mock-сервер с уровнем логирования SWAGGER_MOCK_LOG_LEVEL=debug
и пришлите содержимое лога docker logs swagger_mock
при воспроизведении ошибки. Это поможет быстрее разобраться с багом. Спасибо!