OpenAPI Comparator — детектор изменений, ломающих [большие] API

от автора

Защита от изменений API, которые могут повлиять на ваших клиентов, — одна из самых больших проблем при разработке HTTP API. Если вы вносите критические изменения, то создаете клиентам серьёзные проблемы. Стабильный API — ключ к удовлетворенности клиентов и, в конечном счете, к успеху в бизнесе.

Но есть одна загвоздка: потребности клиентов меняются, что часто требует развития самого API. Например, добавления параметров для работы с данным ресурсом или удаления других параметров для упрощения всего API.

Предотвращение критических изменений затрудняется по мере роста API. С более чем 250 конечными точками API мы достигли момента, когда ручное обнаружение критических изменений стало несостоятельным. Вот почему мы искали автоматизированное решение.

Что такое критическое изменение?

В двух словах, критическое изменение — это изменение в API, способное вызвать сбои в использующих API приложениях.

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

Не все изменения являются критическими. Добавление в схему свойства или необязательного параметра не должно иметь никакого значения, ведь использующим API приложениям для запуска не нужно обновление.

Другие изменения могут не отражаться в контракте API, например изменения поведения. Эти критические изменения сложнее обнаружить, рассматриваться в этой статье они не будут.

Определение степени критичности изменения в основном зависит от API. API на ранней стадии, стабильность которого не в приоритете, может иметь определение критических изменений, отличное от определения того же понятия у давно существующего API. По ссылке неполный список поддерживаемых в Criteo изменений.

Для написания контрактов API мы используем стандарт спецификации OpenAPI (OAS). Это, безусловно, самый продвинутый и поддерживаемый стандарт описания HTTP API. Возможно, вы слышали о нем под названием Swagger Specification.

Примеры критических изменений

Давайте рассмотрим обновление значения перечисления и посмотрим, как оно выглядит в спецификации OpenAPI. Отправной точкой будет следующее определение параметра запроса animal-type, значения которого — cat, dog или panda:

parameters:   - in: query     name: animal-type     schema:       type: string       enum: [         cat,         dog,         panda       ]

Допустим, API обновлен, а параметр запроса animal-type больше не принимает значение panda. Приложение может ожидать, что это значение по-прежнему допустимо, но API изменился, поэтому panda больше не принимается:

{     "traceId": "56ed4096-f96a-4944-8881-05468efe0ec9",     "type": "validation",     "code": "validation-error",     "instance": "/clinics/1234/pets",     "title": "Unknown enum value",     "detail": "Unexpected enum value: panda" }

Обнаружение изменений, но где?

API Criteo соответствует отраслевому стандарту; он разбит на подсервисы, каждый из которых отвечает за часть API. Шлюз API — как единая точка входа для API — размещается перед этими сервисами. Каждый вызов API сначала достигает шлюза, перенаправляющего вызов в нужный нижележащий сервис.

Благодаря конфигурации маршрутизации из регистра сервисов шлюзу известно, на какой сервис перенаправить вызов.

А если вы хотите больше узнать о том, как развивался дизайн нашего API, прочитайте эту статью.

Регистр сервисов отвечает за построение конфигурации маршрутизации. Каждый внутренний сервис имеет собственную конфигурацию маршрутизации и контракт спецификации OpenAPI. Конфигурация и контракт объединяются и предоставляются регистром. Кажется, это хорошее место для обнаружения критических изменений.

Как?

Конфигурация маршрутизации и спецификация OpenAPI каждой конечной точки хранятся в репозитории git. Это позволяет проверять изменения контракта и легко просматривать историю.

Кроме того, запрос на изменение конфигурации инициирует автоматические проверки, чтобы убедиться в правильности маршрутов и спецификаций OpenAPI. При таком процессе каждое обновление внешнего API версионируется, автоматически валидируется и пересматривается человеком.

Одна из автоматических проверок гарантирует, что критические изменения внесены не были. Проверка сравнивает агрегированную спецификацию OpenAPI в репозитории с рабочей спецификацией. Каждое обнаруженное различие классифицируется. Одни типы классификации рассматриваются как поломка, другие — нет. Если обнаружены различия, и хотя бы одно из них мы считаем критическим, то пул-реквест отклоняется.

Возможность эффективного сравнения спецификаций OpenAPI — ключевой компонент системы, как показана выше, и здесь на помощь приходит компаратор OpenAPI.

Компаратор OpenAPI

Большая часть нашего стека написана на .NET, поэтому мы искали библиотеку C#, способную сравнивать спецификации OpenAPI. Тогда внимание привлек один проект с открытым кодом: openapi-diff, разработанный Microsoft Azure. К сожалению, он не был доступен в виде пакета NuGet. И, что важнее, openapi-diff работает только с OpenAPI 2.0, который в 2017 году заменен OpenAPI 3.0. Мы решили создать внутренний форк проекта и выполнить миграцию, чтобы сравнивать спецификацию Open API версии 3.0.

Теперь, когда миграция завершена, справедливо поделиться инструментом с сообществом: OpenAPI-Comparator, библиотека C#, сравнивающая спецификации OpenAPI версии 3.0. Наша библиотека доступна в виде пакета NuGet. Библиотека может обнаруживать многие виды различий, что полезно при сравнении двух API или двух версий одного API. Для каждого обнаруженного отличия возвращаются дополнительные метаданные:

  • Явное описание изменения.
  • Его расположение в старой и новой спецификации.
  • Ссылка на документацию о нарушенном правиле сравнения.
  • Тип: удаление, обновление или дополнение.
  • Серьезность обнаруженного изменения может быть следующей: Info, Warning или Error.

У компаратора довольно простой API. Код ниже соответствует одному методу, для сравнения в качестве аргументов использующему две спецификации OpenAPI:

IEnumerable<ComparisonMessage> OpenApiComparator.Compare(     string oldOpenApiSpec,      string newOpenApiSpec);

Инструмент также имеет интерфейс командной строки, этот интерфейс доступен как пакет NuGet:

openapi-compare --old path/to/old-spec.json --new path/to/new-spec.json

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

Заключение

Когда клиент начинает использовать API, заключается неявное соглашение: одна и та же версия API не должна обновляться критически. Защита API от критических изменений — это стратегическое вложение, которое не следует недооценивать.

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

Автоматизация обнаружения критических изменений привела к значительному повышению производительности и эффективности. И мы рады возможности помочь большому сообществу разработчиков API, открыв исходный код компаратора OpenAPI.

А полезная теория и ещё больше практики с погружением в среду IT ждут вас на наших курсах:


ссылка на оригинал статьи https://habr.com/ru/articles/717918/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *