Микросервисы: как соблюсти контракт

    Переход к микросервисной архитектуре требует пересмотра подхода к разработке, тестированию, сопровождению, проектированию – иными словами, ко всем аспектам жизненного цикла программных компонентов. В этом посте мы расскажем о практиках, к которым пришла команда архитекторов Acronis на пути к лучшим API компонентов. Рассказ будет включать как постановку задачи, так и анализ ее решений. Возможно, кому-то этот пост покажется “капитанским”, кому-то будет неясно почему упустили супер-решение Х, но надеемся, что вам он будет интересен и полезен. Строителей микросервисов приглашаем под кат – почитать и оставить свои комментарии.

    image

    Если вы подписаны на наш блог, то уже читали про контракты микросервисов. О них мы говорили в постах, посвященных выбору Swagger или RAML, а также статическим проверкам, которые можно проводить на базе созданных ранее аннотаций. Поводом для сегодняшнего поста стал доклад на конференции HighLoad. Нам нужно было в целом рассказать о том пути, который мы прошли для формализации взаимоотношений между микросервисами. И сегодня хочется поделиться с Хабром нашими выводами, а также проверить, согласны ли с нами другие архитекторы.

    Микросервисы – это «кирпичики», из которых разработчики создают современные приложения. Каждый такой сервис взаимодействует с внешним миром через API. Обычно микросервисы разрабатываются отдельными командами, иногда разнесенными географически, так что для эффективной работы необходимо поддерживать консистентность и целостность их публичных интерфейсов. В больших компаниях с сотнями сервисов необходимо иметь аннотацию каждого компонента: формализовать входные данные и подробно описать результаты его работы. Если вы работаете c HTTP REST, то для этого существует два распространенных формата аннотаций: RAML и Open API Specification (aka Swagger). Но вопросы, на которых мы останавливаемся сегодня, не привязаны ни к какому конкретному протоколу. Поэтому сказанное ниже будет актуально даже для gRPC.

    Предыстория


    Компания Acronis существует уже более 15 лет. За это время продукты и кодовая база значительно эволюционировали. От сложного desktop-приложения мы пришли к enterprise модели с централизованными консолями управления, разграничениями прав и аудит-логами. Следующим шагом стало преобразование enterprise-приложения в открытую платформу, где накопившийся опыт применялся для интеграции с внешними сервисами.

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

    Основные проблемы


    Проблемы вокруг построения API знакомы, кажется, всем. Опишем их в гипертрофированном виде: как боли, которые мучают гипотетического программиста Васю и его не менее гипотетического менеджера Колю. Все имена вымышлены, а любые совпадения не случайны :)

    1. Описание устарело

    Пусть программист Вася разрабатывает компонент А, который использует API компонента Б. У последнего есть аннотация, но она невалидна. Васе приходится лезть в чужой код, искать людей, задавать вопросы. Сроки съезжают, а его менеджер Коля должен разбираться с переносами дедлайнов.

    2. API неконсистентен

    Программист Вася закончил задачу и переключился на следующую, связанную с работой компонента B. Но и у разработчиков Б, и у разработчиков В разное чувство прекрасного, так что одни и те же вещи в API сделаны по-разному. Вася опять ушел разбираться с кодом, а Коля опять страдает от срыва сроков.

    3. API не документирован

    Менеджер Коля решает опубликовать API компонента А, чтобы интеграторы могли делать чудесные интеграции. Интеграторы сталкиваются с проблемами, служба поддержки перегружена, у менеджера Коли все горит, а Вася чувствует, что скоро настанет его черед.

    4. API несовместима со старой версией

    Интеграции внедрены, все пожары потушены. Но Вася вдруг решает, что API его компонента далек от совершенства и погружается в доработку. Разумеется, при этом нарушается обратная совместимость и все интеграции разваливаются. Эта ситуация приводит к тратам со стороны интеграторов и потере денег компанией-разработчиком.

    Методы лечения


    Все эти проблемы возникают, когда у программистов нет представления о хорошем REST API или это представление фрагментировано. В реальности далеко не все разработчики имеют опыт работы с REST. И потому основные методы “лечения” направлены на просвещение. Когда в голове каждого разработчика начинает брезжить видение правильного API, скоординированного с видением других разработчиков, архитекторов и документаторов, API становится идеальным. Процесс формирования этого видения требует усилий и специализированных средств, про которые мы как раз сейчас будем рассказывать.

    Боль 1. Аннотация не соответствует имплементации


    Аннотация может отличаться от актуального состояния сервиса не только потому, что это API “темного прошлого”, до которого никак не дойдут руки. Это может быть также API светлого будущего, которое пока так и не наступило.

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

    Вылечить эту боль можно, проводя:

    • Архитектурное ревью. Очень полезная штука для компаний любых масштабов, в которых есть хотя бы один программист, который “знает, как правильно”. При изменении сервиса архитектор или ответственное лицо должны отслеживать состояние аннотаций и напоминать программистам, что нужно обновлять не только сервис, но и его описание. Побочные эффекты – узкое место в лице архитектора
    • Генерацию кода из аннотаций. Это так называемый подход API-first. Он подразумевает, что вы изначально делаете аннотацию, потом генерируете первичный код (инструментов для этого хватает, например [go-swagger] (https://github.com/go-swagger/go-swagger)), а затем заполняете сервис бизнес-логикой. Такая схема позволяет избежать несоответствий. Она хорошо работает, когда область решаемых сервисом задач четко очерчена.
    • Тестирование аннотации против имплементации. Для этого мы генерируем из аннотации (RAML/swagger) клиента, который бомбит сервис запросами. Если ответы будут соответствовать аннотации, а сам сервис не будет падать, значит все хорошо.

    Тестирование аннотация vs имплементация
    Остановимся подробнее на тестировании. Подобная полностью автоматическая генерация запросов – сложная задача. Имея данные из аннотаций API, можно создавать отдельные запросы. Однако любой API подразумевает зависимости, например, перед вызовом GET /clients/{cliend_id} нужно этот объект сначала создать, а затем получить его id. Иногда зависимости бывают менее явными – создание объекта Х требует передать идентификатор связанного объекта Y, и это не sub-collection. Ни RAML, ни Swagger не позволяют описывать такие зависимости в явном виде. Поэтому тут возможны несколько подходов:

    1. Ожидать от разработчиков формализованных комментариев в аннотации, указывающих на зависимости.
    2. Запросить описание ожидаемой последовательности у разработчиков (существует довольно много способов описать запросы используя YAML, специализированный DSL или через красивый GUI, как это делал ныне заброшенный apigee.
    3. Взять реальные данные (например, используя OpenResty для логгирования всех запросов и ответов сервера)
    4. Извлечь зависимости из аннотации с помощью (почти что) искусственного интеллекта (например, RESTler)

    В любом случае задача тестирования оказывается весьма трудоемкой.

    image

    Лично мы пришли к тому, чтобы готовить тестовые последовательности вручную. Разработчикам в любом случае нужно писать тесты, так что мы можем предоставить им удобный инструмент, который, возможно, найдет пару дополнительных багов.

    Наша утилита использует для описания последовательностей запросов вот такой yaml:

    image

    В фигурных скобках объявлены переменные, которые подставляются в ходе тестирования. Переменная address передается как CLI параметр, а random генерирует произвольную строчку. Наибольший интерес тут представляет поле response-to-var: оно содержит переменную, в которую будет записан json с ответом сервера. Таким образом, в последней строке можно получить id созданного объекта с помощью task.id.

    Боль 2. API неконсистентен


    Что такое консистентность? Не будем вводить какого-то формального определения, но, упрощая, это внутренняя непротиворечивость. Например, в изначальном проекте Васи нужно было агрегировать данные по докладам на HighLoad, и API предоставляет фильтрацию данных по годам. После того, как проект был почти закончен, к Васе пришел менеджер Коля с просьбой добавить в анализ статистику по докладчикам, причем сделать новый метод “GET speakers” тоже с фильтрацией по годам. В итоге Вася за пару часов дорабатывает код, но в процессе тестирования оказывается, что метод не работает. Причина в том, что в одном случае “год” – это число, в другом – строка. Но это, конечно, не очевидно с первого взгляда и требует постоянной внимательности при работе с API. Конститеность API — это когда такая чрезмерная внимательность не требуется.

    Примеров неконсистентости множество:

    1. использование разных форматов одних и тех же данных. Например, формат времени, тип идентификатора(число или строка UUID),
    2. применение разного синтаксиса фильтрации или паджинации,
    3. разные схемы авторизации на сервисах. Мало того, что различия пудрят мозг программистам, они также отражаются на тестах, которые должны будут поддерживать разные схемы.


    Лечение:

    • Архитектурное ревью. Если есть архитектор-тиран, он (при отсутствии шизофрении) обеспечит консистентность. Побочные эффекты: bus factor и тирания :)
    • Создание API Guideline. Это единый стандарт, который нужно разработать (или взять готовый), но самое главное – внедрить. Для этого требуется и пропаганда, и кнут, и пряник.
    • Внедрение статических проверок на предмет соответствия аннотации API Guideline (об этом читайте здесь).

    image
    Пример — предметы статических проверок

    Каждая компания делает свой выбор, каким Guideline пользоваться. И, наверное, нет универсального подхода, что там должно быть, а чего – нет. Ведь чем больше положений в стандарте, тем строже вы подходите к контролю и тем сильнее ограничиваете свободу творчества. И главное, что мало кто дочитает до конца документ из “всего-то 100 страниц”.

    В нашей компании мы включили в гайдлайн следующие моменты:

    image
    Другие хорошие примеры Guideline-ов можно найти у Microsoft, PayPal, Google.

    Боль 3. API не документирован


    Существование аннотации – необходимое, но не достаточное условие для простоты работы с API. Можно написать аннотацию так, что она не реализует весь свой потенциал. Это случается когда:

    1. не хватает описаний (для параметров, хэдеров, ошибок и т.д.);
    2. не хватает примеров использования, ведь example могут быть использованы не только для улучшения документации (больше контекста для разработчика и возможность прямо с портала интерактивно поиграться с API), но и для тестирования (как отправная точка fuzzing-а));
    3. имеются недокументированные функции.

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

    Лечение:

    • Доступность средств генерации API reference программисту. Если разработчик будет видеть, как выглядит описание его API для коллег и пользователей, он будет стараться сделать аннотацию лучше. Побочные эффекты: конфигурирование этих средств потребует дополнительных рабочих рук.
    • Настройка взаимодействия между всеми причастными: программистами, евангелистами, сотрудниками саппорта. Побочные эффекты: совещания всех со всеми, усложнение процессов.
    • Использование тестов на основе аннотации API. Внедрение описанных выше статических проверок в CI репозиториев с аннотациями.

    В Acronis на базе аннотаций генерируется API reference с SDK client-ами и Try-It секциями. Вместе с сэмплами кода и описаниями use case-ов, они формируют полный спектр необходимых и удобных дополнений для программистов. Посмотреть на наш портал можно на developer.acronis.com

    image

    Надо сказать, что существует целый класс инструментов для генерации API reference. Некоторые компании сами разрабатывают подобный инструментарий под собственные нужды. Другие используют такие достаточно простые и бесплатные инструменты, как Swagger Editor. Мы в Acronis после долгих (действительно долгих) изысканий остановились на Apimatic.io, предпочтя его REST United, Mulesoft AnyPoint и другим.

    Боль 4. Проблемы с обратной совместимостью


    Обратная совместимость может быть нарушена из-за любой мелочи. Например, программист Вася каждый раз пишет слово compatibility с опечаткой: compatability. Эта опечатка встречается и в коде, и в комментариях, и в одном query parameter. Заметив ошибку, Вася делает замену этого слова по всему проекту и не глядя отправляет изменения в продакшн. Разумеется, обратная совместимость будет нарушена и сервис упадет на несколько часов.

    Почему такие события вообще могут происходить? Основная причина заключается в непонимании жизненного цикла API, который может проявляться и в ломающихся интеграциях, и в непредсказуемых политиках EOL(End Of Life), и в непонятных релизах API.

    Лечение:

    • Архитектурное ревью. Как и всегда, твердая рука архитектора способна предотвратить нарушение обратной совместимости. Однако главной его задачей является объяснение стоимости поддержки нескольких версий и поиск вариантов внесения изменения без поломки существующего API.
    • Проверка на обратную совместимость. Если аннотация API содержит актуальное описание, то можно проверять нарушения обратной совместимости на этапе CI;
    • Своевременное обновление документации. API reference и описание API должны обновляться одновременно с изменением кода сервиса. Для этого можно хоть checklist-ы стандартизованные заводить, хоть нотификации на изменения настраивать, хоть тренировать супер-способности по генерации всего из всего… Важно! Отдел документации должен быть в курсе всех планируемых изменений, чтобы у них была возможность запланировать ресурсы на обновление документации и написания upgrade guide-ов. Upgrade guide, протестированный и подтвержденный, — печально значимый атрибут любого переименования, которое вы затеяли в API.

    Change Management


    Правила, описывающие активности, связанные с жизненным циклом API, называются политиками управления изменениями — change management

    image

    Если у вас есть две версии аннотации “текущая” и “новая”, технически проверка на обратную совместимость реализуется просто: распарсив обе аннотации, нужно проверить существование необходимых полей

    image

    Мы написали специальный инструмент, который позволяет сравнить все критичные для обратной совместимости параметры в CI. Например, при изменении тела ответа в запросе GET /healthcheck будет выдано сообщение следующего вида:

    image

    Заключение


    Избавиться от проблем с API мечтает каждый архитектор. Не знать о проблемах API мечтает каждый менеджер. :). Есть много лекарств, но каждое имеет и свою цену и свои побочные эффекты. Мы поделились своими вариантами лечения самых простых детских болезней с API, а дальше встают уже более серьезные проблемы. Выводы из нашей статьи “капитанские”: проблемы API начинаются с головы и обучение людей хорошим практикам есть главный залог успеха. Все остальное лишь дело техники. А с какими проблемами сталкивались вы и какие средства для решения вы избрали в своей организации?

    image
    Лекарства от плохого API.

    Будем рады любым мыслям, оценкам, замечаниям, мнениям и вопросам!
    Acronis
    Компания

    Комментарии 46

    • НЛО прилетело и опубликовало эту надпись здесь
        +1
        В монолитах свои проблемы с API. Текущие абстракции (leaky abstractions). Спинлоки, торчащие из интерфейсов, для производительности. Переменные с разделяемым доступом. Неструктурированные, но такие уютные и привычно-домашние интерфейсы, в которых любой посторонний ногу сломит.
        Я нежно люблю монолиты за их скорость, но программный интерфейс между подсистемами внутри монолита нельзя называть сильной стороной этого паттерна
        • НЛО прилетело и опубликовало эту надпись здесь
            0

            Не думали, что придется делать для третьих лиц апишки)

            +1

            Интересно, не придумал ли кто-то способа энфорсить слабо связанную архитектуру, не заставляя маршалить данные и взаимодействовать по сети?

              0
              Мне кажется, или это называется «подключить библиотеку пакетным менеджером»?
              Понятное дело, что очень ограниченно работает для компонент на разных языках программирования, но там без сериализации данных в любом случае не обойтись.
                0

                Если ты на одном вычислительном узле и сервисы на одном и том же языке, можно и без сериализации.

                  0

                  Я так понимаю, что в микросервисах огранисения типа агрегатов DDD — нельзя например передавать ссылки, на что-то внутренне а только value object. Пакеты это никак не ограничивают.

                  0

                  Придумали. Через ipc.

                    0
                    Интересно, не придумал ли кто-то способа энфорсить слабо связанную архитектуру, не заставляя маршалить данные и взаимодействовать по сети?

                    Бить монолит на модули и следить за границами.

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

                    Код ревью. Микросервисы слабо связанную архитектуру то не обеспечивают. Это просто более явные границы которые люди всё равно нарушают/проводят неправильно. Чем больше мода на них и проще их становится пилить, тем больше людей появляется у которых всё это дело деплоится как единый связанный монолит.
                      0
                      и следить за границами

                      следить за соблюдением каких правил?


                      Код ревью.

                      А что-то автоматическое?

                    0

                    ИМХО проблемы с RESTAPI: его документирования, консистентности и совместимости это другая плоскость и RESTAPI в микросервисы/монолитах имеют одини и теже проблемы.
                    Разве что в микросервисной архитектуре добавляется необзодимость собирать документацию из нескольких проектов которые могут быть разработаны на разных языках программирования.

                    0

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

                      0
                      Думаю, под «нерешаемой» проблемой скалирования/масштабирования вы имели ввиду «ограниченно решаемую»? Ведь наплодить потоков со своими дубликатами данных в рамках одного адресного пространства — дело несложное, но возникает ограничение размерами физической ноды.
                        0
                        -
                      0
                      Микросервисы – это «кирпичики», из которых разработчики создают современные приложения.

                      Как потом деплоится такое приложение?

                      А то вкупе с многочисленными упоминаниями «общения микросервисов», причём по http, возникает мысль что речь идёт про распределённый монолит взаимодействующий по сети, а не независимые микросервисы.
                        +1
                        7 бед — один кубернет. И с ним уже 8 бед.
                        Но обычно история про deploy отделена от истории про API.
                          0
                          7 бед — один кубернет. И с ним уже 8 бед.

                          Намекаете на то что мысль выше — верна? Ок, спасибо.

                          Но обычно история про deploy отделена от истории про API.

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

                          И утверждения, процитированное в предыдущем комментарии, и:
                          Де факто есть два способа взаимодействия микросервисов – HTTP Rest и gRPC от компании Google

                          Показались сомнительными, и как мне показалось, говорят о зависимых друг от друга сервисов(это норма, вопрос лишь в количестве зависимостей).
                            0
                            >>7 бед — один кубернет. И с ним уже 8 бед.
                            Намекаете на то что мысль выше — верна? Ок, спасибо.

                            kubernetes как ответ на вопрос «как потом деплоится такое приложение?». под «распределённый монолит взаимодействующий по сети» Вы имеете в виду сильную связность сервисов?

                            я бы сказал что история про deploy перекликается с историей про обратную совместимость

                            Безусловно, чтобы обновить API нужно раздеплоить новую версию компонента. Но, Евгений, кажется, я не улавливаю Выше мысль. Развернете?
                              0
                              Вы имеете в виду сильную связность сервисов?

                              Да. Интересно было бы узнать, независимый ли у микросервисов цикл релизов друг от друга, и сколько сил/времени занимает координация релизов, она ведь всё-равно нужна иногда.

                              Безусловно, чтобы обновить API нужно раздеплоить новую версию компонента. Но, Евгений, кажется, я не улавливаю Выше мысль. Развернете?

                              Всё так, наверное не очень корректно было спрашивать именно про деплой в первом коммментарии.
                              Если происходит поломка обратной совместимости API сервиса, которое используется другими сервисами, нужно править их, а это коммуникации между командами и ожидание обновления от них(=время, деньги, медленнее деливери).

                              Вы ранее назвали HTTP/gRpc стандартом общения микросервисов, а это значит что общение происходит синхронно(request/response), хотя для поддержания низкой связности всякие event-driven подходы считаются предпочтительнее.
                                0

                                Есть два варианта, как быть с обратной совместимостью апи:


                                1. Поддерживать разные версии АПИ в одном сервисе.
                                2. Поддерживать в продакшне разные версии самих сервисов, а на апи распределять уровнем выше на входе.

                                Второй вариант, ИМХО, проще, но может быть чреват проблемами безопасности из-за необновляемости, либо же нужно будет поддерживания несколько версий сразу.


                                Общение не всегда может быть предпочтимо по событийной модели. В частности, в случае, когда скорость ответа достаточно критична. А иногда и просто логически не имеет смысла. Например, у нас был сервис, который получал какие-то данные из эластика и формировал из них некие структуры в API-ответе, которые надо было потом выдать в конечном итоге на фронтенд. Событийная модель здесь ну прям совсем неуместна.

                                  0
                                  оба варианта, как мне кажется, имеют одинаковую сложность. Но в одном случае сложность имплементируется в коде, а во втором — в deployment схеме. Помните знаменитую картинку про микросверисы: сложность в коде vs сложность в связях?
                                    0

                                    Не понял, а что сложного в deployment во втором варианте?

                                      0
                                      Главным образом, сценарии по апдейту и сценарии нескольких инстансов различных версий работающих с одной базой данных.
                                        0

                                        База данных — это частный случай, я вообще его не рассматривал. У нас большинство сервисов stateless.

                                  0
                                  Интересно было бы узнать, независимый ли у микросервисов цикл релизов друг от друга, и сколько сил/времени занимает координация релизов, она ведь всё-равно нужна иногда.


                                  В Acronis сложная модель deploy-я в том смысле, что кроме облака, которым оперируем мы сами, есть еще on-premise deployment, когда наше облако разворачивают customer-ы для своих личных нужд. Поэтому модель «поправили (микро)сервис, залили в прод» у нас не применима. Мы выпускаем целостные релизы Acronis Cyber Cloud где фиксированы версии каждого сервиса
                                    0
                                    Вы ранее назвали HTTP/gRpc стандартом общения микросервисов, а это значит что общение происходит синхронно(request/response), хотя для поддержания низкой связности всякие event-driven подходы считаются предпочтительнее.


                                    В архитектуре, чисто философски, все компромисс. Иногда ведь и Вы, как архитектор, наверняка отказываетесь от более мощных решений (дающих лучшее масштабирование или производительность) в пользу более понятных решений (дающих более быстрый кодинг, ниже стоимость сопровождения). Cинхронное общение с одной стороны более понятное (простое с точки зрения отладки), с другой стороны более быстрое (все-таки проход через очередь дает много накладных расходов, хотя и добавляет гарантий). Поэтому, как мне кажется, в целом http/gRPC более широко используются чем общение через очереди. Ну и на http можно асинхронное имплементировать (202 и в путь).
                                    Но я согласна с Вами, что event-driven подход имеет свои преимущества
                                      0
                                      Cинхронное общение с одной стороны более понятное (простое с точки зрения отладки), с другой стороны более быстрое (все-таки проход через очередь дает много накладных расходов, хотя и добавляет гарантий). Поэтому, как мне кажется, в целом http/gRPC более широко используются чем общение через очереди. Ну и на http можно асинхронное имплементировать (202 и в путь).

                                      Так суть как раз в том чтобы не рассматривать http vs queue как две разных реализации транспорта, а делать меньше запросов за данными, получая и сохраняя информацию заранее у себя через всякие Event Notification и Event-Carried State Transfer.

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

                                Маркетинговая политика облачных провайдеров, которая сейчас "прикармливает" клиентов и спикеров на использование кубернетиса а посему на использование микросервисов к сожалению оставляет в тени другие заслуживающие внимания решения например j2ee, wamp. Однако стандарты как показывает опыт побеждают в долгосрочной перспективе.

                                  0
                                  J2ee, кажется, ограничено Java-ой? А задачи Wamp-а не соответствуют задачам Kubernetes?
                                  В общем, здесь можно идти в долгий философский диспут. Я далеко не фанат kubernetes, но, как Вы правильно сказали, стандарты побеждают в долгосрочной перспективе. А из нескольких альтернативных стандартов выживает не всегда самый лучший с технической точки зрения.
                              +1

                              Не возникало ли у Вас в процессе мысли о том что проблем было бы меньше если бы использовалось не RESTAPI а более строгая спецификация? А если RESTAPI, то в ее модификации купно с HATEOAS?

                                0
                                А если RESTAPI, то в ее модификации купно с HATEOAS?

                                Те сервисы Акронис, которые используют мультимедиа контент, следуют рекомендациям HATEOAS. Если у Вас есть позитивный опыт применения HATEOAS в других паттернах, буду рада услышать
                                  0

                                  Опыта нет. Я бы вообще не применял RESTAPI если бы мобильные разработчики не были сильно против

                                  0
                                  Не возникало ли у Вас в процессе мысли о том что проблем было бы меньше если бы использовалось не RESTAPI а более строгая спецификация?

                                  Мысли что-то улучшить рождаются постоянно. Ограничивает обычно время, ресурсы и здравый смысл про лучшее враг хорошего. Но давайте обсудим про более строгие спецификации. Вы имеете в виду GraphQL или что-то другое? И какие плюсы Вы сами в них видите?
                                    +1

                                    GraphQL — да получаем документацию тождественную коду по крайней мере по входным и выходным параметрам и гибкость. Отрицательные моменты — обработка ошибок и проблема SELECT N + 1


                                    Старый добрый SOAP — его правильно редко используют так как сложно. Все дело в том что без VisualStudio генерировать сигнатуры сервисов очень сложно — практически невозможно.


                                    Но не только это. Например WAMP-протокол, JSON-RPC, JSON-API и oData (последние два собственно RESTAPI с попыткой внести систематизацию в формирование запросов)

                                  +1
                                  Как решаете проблему с синхронными операциями, если они у вас есть? Или сервисы ведут кросс общение по REST? Спрашиваю, потому что, в нашем случае пришлось уйти на websocket и jsonrpc.
                                    0

                                    Не кажется ли вам, что микросервисы через REST api жестко связаны? Почему не использованы очереди вроде Rabbit?

                                      +2

                                      На rabbit можно получить ту же связанность, только ещё и не очевидную.

                                        0
                                        Есть сценарии, в которых используем очереди. Но это глубоко внутренние сценарии. С моей точки зрения, общение по REST проще в сопровождении и быстрее. Кроме того, простота REST для нас критична как для платформенного решения — представьте семинар по пользованию АПИ, где вы объясняете через POSTMAN collection, и семинар, где вы объясните асинхронную модель и работу с очередями. :) Если что-то для внешних пользователей можно упростить, то это всегда нужно упростить.
                                          0
                                          Общение с внешними пользователями конечно по REST (или другому общепринятому протоколу). Я думал, что REST предлагается и для внутренних взаимодействий сервисов.
                                            0
                                            В целом внутри тоже REST. Ибо внутренние разработчики — они тоже разработчики. HTTP проще отлаживать, проще кодить. Синхронное взаимодействие в целом легче понимать. Но, конечно, есть обстоятельства, когда гарантии доставки (от использования очередей) оказываются более значимыми чем удобство использования.
                                        +1
                                        Тестирование аннотации против имплементации. Для этого мы генерируем из аннотации (RAML/swagger) клиента, который бомбит сервис запросами. Если ответы будут соответствовать аннотации, а сам сервис не будет падать, значит все хорошо.


                                        Зависит от требований в проекте, но обычно тестирования позитивных сценариев недостаточно.

                                        Остановимся подробнее на тестировании. Подобная полностью автоматическая генерация запросов – сложная задача.


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

                                          На данный момент в Schemathesis сгенерированные данные соответствуют схеме (если нет, то стоит завести баг репорт), но возможны ситуации когда приложение может посчитать их невалидными, например из-за дополнительных проверок которые не укладываются в саму схему и реализованы вручную в приложении.

                                          Т.е. то что они расцениваются приложением как невалидные это больше особенность реализации конкретного приложения и его схемы чем намеренное поведение со стороны Schemathesis.

                                          Тем не менее генерация невалидных данных у нас в плане на ближайшие пару месяцев
                                          0
                                          Не рассматривали PACT как альтернативу для тестирования АПИ контрактов?
                                            0
                                            Rust — это хорошая история, но, кажется, тогда всю серверную разработку прийдется переводить с Go на Rust, а это достаточно трудоемко. Вы используете Rust у себя? Можете поделиться опытом?
                                              0
                                              Прошу прощения — я имел в ввиду docs.pact.io — consumer driven contract testing.

                                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                          Самое читаемое