Как создать версию / пометить тестовую рамку с помощью тестов API REST для нескольких микросервисов? - PullRequest
1 голос
/ 30 марта 2019

У нас много разных микросервисов, и мы тестируем, среди прочего, REST API этих разных микросервисов.Эти автоматизированные тесты API REST не включены в проекты / репозитории Microservice.Вместо этого у нас есть проект testautomation, содержащий все различные тесты, такие как API-тесты и тесты end2end, потому что мы хотим тестировать все как черный ящик.

Теперь проблема в том, что возможны бесконечные комбинации разных версий Microservice.выполнить тестирование в тестовой среде (пример: выполнение тестов сегодня для Microservice A с версией 1.0 и Microservice B с версией 2.0 отличается тем, что завтра те же тесты выполняются для Microservice A с версией 1.1 и Microservice B с версией 2.1).Таким образом, нам потребуется какое-то управление версиями или тегами нашего проекта Testautomation или выполненных тестов, чтобы мы могли определить, какие комбинации разных версий Microservice являются допустимыми, а какие - недействительными / работающими, потому что, например, некоторые тесты не пройдут.

Существуют ли какие-либо рекомендации или опыт для реализации и интеграции такого механизма управления версиями / тегов?

1 Ответ

1 голос
/ 30 марта 2019

Для меня актуальная проблема уже основана на вашем реальном дизайне. Вы заявляете, что поддерживаете некоторые микросервисы, основанные на архитектуре REST, хотя в такой среде для начала не требуется версия конечной точки как таковой. Сам Филдинг ответил, как версионировать API в среде REST, просто ответив: Не .

Но почему это? Одним из немногих ограничений REST является HATEOAS (или Hate-Us, как я его называю), который обозначает Hypertext-As-Engine-Of-Application-State. Этот аббревиатура в основном описывает модель взаимодействия, используемую в Интернете, которая не будет иметь никаких предварительных предположений относительно содержимого, которое будет получено, и будет отображать пользователю только то, что оно получило, включая любые URI, возвращаемые сервером. Браузер вызовет изменение состояния при вызове конечной точки, на которую нацелен URI, вызванный пользователем. Это может быть ссылка, изображение или кнопка формы (или что нет). Основная идея здесь заключается в том, что клиент будет обслуживаться API или сервером со всей информацией, необходимой ему для выполнения дальнейших действий и просто представления результатов пользователю.

Просматривая веб-страницу вашего предпочтительного производителя или поставщика, вы можете заметить, что вы, скорее всего, получите HTML-страницу, содержащую изображения, ссылки и другое содержимое. Сам браузер не знает о продукте, предлагаемом на этом сайте, хотя он все равно способен отображать результат пользователю, поскольку он знает, как отображать HTML. Если вы посетите другую страницу, ваш браузер все равно сможет отображать HTML независимо от содержимого, которое предлагает эта страница. Тем не менее, если одна из этих страниц каким-либо образом изменится, ваш браузер все равно сможет отобразить результат для вас, если только сервер не ответит с типом носителя, о котором ваш браузер еще не знает, что, однако, очень маловероятно в Интернете .

Однако большинство самозваных API-интерфейсов «REST» возвращают произвольный контент, специфичный для определенного API, хотя большинство из них используют application/json в качестве формата представления. Специализированный клиент, обладающий некоторыми знаниями о встроенном API, обычно взаимодействует с таким API, который, однако, вряд ли сможет взаимодействовать с любым другим API. Если что-то на уровне API изменится, то вероятность поломки этого клиента без каких-либо дополнительных обновлений будет высокой. Это очень часто встречается в RPC-подобных системах, таких как SOAP, RMI и CORBA.

Такие клиенты часто предполагают, что определенные конечные точки, такие как /api/users/12345, возвращают данные о конкретном пользователе в наиболее вероятном представлении JSON. Позднее полезная нагрузка распределяется по объекту базового языка программирования, возможно, игнорируя любые неизвестные поля и обнуляя указанные поля, которые недоступны в ответе. Хотя основная проблема здесь заключается в том, что клиенты предполагают, что определенные конечные точки имеют определенные типы . «Умные» разработчики теперь будут вводить управление версиями в конечных точках, так что вышеупомянутый URI изменится на /api/v1/users/12345 для представления JSON, содержащего старые поля, в то время как /api/v2/users/12345 вернет новые поля. Обе версии, однако, все еще описывают одного и того же пользователя. Наличие двух разных URI для одного и того же пользователя само по себе является плохим дизайном, хотя обычно управление версиями конечной точки не само по себе. Обычно весь API сам является версионным, поэтому, если вы столкнулись с серьезными изменениями, вы вынуждены ввести совершенно новую версию API, либо скопировав другие немодифицированные ресурсы, либо повторно используя те же самые модели для внутреннего использования, просто снова выставляя их под несколькими URI.

Вместо того, чтобы предполагать, что конечные точки возвращают определенный тип с предопределенным форматом представления, клиенты и сервер должны договариваться о контенте.HTTP здесь, в частности, поддерживает согласование типа контента , когда клиент сообщает серверу о своих возможностях, и сервер должен отвечать в формате представления, понятном клиенту.Это может быть что-то вроде application/vnd.acmee-users+json или application/vcard+xml или тому подобное.Клиент понимает application/vnd.acmee-users.v2+json, т. Е. Может обслуживаться сервером в новом представлении, в то время как более старые клиенты все же сообщают серверу, что они понимают только application/vnd.acmee-users+json, и обслуживаются таким представлением.То, как сервер обрабатывает изменения внутри, не представляет интереса для клиента.Он просто интересуется форматом представления, который он может обрабатывать.

Хотя версионирование медиа-типов также не является предпочтительным способом версионирования изменений некоторыми архитекторами, поскольку вы по-прежнему в основном описываете одно и то же, просто немного по-другомусинтаксис или немного другая семантика.HTML, т.е. все еще поставляется с application/html (редко с text/html), но не с application/html_5 или подобным.Он разработан явно таким образом, чтобы оставаться обратно совместимым.Сервер, генерирующий вывод HTML 5, будет по-прежнему отображаться в браузере, который поддерживает только HTML 4.01 или 2. Возможно, не все элементы будут отображаться так же, как в браузере, совместимом с HTML 5, но клиент не перестанет работать неожиданно.

Марк Ноттингем, который является сопредседателем рабочей группы IETF HTTP, заявил, что основной принцип управления версиями заключается в том, чтобы не ломать существующих клиентов.Поэтому, по его словам,

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

Ноттингем даже заявляет, что product-token , используемый в User-Agent или Server заголовках, следует отдавать предпочтению любому URIили версионирование типа носителя для получения ответов, специфичных для определенных версий программного обеспечения.Однако, учитывая огромное количество клиентского программного обеспечения, я не самый большой поклонник этого подхода, поскольку для этого потребуется, чтобы сервер имел определенные знания о возможностях HTTP-клиентов и их используемых версиях.Однако для API, которые имеют только ограниченное количество клиентов, вероятно, большинство из них также находятся под тем же контролем, что и API / сервер, это может быть жизнеспособным подходом.

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

Как упоминал Фил Стерджон в одном изего сообщений в блоге

Если люди собираются разрабатывать свои API-интерфейсы как RPC с RESTish-фасадом, им следует просто взять на себя обязательство быть RPC-API и создать конечную точку для конкретных клиентов, как онибуквально уже делаем.

Просто будьте честны с этим.Скрыть ложное намерение, RPC партия, документ как таковой, и, возможно, просто использовать gRPC.

...