Переход к микросервисной архитектуре требует пересмотра подхода к разработке, тестированию, сопровождению, проектированию – иными словами, ко всем аспектам жизненного цикла программных компонентов. В этом посте мы расскажем о практиках, к которым пришла команда архитекторов 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 с опечаткой: compatibility. Эта опечатка встречается и в коде, и в комментариях, и в одном 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.

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

Комментарии (35)


  1. epishman
    10.01.2020 12:36
    +3

    Как хорошо, что в монолитах все перечисленные проблемы решают за меня в автоматическом режиме компилятор и статический анализатор (если компилятор слаб).


    1. AnnaTref Автор
      10.01.2020 15:00

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


      1. epishman
        10.01.2020 16:45

        Ну, последние тенденции все ж радуют — асинхронные интерфейсы между компонентами на основе корутин/асинков, обмен сообщениями вместо вызовов — это снижает зацепленность, а строгая типизация объектов-сообщений по прежнему обеспечивает консистентность интерфейсов в компайлтайме. Хотя согласен, спор религиозный.


        1. atomic1989
          12.01.2020 18:43

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


      1. ApeCoder
        10.01.2020 18:14
        +1

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


        1. Starche
          10.01.2020 20:47

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


          1. snikulov
            10.01.2020 22:49

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


          1. ApeCoder
            11.01.2020 21:39

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


        1. snikulov
          10.01.2020 22:46

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


        1. EvgeniiR
          12.01.2020 09:33

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

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

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

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


          1. ApeCoder
            12.01.2020 19:20

            и следить за границами

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


            Код ревью.

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


      1. apapacy
        10.01.2020 19:18

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


    1. SirEdvin
      12.01.2020 13:36

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


      1. AnnaTref Автор
        12.01.2020 18:54

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


  1. EvgeniiR
    10.01.2020 12:50

    Микросервисы – это «кирпичики», из которых разработчики создают современные приложения.

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

    А то вкупе с многочисленными упоминаниями «общения микросервисов», причём по http, возникает мысль что речь идёт про распределённый монолит взаимодействующий по сети, а не независимые микросервисы.


    1. AnnaTref Автор
      10.01.2020 14:43

      7 бед — один кубернет. И с ним уже 8 бед.
      Но обычно история про deploy отделена от истории про API.


      1. EvgeniiR
        10.01.2020 16:44

        7 бед — один кубернет. И с ним уже 8 бед.

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

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

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

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

        Показались сомнительными, и как мне показалось, говорят о зависимых друг от друга сервисов(это норма, вопрос лишь в количестве зависимостей).


        1. AnnaTref Автор
          12.01.2020 19:02

          >>7 бед — один кубернет. И с ним уже 8 бед.
          Намекаете на то что мысль выше — верна? Ок, спасибо.

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

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

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


          1. EvgeniiR
            12.01.2020 19:27

            Вы имеете в виду сильную связность сервисов?

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

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

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

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


            1. tendium
              13.01.2020 00:34

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


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

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


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


      1. apapacy
        10.01.2020 19:22

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


        1. AnnaTref Автор
          12.01.2020 19:07

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


  1. apapacy
    10.01.2020 13:05

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


    1. AnnaTref Автор
      10.01.2020 14:51

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

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


      1. apapacy
        10.01.2020 15:06

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


    1. AnnaTref Автор
      10.01.2020 14:54

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

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


      1. apapacy
        10.01.2020 15:12

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


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


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


  1. GraiT
    10.01.2020 14:55
    +1

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


  1. PaulIsh
    11.01.2020 05:55
    +1

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


    1. VolCh
      13.01.2020 00:07

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


  1. estet
    11.01.2020 14:46

    Тестирование аннотации против имплементации. Для этого мы генерируем из аннотации (RAML/swagger) клиента, который бомбит сервис запросами. Если ответы будут соответствовать аннотации, а сам сервис не будет падать, значит все хорошо.


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

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


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


    1. Stranger6667
      12.01.2020 14:48

      проверяет и валидные и невалидные данные

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

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

      Тем не менее генерация невалидных данных у нас в плане на ближайшие пару месяцев


  1. ansobolev1989
    12.01.2020 18:39
    -1

    Не рассматривали PACT как альтернативу для тестирования АПИ контрактов?


    1. AnnaTref Автор
      12.01.2020 18:41

      Rust — это хорошая история, но, кажется, тогда всю серверную разработку прийдется переводить с Go на Rust, а это достаточно трудоемко. Вы используете Rust у себя? Можете поделиться опытом?


      1. ansobolev1989
        12.01.2020 21:13

        Прошу прощения — я имел в ввиду docs.pact.io — consumer driven contract testing.