OpenAPI Diff
Сравнение OpenAPI сопоставляет две версии спецификации API — старый контракт и новый — и сообщает, что на самом деле изменилось: удалённые конечные точки, параметры, ставшие обязательными, поля, у которых изменился тип, исчезнувшие значения перечислений. Загрузите или вставьте обе спецификации ниже, и эта страница классифицирует каждое изменение как ломающее или не ломающее, чтобы вы могли оценить обновление поставщика или собственный релиз до того, как оно достигнет продакшена. Оба файла разбираются на этой странице, на вашем устройстве — ничего не загружается на сервер, и это важно, потому что спецификации описывают внутренние конечные точки, которые вы, возможно, не хотите видеть на чужом сервере. Впервые встречаете эту лексику? Сопутствующая статья ломающие изменения API с объяснениями определяет каждый используемый здесь термин.
Последнее обновление:
Старая спецификация (контракт, который клиенты используют сегодня)
Перетащите файл в любое место этой панели, выберите файл или вставьте текст. Разбор происходит локально; ничего не покидает это устройство.
Новая спецификация (контракт-кандидат)
Перетащите файл в любое место этой панели, выберите файл или вставьте текст. Разбор происходит локально; ничего не покидает это устройство.
Результат сравнения
Сводка скопирована в буфер обмена.
Что проверяет этот инструмент — и что «ломающее» означает на самом деле
Изменение является ломающим, когда клиент, корректно написанный против старой спецификации, может отказать против новой, не изменив ни строки собственного кода. Это определение определяет каждый вердикт на этой странице. Удаление пути или операции ломает, потому что существующим вызовам некуда идти. Удаление статуса ответа — прежде всего 2xx — ломает, потому что обработка ошибок клиента была написана вокруг старого набора. Добавление обязательного параметра или обязательного свойства запроса ломает, потому что вчерашний допустимый запрос внезапно отклоняется. Изменение типа или формата поля ломает, потому что парсеры, валидаторы и сгенерированные SDK строятся на объявленном типе. Удаление значения перечисления ломает, потому что клиент может по-прежнему отправлять его или хранить данные, которые больше не может интерпретировать. Всё остальное — новая конечная точка, необязательный параметр, новое поле ответа, новое значение перечисления, новый код статуса — сообщается как не ломающее: старые клиенты продолжают работать, даже если пока не могут использовать новую возможность.
Сравнение структурное, а не текстовое. Оба документа нормализуются в одну модель до всякого сравнения: каждый путь и операция, их параметры, индексированные по имени и расположению, тело запроса и каждый ответ, сведённые к сигнатуре схемы — детерминированной сводке типов, форматов, имён свойств, списков обязательных полей и значений перечислений, построенной рекурсивно и с разрешёнными локальными ссылками $ref. Поэтому перестановка ключей, переформатирование пробелов или переписывание каждого описания даёт пустой diff: ничто из этого не меняет контракт. И поэтому изменение, погребённое на три уровня вглубь ссылаемой схемы, тоже находится — сигнатура разворачивает ссылку, а не сравнивает её имя.
Принимаются две формы ввода, потому что экосистема публикует обе: сначала пробуется JSON, а когда это не удаётся, текст разбирается как YAML — формат, который использует большинство рукописных документов OpenAPI. Документы Swagger 2.0 тоже работают, включая их параметры in: body и схемы на каждый ответ. Намеренно нет ни живой загрузки, ни отправки на сервер: вставьте документы или перетащите файлы, точно как вы сделали бы это с захватом HAR, и сравнение выполняется при нажатии кнопки — а не при каждом нажатии клавиши —, поэтому две большие вставленные спецификации остаются отзывчивыми.
Используйте результат как ворота релиза, а не как украшение. На ревью список ломающих изменений — это повестка: каждая запись нуждается либо в исправлении, либо в повышении версии, либо в окне устаревания, либо в письменном решении, что разрыв намерен и объявлен. Список не ломающих изменений — это черновик журнала изменений. Экспорт diff в JSON позволяет архивировать это решение рядом с релизом, а копируемую сводку можно сразу вставить в запрос на слияние — та же дисциплина, что вы применили бы к изменению контракта вебхука, где молча изменённая полезная нагрузка ломает каждого подписчика разом.
Честные ограничения, сказанные прямо. Этот инструмент сравнивает объявленный контракт: он не может видеть поведение, которое спецификация не объявляет, — например поле, которое сохраняет тип, но меняет смысл, новое бизнес-правило, более строгие лимиты или сообщение об ошибке, которое клиенты (неразумно) разбирали. Он следует локальным ссылкам и сравнивает схемы до ограниченной глубины, поэтому патологически глубоко вложенные или взаимно рекурсивные схемы суммируются, а не разворачиваются бесконечно. И diff с нулём ломающих изменений — не обещание, что обновление безопасно: это свидетельство того, что задокументированный контракт выдержан, а именно такое свидетельство и стоит иметь перед развёртыванием.
Таблица классификации, по которой оценивает эта страница
| Удалён путь или операция | Ломающее. Вызовы к конечной точке, которой больше нет, отказывают сразу; нет совместимого способа заставить старого клиента продолжать работать против неё. |
| Удалён статус ответа | Ломающее. Логика повторов, обработки ошибок и мониторинга клиента пишется против объявленного набора статусов; потеря 2xx — самая тяжёлая форма. |
| Параметр стал обязательным / добавлено обязательное поле | Ломающее. Запросы, допустимые по старой спецификации, отклоняются новой, поэтому каждый существующий клиент должен измениться, прежде чем сможет вызывать конечную точку. |
| Изменён тип или формат | Ломающее. Парсеры, валидаторы и сгенерированные SDK строятся из объявленного типа; переход от integer к string (или от int32 к int64) ломает строгих клиентов, даже когда значения на проводе выглядят похоже. |
| Удалено свойство (запроса или ответа) | Ломающее. Свойство запроса, которое клиенты отправляют, игнорируется или отклоняется; свойство ответа, которое клиенты читают, становится null или отсутствует в их коде. |
| Удалено значение перечисления | Ломающее. Клиенты могут по-прежнему отправлять удалённое значение или хранить данные, его использующие. Добавленные значения перечислений не ломают и сообщаются отдельно. |
| Дополнения | Не ломающее. Новые пути, операции, необязательные параметры, необязательные свойства запроса, свойства ответа, статусы ответа и значения перечислений никогда не делают ранее допустимое взаимодействие недопустимым. |
Часто задаваемые вопросы
Загружаются ли мои файлы спецификаций куда-нибудь?
Нет. Оба документа разбираются и сравниваются на этой странице, на вашем устройстве; сравнение не делает сетевых запросов и ничего не сохраняется. Это намеренное правило: спецификация — это карта вашего API, включая внутренние и недокументированные конечные точки, и инструмент, который просил бы загрузить её для сравнения, собирал бы именно ту карту, которую следует держать в тайне.
Какие форматы принимаются?
OpenAPI 3.x и Swagger 2.0, в JSON или YAML. Текст сначала пробуется как JSON и разбирается как YAML, когда это не удаётся. Документ должен нести объект paths, чтобы быть распознанным как спецификация; всё остальное сообщается как «не спецификация», а не молча даёт пустой diff.
Что здесь считается ломающим изменением?
Всё, что может заставить корректно написанного старого клиента отказать: удалённые пути, операции или статусы ответа; параметры или свойства запроса, ставшие обязательными; изменения типа или формата; удалённые свойства запроса или ответа; и удалённые значения перечислений. Добавление чего-либо необязательного не ломает. Изменения описания, заголовка и форматирования полностью игнорируются — это не изменения контракта.
Как обрабатываются ссылаемые схемы?
Локальные ссылки, такие как #/components/schemas/Pet (или #/definitions/Pet в Swagger 2.0), разрешаются при построении сигнатур, поэтому изменение внутри общей схемы сообщается по каждой операции, которая её использует. Разрешение ограничено по глубине и безопасно при циклах, поэтому рекурсивные схемы не могут повесить сравнение.
Можно ли архивировать или поделиться результатом?
Да. Кнопка скачивания экспортирует полный diff в JSON — счётчики сводки плюс каждое изменение с его серьёзностью, видом, путём, методом и структурированной детализацией, — а кнопка копирования создаёт текстовую сводку для запроса на слияние или примечания к релизу. Обе генерируются локально из сравнения, которое вы только что выполнили.