Русский
Русский
English
Статистика
Реклама

Documentation

Документирование микросервисов в LeanIX (EAM)

08.07.2020 12:13:32 | Автор: admin


Расскажу о нашем опыте автоматического документирования 150+ микросервисов в системе LeanIX Enterprise Architecture Managment. Многое получилось, как мы и хотели, для чего-то пришлось делать специальные доработки, часть вопросов не смогли решить. Но в любом случае мы получили опыт и готовы им поделиться.


Начну статью с оговорки, что это результат прототипа или исследования. Попытка ответить на вопрос: "Возможно ли использовать системы описания архитектуры предприятия для описания системы построенной на микросервисном подходе?"


Для чего вообще нужно описывать ландшафт предприятия?


Короткий ответ для поддержания процессов управления архитектурой предприятия (Enterprise Architecture Management / EAM).


Более полный ответ уже заключен в самой дисциплине EAM это системная концепция для разработки и развития IT-ландшафта в соответствии с бизнес-возможностями и процессами, а также оргструктурой организации. Бизнес-возможности (business capabilities) в свою очередь являются основой, на которой предприятие строит свои текущие и будущие бизнес-процессы.


EAM включает в себя набор сценариев использования каталога IT-систем, вот основные:



Cценарии выше релевантны не только для архитекторов предприятия (Enterprise Architect), но и для системных архитекторов (System Architect) и архитекторов решений (Solution Architects). Сам по себе каталог IT-систем особенно полезен на этапе интеграции приложений и отслеживания зависимостей. Тем более, что в большинстве организаций такой каталог является "Single Point of Truth".


Актуальность такого каталога необходимо постоянно поддерживать, либо тратя на это много времени сил, либо автоматизируя наполнение.
Эта проблема особенно ощутима, если хотя бы часть ландшафта предприятия построена на микросервисной архитектуре. В этом случае каталог будет содержать уже не 100-500 систем, а 500-1000 (и даже большое) компонентов.



Вот и у нас есть устоявшийся ландшафт на 500+ IT-систем (на диаграмме разбивка на отделы), и уже сейчас поддержка единой базы IT-приложений требует существенных трудозатрат (каталог самих приложений, их связей с бизне- функциями, связи между собой, roadmap каждого приложения и т.п.).


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


Соответственно, возникает вопрос как с этим всем жить?


  • Самое простое решение не документировать в центральном каталоге каждый микросервис. Такой вариант не является совсем уж неверным: сами микросервисы не настолько интересны для бизнес-анализа ландшафта, а группы микросервисов можно объединить в "приложения"/"системы"/"домены" и документировать уже приложения. У этого решения, естественно, есть очень приятный плюс "сокращение трудозатрат" поддержки EAM каталога. Но если каждая система в каталоге будет представлять собой "черный ящик", то теряется прозрачность работы и взаимодействия внутренних компонентов. Также каждая IT-система в рамках своих проектов должна изобретать способ документирования своего каталога микросервисных компонентов, потому что при разработке все равно необходим общей список всех микросервисов приложения.


  • Второе решение автоматизировать документирование микросервисов в каталоге IT-ландшафта. Вот с этим мы и поэкспериментируем.



Текущий ландшафт у нас описан в системе, построенной на платформе Alfabet. Сейчас мы активно анализируем EAM решение от компании LeanIX как потенциального преемника.


LeanIX относительно молодой продукт, поэтому с моей точки зрения, в нем пока мало "унаследовательности", и он достаточно гибок и обладает современными возможностями для интеграции, и что немаловажно, опять же по моему мнению, у него довольно удобный и приятный пользовательский интерфейс.
Даже Gartner в 2019 году назвал LeanIX одним из Visionaries.



Можно долго перечислять причины выбора именно LeanIX (мы действительно проводили RFI/RFP процесс), но не надо забывать что одним из основных инвесторов компании LeanIX является Deutsche Telekom Capital Partners, то есть мы сами заинтересованы в развитии продуктов LeanIX.


Разработчики системы LeanIX EAM изначально заложили в продукт возможность документирования микросервисов. Попытались они это сделать на основе подхода, предложенного проектом Pivio ( http://pivio.io/)


Сам по себе "Pivio-подход" работает следующим образом: рядом с исходным кодом компонента (микросервиса) размещается yaml файл с метаинформацией о компоненте, который
посредством Pivio Client загружается в Pivio Server.



Cервер хранит информацию в ElasticSearch и предоставляет API для ваших инструментов.
Также существует Pivio Webview c очень ограниченными возможностями поиска и визуализации каталога (видимо, это как раз та часть проекта Pivio, которую вы должны были сами расширять для своих потребностей).


Вызов Pivio Client может быть частью процесса сборки или деплоймента компонента.


Естественно, для загрузки документов в Pivio Client они должны быть определенного формата. (см. http://pivio.io/docs/)


Под спойлером пример такого документа:


Скрытый текст
id: next-generation-print-2342-2413-9189-1990name: Next Generation Print Serviceshort_name: NGPStype: serviceowner: Team Goldfingerdescription: Prints all kinds of things. Now with 3D printing support.vcsroot: git://git.vcs.local/UBPcontact: Auric Goldfingerlifecycle: productiontags:- Old- Demolinks:homepage: http://wiki.local/ubpbuildchain: http://ci.local/ubpapi_docs: http://docs.local/ubp-apiservice:provides:- description: REST APIservice_name: uber-bill-print-serviceprotocol: httpsport: 8443transport_protocol: tcppublic_dns:- api.demo-company.com- soap.demo-company.io- description: SOAP API (legacy)service_name: print-serviceprotocol: httpsport: 80transport_protocol: tcpdepends_on:internal:- service_name: print-servicewhy: need to print- service_name: gateway-service- short_name: NGPSport: 8719external:- target: https://api.superdealz.me:443transport_protocol: tcpvia: proxy-servicewhy: Need to sync data with it.- target: mqtt://192.xxx.xxx.xxx:5028transport_protocol: tcpwhy: Get the latest Dealz.

От общей архитектуры Pivio, система LeanIX переиспользовала только PivioClient и формат файла (LeanIX Metadata как раз и есть файл в формате Pivio). В качестве каталога микросервисов и визуализации (поиск, отчеты, диаграммы) используются возможности самого LeanIX EAM.



Практика


Вот эту схему интеграции мы и стали проверять на своем проекте. Проект достаточно крупный: 15+ команд разработки, 150+ микросервисов уже в эксплуатации. Нам повезло, метаинформацию о своих микросервисах мы уже хранили вместе с кодом (у нас multirepo схема git-репозиториев, и в каждом репозитории есть метаинформация о компоненте).


Формат нашей метаинформации (https://github.com/AOEpeople/vistecture) отличается от Pivio, но это все еще yaml файл и преобразовать его "на лету" в pivio формат не составило труда.
Информация об интерфейсах и зависимостях между компонентами у нас также была уже задокументирована в машиночитаемом формате (мы используем её для настройки API Gateway).
Для начала мы решили не копировать всю информацию из swagger в систему EAM (структуру данных, методы и т.п.), это осталось пока за рамками, но будет задачей на будущее.


В планах было все просто: встраиваем в наш CI/CD pipeline дополнительный шаг по загрузке метаинформации в LeanIX (конвертация, вызов Pivio Client, который доступен как в качестве jar файла, так и в виде docker контейнера). Выглядело в планах все отлично: декларативное описание компонента, полная автоматизация обновления информации в EAM.



Документация LeanIX по использованию Pivo Client тут: https://dev.leanix.net/docs/microservices-based-on-yaml-files


Но к середине первого дня работы к нам пришло осознание, что все будет не так просто:


  • Оказалось, что LeanIX поддерживает только часть возможностей Pivio-формата (не все атрибуты).
  • Что еще страшнее, оказалось, что реализация Pivio в LeanIX не поддерживает описание интерфейсов между микросервисами (мы не можем документировать зависимости между компонентами).
  • Естественно, наш способ документирования не включал в себя случай, когда мы выводим сервис из эксплуатации и его надо удалить (нет у нас пока pipeline на удаление сервиса). Да и Pivio Client не умеет удалять описание микросервисов из LeanIX.

Пункт 1. решился дополнительным вызовом REST интерфейса самого LeanIX. (см. https://eu.leanix.net/services/pathfinder/v1/docs/#/)


Пункт 2. решился использованием GraphQL API LeanIX.


  • позволяет создать сущность "Интерфейса" и связать его c провайдером и потребителем.

Скрытый текст

Creating Interface


mutation {   createFactSheet(validateOnly: false,     input: {name: service["name"], type:Interface},     patches: [{op: replace, path:"/description",value: service_url },         {op: replace, path:"/externalId",value:"externalId:service["name"]"}] ) {                 factSheet {                     id                     name                     displayName}        }}

Attach interface to provider


mutation{  upsertRelation(from:      {externalId: {type: externalId, id: service["name"] }},           to: {externalId: {type: externalId, id: service["provider"]}},            type: relInterfaceToProviderApplication) {                relation {                id            }      }}

  • Но graphQL API LeanIX не декларатильвен, значит, надо выяснять разницу между тем что есть в LeanIX и тем, что мы хотим создать/обновить.

Скрытый текст

Searching if Interface/Microservice already exist:


{allFactSheets(     filter: {externalIds: ["externalId/" + externalId]}        ) {        edges {            node {                id                name                }            }      }}

  • Также мы столкнулись с тем, что нельзя привязать интерфейс к микросервису, если сам микросервис еще не документирован, следовательно, это требует последовательного создания документации на провайдера, потребителя и интерфейсов между ними. Решили мы пока эту задачу "топорно": создаем документацию на все компоненты и только потом документируем интерфейсы и зависимости.

Пункт 3. пока решили оставить как ручной шаг.


В итоге получилась такая рабочая схема:


Тут крупнее


После этого можно считать, что процесс автоматизации у нас заработал, a значит, мы можем позволить себе поддерживать документацию о наших микросервисах в системе LeanIX без дополнительных трудозатрат со стороны команд разработки.


Что это нам дало:


  • полнотекстовый поиск по описаниям микросервисов и интерфейсов (в том числе по endpoints name).
  • информацию о версии компонента на продакшене, а также название команды, которая за компонент отвечает сейчас.
  • список потребителей каждого конкретного интерфейса.
  • автоматическая визуализация распределения микросвервисов по их областям (доменам) и командам разработчикам.

Тут крупнее


На схеме уже видно, что баланс разделения ответственности между командами в области домена order куда лучше, чем, например, в presales. В order большая часть работы выполняется всего двумя командами и затраты на коммуникации и интеграции значительно ниже, чем между 4-мя командами в presales.


  • Возможность полуавтоматически визуализировать потоки коммуникации.

    Тут крупнее
    На схеме процесс сбора бизнес метрик, который позволяет оценить прогресс наших бизнес-процессов.


  • Возможность визуализировать зависимости между сервисами.

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



Итоги и открытые вопросы:


  • Вопрос о том, нужно ли вообще документировать микросервисы в общем IT-ландшафте все еще остается открытым, так как пользы от такой детальной документации для главного пользователя EAM (Enterprise Architect / Business Architect) пока немного. Но мы показали, что такая подробная документация нам почти "ничего не стоит".
  • Автоматизация документирования отлично вписывается в pipeline CI/CD
  • Сама система LeanIX гибка и предоставляет широкие возможности для интеграции. Но это и ее минус, так как не все способы одинаково функциональны и требуется разобраться во всех них.
    • Интеграция с Pivio Client декларативная, выглядит как то, что надо, но не поддерживает описание интерфейсов и у нее нет логики по "удалению" документации из LeanIX.
    • В REST API легко делать простые операции, но любой поиск по критериями превращается в "танцы с бубном" на стороне клиента.
    • GraphQL API не всегда логичный (к этому, наверное, можно привыкнуть).
    • Integration API до него пока не добрались, потому что требуется разбираться с проприетарном форматом обмена данными (LDIF)
  • LeanIX молодая система, и в процессе проверки нашего подхода было найдено несколько дефектов. Надо отдать должное команде LeanIX: они исправляли проблемы быстро.
  • Нам имеет смысл пересмотреть какие API мы действительно хотим видеть в общем каталоге. Вероятно, что у нас будет три типа API:
    • internal в рамках подсистемы/домена;
    • system для поддержки процессов через несколько доменов;
    • enterprise уровень для интеграции внешних систем.

Cледующие шаги:


  • Хочется задокументировать swagger описания интерфейсов в той же системе (пока они у нас отдельно все собраны) или хотя бы просто проставить ссылки на наш API Developer Portal / Swagger UI.
  • Вероятно, придется настроить интеграцию через "Integration API", так как по описанию он наиболее полный с точки зрения автоматизации документирования.
  • После демонстрации нашего решения и результата компании LeanIX нам было предложено попробовать новый продукт "LeanIX Cloud Native Suite: Microservices Intelligence", который имеет метамодель более ориентированную на описание микросервисной архитектуры. Кроме вышеописанных интеграционных подходов также обещают прямую интеграцию с kubernets, что позволит снимать часть актуальной информации прямо с боевого окружения. Возможно, это станет темой следующей статьи.

Немного и полезных ссылок на прощание:


Подробнее..

Выбор хорошего инструмента для хранения тест документации и сравнительный анализ 3х выбранных инструментов

30.09.2020 16:04:54 | Автор: admin

Ведение документации для тестирования в Google-доках и Google-таблицах не лучший способ работы с тестовой документацией. Такой подход имеет свои недостатки.
В этой статье я расскажу, как мы перешли от хранения тестовой документации с Google docs к специализированным SaaS-решениям, сделаю сравнение трех разных инструментов (HipTest, Leantesting, Test Management for Jira) и поделюсь результатами такого перехода.




Меня зовут Татьяна и уже 2,5 года я работаю в компании Englishdom на позиции qa engineer. Мы онлайн-школа английского языка, и наш IT-отдел разрабатывает уникальную цифровую платформу учебник для изучения английского, а также несколько приложений для тренировок и домашних заданий. QA-команда тестирует эти продукты и для этого мы ведем документацию.
Использование Google-доков и Google-таблиц имеет свои преимущества:


  • бесплатные ресурсы без ограничений;
  • легкая адаптация так как таблицы простой и понятный инструмент.

Но у такого подхода есть и свои недостатки:


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

Когда я пришла на работу в проект Englishdom, в качестве тестовой документации мы как раз использовали чек-листы в Google-таблицах и в Confluence. Из-за недостатков, описанных выше, одной из главных задач для улучшения процессов был переход с чек-листов на тест-кейсы. А для этого требовался хороший инструмент для их хранения и управления.

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


  • избегание переезда или нежелание переноса множества тестов на другой инструмент;
  • дискомфорт при выходе из зоны комфорта и получении непривычного нового опыта;
  • отсутствие необходимого бюджета, т.к. почти все Test Case Management Tools платные;
  • выбор self-hosted, а не saas-cloud решений для Test Case Management System, что также является платным, и может быть проблемой ввиду отсутствия или ограниченности бюджета;
  • имеются сложности договориться с менеджментом о необходимости или стоимости для такого инструмента.


В нашем случае первоначально стояла задача: найти бесплатный Test Case Management Tool на минимальное количество пользователей, так как на проекте было всего несколько тестировщиков и большое количество юзеров для нас не имело значения, также количество тестовых проверок на тот момент было не слишком большое. Ввиду этого не было необходимости в платном и супер-крутом инструменте.


HipTest


Дальше настало время экспериментов. Первый инструмент, который мы решили попробовать это HipTest https://hiptest.net/ Представлю краткий его обзор:


Преимущества:


  • наличие централизованного хранилища результатов тестов от запуска к запуску в наглядном представлении;
  • возможность просмотра шагов теста, при этом если изначально выбрать хороший стиль написания сценариев, то каждый участник проекта/команды без проблем разберется в сути теста.

Недостатки:


  • создание и редактирование сценариев и action words (при создании новых шагов-действий можно квалифицировать их как шаг, ожидаемый результат или многоразовое действие, это называется action words в HipTest) возможно только в HipTest, а редактор там специфичный. Чтобы понять, нужно попробовать и сравнить с блокнотом или, скажем, с google docs/sheets;
  • массовый быстрый рефакторинг сценариев не получится так же, как это легко можно делать в текстовых редакторах;
  • необходимо быть аккуратным с переименованием (случайным или нет) action words, т.к. в случае, если сценарий уже автоматизирован, то переименование только в HipTest приводит к упавшему тесту, потому что в части реализации наш action word остался с прежним именем;
  • нет возможности прикреплять скриншот к step, а только ко всему тест-кейсу.


Пример тестового сценария в hiptest

Изначально интерфейс этого инструмента мне показался очень простым и удобным, я вдохновилась преимуществами и мы начали переезд на этот инструмент. Возникли некоторые проблемы с экспортом чек-листов с google таблиц и confluence и пришлось вручную переписывать их в HipTest. Дальше при презентации команде было принято общее решение все-таки отказаться от этого тула в виду одной и самой большой причины все-таки сильно неудобно, что в скриншот можно крепить только один ко всему тесту, а не к каждому шагу. В итоге HipTest в работе мы так и не использовали.

P.S. В моем рассказе HipTest представлен в том виде, который был на момент нашего использования. На данный момент HipTest объединен с Cucumber под одним брендом, запустив CucumberStudio и новый улучшенный веб-сайт Cucumber.io. Однако теперь инструмент платный.


LEANTESTING


Итак, поиски инструмента продолжились. Следующим был вариант https://leantesting.com/ (по сути это бесплатный аналог Test Rail, однако есть возможность приобрести расширенные возможности за дополнительную плату. Сейчас мы рассмотрим особенности бесплатной версии.




Пример тестового сценария в LeanTesting

Преимущества:


  • неограниченное количество пользователей;
  • неограниченное количество проектов;
  • неограниченное количество тестов и тест сайклов;
  • удобные отчеты;
  • в новом обновлении Lean Testing может запускать автоматизированные тесты с Selenium.

Недостатки:


  • интеграция с другими вебхуками (например, Slack, GitGub, BitBucket ) платная;
  • настройка пользовательских статусов и типов ошибок также платная;
  • нет интеграции с какими-либо системами баг-трекеров (в нашем случае Jira);
  • скриншот можно прикрепить только к тест-кейсу в целом, но не к шагам;
  • нет возможности импортировать тест-кейсы из других Test Case Management Tools или Excel.

Изначально приняв решение о переходе на этот инструмент, мы видели одно большое преимущество более удобный пользовательский интерфейс, чем в HipTest, но спустя год активного использования все-таки решили уйти от Lean Testing. Главной причиной для нас на тот момент стало отсутствие интеграции с Jira (на проекте мы активно ее используем для ведения всех задач и, конечно же, было бы удобно хранить все в одном месте) и возможность прикреплять скриншот только ко всему тест-кейсу, а не к каждому шагу. Также на тот момент в бесплатной версии было ограничено количество создаваемых кейсов.

То есть изначально при выборе инструмента, мы не задумывались о таких вещах как интеграция с Jira, но впоследствии пришли к выводу, что это было бы очень удобно и полезно для тестирования и разработки. Мы не думали про то, что проект будет так стремительно расти, а с ним и количество наших тестов. Изначально мы просто хотели перенести документацию только для части функционала, а остальную оставить в Confluence. Но со временем, пощупав удобство пользования тест-кейсами в специальной системе их хранения, мы решили переносить туда и другие тесты.


Test Management for Jira (TM4J)


Спустя какое-то время поиска выбор пал на Test Management (https://www.adaptavist.com/doco/display/KT/Test+Management+for+Jira+Server) встраиваемый в Jira инструмент, простыми словами плагин.

Преимущества:


  • красивые и понятные отчеты в виде диаграмм (но довольно простенькие);
  • добавление и удаление статусов к тест-кейсам, тест прогонам и результатам;
  • возможность проставлять лейблы, компоненты, приоритеты в каждом кейсе;
  • возможность добавлять скрины в каждый шаг тест-кейса (!);
  • связь с Jira.

Недостатки:


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


Для нас главным и приоритетным преимуществом выбора инструмента стала все-таки связь с Jira. Это значит, что во время прохождения тест-сайкла на регрессии перед релизом вы заводите баг и прикрепляете прямо к тест-кейсу, указываете на каком шаге фейлится тест, разработчик заходит сразу в тест-кейс и видит нужную информацию это же круто, экономия времени). Еще вариант использования: продакт-менеджер создает задачу, qa прикрепляет тест-кейсы к задаче, разработчик сразу видит тест кейс и шаги к нему, которые ему необходимо пройти перед передачей функционала на тестирование. И несмотря на то, что плагин платный, мы поняли, что эти преимущества очень важны для нас и помогут улучшить процессы в тестировании.



Визуализация тест сайклов



Визуализация создания тест-кейса (скрин1)



Визуализация создания тест-кейса (скрин2)


Сравнительный анализ трех инструментов приведен в таблице:





Итоги


Методом проб и ошибок мы сменили инструмент, выбрав тот, который оказался самым удобным для нашего проекта, изменили подход к ведению тестовой документации, ее хранению и управлению, забыв про чек-листы в Google-таблицах и полностью перейдя на тест-кейсы в специальной системе Test Management. За все время использования еще ни разу не пожалели о выборе. Ведение тестовой документации прямо в Jira оказалось неимоверно удобным. Такой подход планируем использовать и в будущем.


Совет для тех, кто еще не решился уходите из Google-доков и переходите на специальные инструменты для тестовой документации. Какой решать вам, предложений по инструментам действительно много, но точно найдется вариант под ваш проект и ваши цели. Я лишь поделилась историей опыта нашего qa-отдела. Могу сказать, что это сэкономило нам немало времени. Пара примеров: актуализация, формирование тест-сайкла и распределение ответственных qa раньше занимало приблизительно час, сейчас 40 мин. Также создание бага раньше занимало до 15 мин, сейчас около 5 мин времени. Итого, экономия времени составила до 30%.

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

Подробнее..

Что было раньше код или документация? OpenApi (OAS 3.0) и проблемы кодогенерации на Java

12.11.2020 14:14:33 | Автор: admin

Задача интеграции сервисов и различных систем является чуть ли не одной из основных проблем современного IT. На сегодняшний день самым популярным архитектурным стилем для проектирования распределенных систем является REST. Но, как известно, единого стандарта для RESTfulсервисов нет, а у кажущейся простоты и свободы есть обратная сторона медали. Не менее важной является задача интеграции систем разными командами или даже компаниями, с которой приходит вопрос об актуальности документации на протяжении жизни всего проекта, и удобного способа передачи потребителю.

Эту проблему отчасти удалось решить при помощи спецификации OpenAPI(OAS3.0)[1], но все равно часто встает вопрос о правильном применении и подводных камнях кодогенерации, например на языке Java. И можно ли полностью предоставить аналитикам написание функциональных требований, документации и моделей в ymlформе для OpenAPI, а разработчикам предоставить возможность только написание бизнес-логики?

Что было раньше: код или документация?

Я уже около десяти лет занимаюсь разработкой на Java,и почти в каждом проекте так или иначе приходилось сталкиваться с необходимостью поделиться разработанным сервисом с другими людьми. Иногда достаточно просто составить понятное описание APIсуществующего сервиса, но в серьезной enterprise-разработке такое описание часто создается еще на этапе аналитики в виде полноценного документа и является основой для грядущей работы.

В некоторых случаях такие документы составляются на этапе проектирования архитектуры в обычном текстовом формате, а потом передаются разработчику для реализации. Однако, для разработки REST-APIтакой подход не очень удобен и усложняет жизнь как программистам, которые должны еще правильно понять написанное, так и командам, которые будут с получившимся продуктом интегрироваться.К тому же документы могут интерпретироваться людьми по-разному, что обязательно приведет к необходимости дополнительных обсуждений, согласований и переделок, что в конечном счете срывает сроки и добавляет дефекты в продукт. Хотя, метод не очень удобен, иногда он до сих пор применяется при проектировании проектов без OpenAPI(например файловая интеграция, интеграция через БД, интеграция через очереди и общую шину).

Бывают подходы, когда требования создаются программистами уже в процессе работы, тогда финальная документация формируется на основе реализованного кода и передается потребителям сервиса. Часто это оправдано при быстрой реализации гипотез, единоличной разработке или очень сжатых cроках, например, при создании стартапов или при участиив хакатонах. В этом случае удобно генерировать документацию на основе написанного кода и предоставлять потребителю вместе с сервисом.

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

В случае крупных и серьезных проектов, ручное документирование приводит к ряду больших проблем. В SOAPсервисах потребители, получая ссылку на WSDL-документ, генерируют на своей стороне модель данных и клиентский код. В отличие от SOAPпри интеграции OAS3.0 или OpenAPISpecificationявляется не просто спецификацией, а целой экосистемой инструментов для создания RESTсервисов, и она позволяет решить как задачу генерации документации по существующему коду, так и обратную - генерацию кода по документации. Нопрежде чем ответить на вечный вопрос, что первично, нужно определиться с целями и потребностями проекта.

Генерация документации по коду

Первым рассмотрим подход с автодокументируемым кодом[2,3]. Простота здесь заключается в том, что при использовании SpringMVCот разработчиков требуется всего лишь подключить пару библиотек, и на выходе уже получается вполне сносная документация с возможностью интерактивного взаимодействия с API.

Зависимости:

Spoiler

Maven

<dependency>   <groupId>org.springdoc</groupId>   <artifactId>springdoc-openapi-ui</artifactId>   <version>1.4.8</version></dependency>
<dependency>   <groupId>org.springdoc</groupId>   <artifactId>springdoc-openapi-webflux-ui</artifactId>   <version>1.4.8</version></dependency>

Gradle

compile group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.4.8'
compile group: 'org.springdoc', name: 'springdoc-openapi-webflux-ui', version: '1.4.8'

Результат доступен на: http://localhost:8080/swagger-ui.html

Сгенерированная документация по ссылке: http://localhost:8080/v3/api-docs

Плюсы подхода:

  • Возможность быстро сгенерировать документацию по существующему коду

  • Простота интеграции

  • Актуальная онлайн документация

  • Встроенная возможность интерактивного взаимодействия

Минусы подхода:

  • Документация написанная для разработчиков, содержит немного бизнес информации

  • При требовании подробного описания моделей и API возникает необходимость внедрять в код аннотации.

  • Для любых изменений требуется участие разработчика и правки кода

  • Требует от разработчика полного понимания архитектуры приложения или дополнительного документа с ее описанием

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

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

Генерация кода по документации

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

Плюсы подхода

  • Ведение документации становится доступно не только разработчикам, но и техническим и системным аналитикам

  • Есть возможность разделить код и документацию

  • Можно объединить описание моделей, API и функциональных/бизнес требований

  • Любые изменения, инициированные бизнесом, сразу же применяются к модели и контроллерам

  • В случае критического несоответствия сервиса документации, сервис не соберется уже на этапе компиляции и потребует привести интерфейсы в соответствие с реализацией

  • Документацию в yaml формате легко предоставить потребителям сервиса при помощи сторонних библиотек, например redoc[4]

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

  • На основе этой документации генерировать у себя тестовые сервисы для интеграционных и функциональных тестов

Минусы подхода

  • Более актуально для крупных и долгоживущих проектов (от одного года разработки)

  • Требует знания yaml формата для описания моделей

  • Требует навыки работы с markdown для описания функциональных требований

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

Подводные камни и опыт реализации:

Задача по применению второго подхода впервые появилась, когда потребовалось предоставить потребителям актуальную веб-версию документации с подробным описанием функциональных требований и бизнес-кейсов. Написание такой документации и ее актуализацию предстояло вести техническим аналитикам без возможности напрямую редактировать код. И еще одним важным требованием было красивое визуальное представление документации. Далее опишу базовый набор конфигураций для достижения этой цели и возможные подводные камни и проблемы[2,3]

Первым делом добавляем зависимость на mavenплагин

Spoiler
<dependency>   <groupId>io.swagger.codegen.v3</groupId>   <artifactId>swagger-codegen-maven-plugin</artifactId>   <version>3.0.21</version></dependency>
   <artifactId>springdoc-openapi-webflux-ui</artifactId>
   <version>1.4.8</version>

И конфигурируем генератор кода

Spoiler
<plugin>   <groupId>io.swagger.codegen.v3</groupId>   <artifactId>swagger-codegen-maven-plugin</artifactId>   <version>3.0.21</version>   <executions>       <execution>           <id>1</id>           <goals>               <goal>generate</goal>           </goals>           <configuration>               <groupId>com.habr</groupId>               <artifactId>oas3</artifactId>               <inputSpec>${project.basedir}/src/main/resources/habr-1.yaml</inputSpec>               <output>${project.build.directory}/generated-sources/</output>               <language>spring</language>               <configOptions>                   <sourceFolder>src/gen/java/main</sourceFolder>                   <library>spring-mvc</library>                   <interfaceOnly>true</interfaceOnly>                   <useBeanValidation>true</useBeanValidation>                   <dateLibrary>java8</dateLibrary>                   <java8>true</java8>                   <apiTests>false</apiTests>                   <modelTests>false</modelTests>               </configOptions>               <modelPackage>com.habr.oas3.model</modelPackage>               <apiPackage>com.habr.oas3.controller</apiPackage>           </configuration>       </execution>       <execution>...</execution>     ...   </executions>

В случае наличия в проекте нескольких файлов документации следует указывать их в разных executionблоках, однако, каждый запуск перетирает результаты предыдущего запуска (либо игнорирует при включении определенного флага). При наличии нескольких yamlфайлов рекомендуется избегать коллизий в моделях и интерфейсах чтобы запуски не перетирали уже сгенерированные модели.

InputSpecсодержит путь к документации, а modelPackageи apiPackageпакеты для сгенерированных моделей. Также можно генерировать моковые реализации интерфейсов для тестов (при генерации некоторый контроллер, что отвечает типичным ответом).

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

Общая структура yaml документации:

  1. openApi - Содержит версию

  2. info - метаданные для api

  3. servers - информация о серверах c api

  4. tags - дополнительные метаданные, в этом блоке нужно писать текст ФТ и регламента взаимодействия

  5. paths - описание endpoints и интерфейсов контроллеров

  6. components - описание модели данных

  7. security - схема безопасности

Исходный код на github и пример документации можно посмотреть здесь

Визуализация и предоставление потребителю: swagger-ui vs redoc

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

Swagger-ui

Удобная реализация с возможностью интерактивного взаимодействия. Идет из коробки в проекте swagger.io[5]. Можно подключить как библиотеку вместе с сервисом или развернуть статикой отдельно.

Пример визуализации документации тестового сервиса:

Redoc

Он позволяет отобразить и кастомизировать документацию альтернативным способом. Более удобная и красивая структура документации[4].

Пример визуализации документации тестового сервиса:

Хотя, redocреализован на react, его также можно использовать и как VueJSкомпонент:

Spoiler
<template>    <div v-if="hasYmlContent">        <RedocStandalone :spec='ymlObject' :options='ropt' />    </div></template><style...><script>    import AuthService from '../services/auth.service';    import DocumentationService from '../services/documentation.service'    import {RedocStandalone} from 'redoc'    import {API_URL} from "../services/auth-header";    import YAML from "yamljs"    import Jquery from "jquery"    export default {        name: 'documentation',        components: {'RedocStandalone': RedocStandalone},        props: ['yml'],        data: function() {            return {                ymlContent: false,                ropt:{...},            }        },        created() {...},        computed: {...}    };</script>

Выводы

Проведение аналитики и проектирование системы до начала этапа разработки помогает лучше понять задачи и избежать многих ошибок при реализации. Проект OAS3.0 показал себя очень удобным для описания документации и поставки ее потребителям сервиса.

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

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

Источники

  1. https://swagger.io/specification/

  2. https://www.baeldung.com/spring-rest-openapi-documentation

  3. https://github.com/springdoc/springdoc-openapi

  4. https://redocly.github.io/redoc/

  5. https://swagger.io/tools/swagger-ui/

Подробнее..

Документируй это

08.05.2021 12:05:15 | Автор: admin

Всем привет! В данной статье хотел бы рассмотреть инструменты документирования в принципиально разных подходах в разработке REST API, а именно для CodeFirst - инструменты SpringRestDocs (а также его надстройку SpringAutoRestDocs) и для ApiFirst - инструменты экосистемы Swagger(Open-Api).

Дисклеймер: В подробности холивара на тему что же лучше CodeFirst или ApiFirst я вдаваться не будут, а постараюсь продемонстрировать возможную практику документации в обоих вариантах.

CodeFirst плюс SpringAutoRestDocs

Как уже описывали в статье про SpringRestDocs это инструмент достаточно широкого использования, позволяющий генерировать различную документацию (аскедок, хтмл и т.д.) на основе тестов. Пожалуй один из немногих недостатков этого инструмента, является его многословность в тестах, а именно - необходимо описывать каждый параметр, каждое поле и т.д. В свою очередь тесы в SpringAutoRestDocs, используя JSR и Spring аннотации, а также Javadoc, становятся более коротким и немногословными.

Чуть более подробно про SpringAutoRestDocs

SpringAutoRestDocs это надстройка над SpringRestDocs, которая ставит своей целью уменьшение написания кода и документации. Основное преимущество этого иструмента - является меньшее количество написанной документации и большая связаность с рабочим кодом.

Некоторые из фичей инструмента:

  • Автоматическое документирования полей запроса и ответа, хедеров и параметров запроса с использованием Jackson, а также описательной части на основе Javadocs

  • Автоматическое документирование опциональности и ограничения полей по спецификации JSR-303

  • Возможность кастомизации итоговых снипеттов

Подробнее можно почитать в официальной документации.

Для демонстрации возьмем классический Swagger PetStore (с небольшой модернизацией, подробно можно посмотреть спеку в репозитории) и имплементируем несколько методов контроллера (addPet, deletePet, getPetById). В статье будет приведен пример на основе одного метода getPetById

Контроллер:

@RestController@RequiredArgsConstructorpublic class PetController implements PetApi {    private final PetRepository petRepository;        @Override    public ResponseEntity<Pet> getPetById(Long petId) {        return new ResponseEntity<>(petRepository.getPetById(petId), HttpStatus.OK);    }  //и другие имплементированные методы}

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

Базовые настройки для тестовой автодокументации:

Для начала нам необходимо определить базовый класс для всех тестов, который опишет основные правила нашей автоматической документации. Основное что нам понадобится, это сконфигурированный MockMvc (более подробно можно посмотреть в репозитории):

@Beforevoid setUp() throws Exception {  this.mockMvc = MockMvcBuilders    .webAppContextSetup(context)    .alwaysDo(prepareJackson(objectMapper, new TypeMapping()))    .alwaysDo(commonDocumentation())    .apply(documentationConfiguration(restDocumentation)           .uris().withScheme("http").withHost("localhost").withPort(8080)           .and()           .snippets().withTemplateFormat(TemplateFormats.asciidoctor())           .withDefaults(curlRequest(), httpRequest(), httpResponse(),                         requestFields(), responseFields(), pathParameters(),                         requestParameters(), description(), methodAndPath(),                         section(), links(), embedded(), authorization(DEFAULT_AUTHORIZATION),                         modelAttribute(requestMappingHandlerAdapter.getArgumentResolvers())))    .build()  }protected RestDocumentationResultHandler commonDocumentation(Snippet... snippets) {  return document("rest-auto-documentation/{class-name}/{method-name}", commonResponsePreprocessor(), snippets)  }protected OperationResponsePreprocessor commonResponsePreprocessor() {  return preprocessResponse(replaceBinaryContent(), limitJsonArrayLength(objectMapper), prettyPrint())  }
Чуть более подробно про настройки MockMVC

WebApplicationContext получаем от @SpringBootTest

prepareJackson(objectMapper, new TypeMapping()) позволяет настроить ResultHandler, который подготовит наши pojo для библиотеки документирования

withDefaults(curlRequest(), httpRequest(), и т.д.) набор сниппетов, которые будут сгенерированы

commonDocumentation() описывает директорию, куда в build папке разместятся сгенерированные сниппеты, а также препроцессинг ответа контроллера.

Непосредственно сам тест:

Пример теста более подробно можно посмотреть в репозитории.

@Testvoid getPetTest() {//givendef petId = 1L//whendef resultActions = mockMvc.perform(RestDocumentationRequestBuilders.get("/pet/{petId}", petId).header("Accept", "application/json"))//thenresultActions.andExpect(status().isOk()).andExpect(content().string(objectMapper.writeValueAsString(buildReturnPet())))}

Здесь приведен стандартный MockMvc тест, с ожидаемым статусом и ожидаемым телом ответа.

Итого на выходе:

Набор снипеттов с "главным" сниппетом под названием auto-section.adoc (который содержит информацию из всех остальных, указанных в настройках MockMVC) из которых позже можно собрать общий index.adoc для всех методов API. Готовая структура сниппетов:

Готовые сниппеты документы можно посмотреть в репозитории: сниппеты, html сгенеренный на основе сниппетов.

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

Чуть подробнее про кастомизацию сниппетов и ограничений

Функционал кастомизации в SpringAutoRestDocs базируется на таковом же в SpringRestDocs.

К примеру русификация шапок сниппетов и описание ограничений:

ApiFirst плюс Swagger

Как уже описывалось во множестве статей (пример1, пример2) swagger - это open-source проект, включающий OpenApi Specification и широкий набор инструментов для описания, визуализации и документирования REST api.

Чуть более подробно про Swagger

Swagger состоит из двух основных частей - это OpenApi Specification и Swagger Tools.

  • OpenApi Specification - это спецификация описывающая процесс создания REST контракта для более простого процесса разработки и внедрения API. Спецификация может быть описана в формате YAML и JSON. Описание базового синтаксиса, а также более подробную информацию можно изучить по ссылке.

  • Swagger Tools - это инструменты визуализации, документации и генерации клиентно-серверной части REST api. Состоят из трех основных блоков: Swagger Editor(браузерный эдитор, для более удобного написания контракта с поддержкой валидации ситаксиса), Swagger UI(рендер спецификации в качестве интерактивной документации API), Swagger Codegen(генератор серверно-клиентной части, а также некоторых типов документаций)

Ниже мы рассмотрим мульти-модульный проект со следущей структурой: библиотека со свагер генератором (swagger-library), стартер с swagger-ui(swagger-webjar-ui-starter), приложение которое имплементирует классы библиотеки(spring-auto-rest-docs).

Для демонстрации возможностей Swagger возьмем классический Swagger PetStore из примера SpringAutoRestDocs выше.

Настройки build.gradle для модуля библиотеки:

Для реализации генерации server stub и документации на основе Swagger контракта используем OpenApi Generator.

Чуть более подробно про OpenApi Generator

В модуле используется gradle плюс gradle plugin OpenApi Generator.

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

Основная таска для генерации библиотеки и ее настройки:

openApiGenerate {    generatorName = 'spring'    inputSpec = specFile    outputDir = "${project.projectDir}/"    id = "${artifactId}"    groupId = projectPackage    ignoreFileOverride = ignoreFile    apiPackage = "${projectPackage}.rest.api"    invokerPackage = "${projectPackage}.rest.invoker"    modelPackage = "${projectPackage}.rest.model"    configOptions = [            dateLibrary            : 'java8',            hideGenerationTimestamp: 'true',            interfaceOnly          : 'true',            delegatePattern        : 'false',            configPackage          : "${projectPackage}.configuration"    ]}
Чуть более подробно про настройки таски openApiGenerate

Незабываем выполнять генерацию кода до компиляции проекта:

task codegen(dependsOn: ['openApiGenerate', 'copySpecs'])compileJava.dependsOn(codegen)compileJava.mustRunAfter(codegen)

Копируем спеки в ресурсы, чтобы была позже возможность отобразить UI прямо из спек:

task copySpecs(type: Copy) {    from("${project.projectDir}/specs")    into("${project.projectDir}/src/main/resources/META-INF/specs")}

При необходимости также можно сгенерить Asciidoc или Html2.

Swagger-ui стартер:

Стартер добавляет в регистр ресурсов спеки с определенными в дефолтными настройками и webjar swagger-ui с измененным путем до дефолтного контракта.

Rest-docs API:

В самом приложении достаточно имплементировать сгенерированный интерфейс и переопределить настройки UI стартера:

@RestController@RestController@RequiredArgsConstructorpublic class PetController implements PetApi {    private final PetRepository petRepository;        @Override    public ResponseEntity<Pet> getPetById(Long petId) {        return new ResponseEntity<>(petRepository.getPetById(petId), HttpStatus.OK);    }  //и другие имплементированные методы}
swagger:  ui:    indexHandler:      enabled: true      resourceHandler: "/api/**"    apis:      - url: http://localhost:8080/specs/some_swagger.yaml        name: My api

Итого на выходе:

Server stub - готовая библиотека с сущностями и интерфейсом для реализации серверной части API.

Swagger UI - с помощью которого мы получаем наглядную визуализацию API и возможность направлять запросы прямо из UI:

Также примеры Asciidoc или Html2 из самого swagger контракта:

Заключение:

Что дает SpringAutoRestDocs:

  • Возможность хранить документацию как в проекте (к примеру в форме собранного index.html из множества сниппетов), так и в любом другом удобном месте.

  • Документация и модель данных всегда синхронизирована с кодом, так как документация генерируется на основе "зеленых" тестов контроллера.

  • Возможность кастомизации сниппетов и ограничений.

Что дает Swagger:

  • Единый артефакт на всех этапах разработки.

  • Документация и модель данных всегда синхронизирована с кодом, так как код генерируется на основе контракта.

  • Возможность использовать UI, в котором будет вся та же информация, что в контракте с возьможностью направлять запросы.

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

Подробнее..
Категории: Java , Api , Spring , Documentation , Swagger , Spring auto rest docs

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru