Меня зовут Игорь Савинов, я работаю системным аналитиком в Альфа-Банке более 5 лет. Последние несколько лет занимаюсь новым интернет-банком для юридических лиц в части внешнеэкономической деятельности, а до этого развивал внутренние сервисы. Сначала немного упомяну о Docs as Code и миддловой документации, чтобы при сравнении были хорошо видны проблемы фронтовой документации (и про решение тоже расскажу).
Кратко о документации и Docs as Code
Docs as Code — это подход к разработке документации с использованием тех же инструментов и процессов, что и для написания кода. Например, мы используем одни и те же инструменты с разработчиками: Git, IDE, CI/CD и другие различные аббревиатуры. С Docs as Code мы можем автоматизировать сборку документации в различных форматах и её публикацию, автоматизировать как часть документации, так и всю, а ещё снижается процент расхождения документации и кода.
Но с другой стороны:
Нужно изучить один или несколько языков разметки, инструменты разработчиков, освоить системы контроля версий. Порог вхождения для специалистов повышается.
Там, где у нас есть автоматизация, необходим процесс настройки и поддержки всего процесса.
Документация в Альфа-Банке делится по слоям: фронт, миддл и бэкенд.
Фронт — слой микросервисов UI-приложения. Здесь мы ведём документацию в Confluence. Также можем использовать различные плагины, например, PlantUML.
Бэкенд — это у нас ABS банка. По ней долгое время документация велась в Word и Excel, но, к счастью, мигрировала в Confluence.
Миддл — это слой микросервисов. Здесь мы применяем Docs as Code, в качестве языка разметки используем AsciiDoc, для генерации диаграмм PlantUML, а для отслеживания изменений и ревью — Bitbucket.
Документация на миддл-слой ведётся так:
На каждый сервис есть свой git-репозиторий.
В каждом репозитории есть отдельная папка для ведения документации и любой из членов команды разработки может внести свои изменения.
После того, как изменения успешно попадают в ветку master, запускается пайплайн. В качестве системы CI/CD у нас собственная платформа на базе Jenkins.
Далее собирается билд, а итоговый артефакт в формате HTML публикуем в своем хранилище JFrog Artifactory.
Немного о формате и структуре.
index.adoc. В корне папки docs/asciidoc есть файл index.adoc, в котором перечисляются все методы API с кратким пояснением, и ссылкой на более подробное описание.
db.adoc. Отдельный файл для описания структур БД, где также могут описываться, например, kafka топики.
config.adoc. Файл для описания конфигов: ссылка на сервис конфигов, или текстовое описание, которое в дальнейшем может использоваться для описания метода сервиса.
_external. В этой папке находится документация на внешний сервис — примеры и вызовы внешних сервисов. Внешний сервис — это любой сервис, по отношению к нашему текущему, который мы описываем.
currencyPayments — каталог, который есть у каждого метода сервиса. В таком каталоге у нас есть 4 файла.
№1. Одноименный файл с каталогом с расширением .adoc. В нем описана вся логика, бизнес-описание, схема, пошаговый алгоритм, маппинги обработки кодов ошибок.
№2. Файл diagram.puml. В нём может быть диаграмма активностей или последовательности.
№3. request.adoc — пример запроса метода сервиса.
№4. response.adoc – примеры ответа метода сервиса.
Последние два файла включаются внутрь основного файла с использованием специальной команды include
.
Итоговый билд в формате .html.
Проблемы и решения фронтовой документации
Единственным отличием и проблемой документации фронт слоя от миддл стало наличие изображений экранных форм.
При сохранении изображений и их изменений в Git они сохраняются в истории коммитов, увеличивая размер нашего репозитория.
Например, пусть одно изображение весит 300 КБ, а в проекте их может быть также 300, то это уже будет 90 МБ репозитория. Предположим, что мы будем апдейтить 30% документации один раз в месяц — через месяц репозиторий будет весить 117 МБ, а через год практически 1,5 ГБ. При этом стандартный фронтовый репозиторий весит 6 МБ (не учитывая всякие зависимости).
Чтобы избежать данной проблемы, решили использовать Git LFS. Это расширение для Git, которое заменяет большие файлы на текстовые указатели, а само содержимое файлов сохраняет в удалённом хранилище.
Например, при добавлении файла в репозитории, Git LFS заменит его на текстовый указатель, а сам файл сохранит в локальном хранилище Git LFS.
Когда мы захотим отправить новый коммит, где есть указатели Git LFS, которые ссылаются на эти коммиты, мы перенесем их файлы из локального хранилища в удалённое, которое будет привязано и настроено к нашему репозиторию.
При переключении на какие-то коммиты, которые содержат указатели Git LFS, мы уже заменим наши текстовые указатели из локального хранилища или из удаленного.
Стоит отметить, что Git LFS работает незаметно для пользователя — не надо специально выполнять эти самые команды, всё происходит фоном при выполнении стандартных команд. Например, при команде git pull
, когда мы хотим получить изменения к себе в рабочую копию, Git LFS автоматически подтянет только те файлы, на которые он ссылается, а не все существующие версии.
Первоначально мы хотели хранить сами файлы также в JFrog Artifactory, но от этого варианта отказались, потому что Bitbucket ничего не знает про Artifactory. Когда мы просматривали файлы с изображениями в Bitbucket, файл не отображался — была ошибка с указанием на то, что файл хранится в каком-то удалённом хранилище LFS.
Ну раз Bitbucket ничего не знает про Artifactory, то сам про себя-то он что-то знает? И решили использовать стандартное хранилище на Bitbucket сервере для хранения файлов в Git LFS. Поэтому к уже знакомой схеме по миддл-документации добавляется Git LFS.
Структура документации на фронт практически такая же, как и на миддл.
Также есть файл index.adoc, где есть краткое описание спецификации.
Есть папка _еxternal, где у нас находятся запросы внешних сервисов.
Каждая спецификация также располагается в отдельном каталоге.
В каждом таком каталоге появляется папка images, в которой мы сохраняем непосредственно наши изображения.
Есть небольшие отличия в том, что у нас в каждом каталоге нет примеров запросов и ответов, потому что для фронтового вызова это будет какой-то внешний сервис и он будет описан в папке _еxternal.
Также нет каких-то файлов типа db.adoc, потому что мы взаимодействуем с ними через миддл-слой.
Вот как это выглядит в коде:
Есть описание сценария.
Внутри сценария указываем якорь ссылки на макеты.
Под каждым пунктом есть макеты, их скрываем в html элемент
<details>
с помощью команды[%collapsible]
, в этом блоке описываем уже непосредственно ссылку на изображение.Дополнительно для каждого изображения можно указать атрибуты, например, ширина и признак открытия изображения в новом окне.
Как выглядит результат
Итак:
В начале блок с общей информацией, в котором располагаются ссылки на архитектурную документацию, макеты, задачи, другие связанные документы.
Далее блок с описанием бизнес-процесса.
Описание самой фичи, где по действиям расписаны шаги пользователя с примерами запросов и ответов сервисов.
Также под каждым действием есть макеты.
В конце идет описание экранных форм. Здесь описываются общие элементы со страницы, например, фильтры или календарь.
В итоге получается, что документацию по миддл слою мы ведём где-то с 2017 года. По фронтовой документации прошли пилот, теперь можем успешно её автоматически собирать, тестировать и измерять метрики работы аналитика.
Примечание про пилот.
Вообще, на первом этапе мы решили вести документацию для фронта в отдельном репозитории — почти рядом с кодом.
В Альфа-Банке уже имелся настроенный asciidoctor gradle plugin, который мы использовали для сборки документации на Java-сервисах. Чтобы не тащить gradle в проекты с фронтом, мы решили доработать фронтовый пайплайн и использовать специальный плагин asciidoctor.js. И пока у нас дорабатывался пайплайн, решили не терять время и переносить документацию с Confluence в Git с использованием разметки asciidoc.
В дальнейшем можно будет из этого репозитория перенести документацию просто копипастом в текущий репозиторий с кодом или использовать специальные команды Git для миграции.
Сейчас мы в активной части пилота, где документация располагается рядом с кодом.
Для сборщика у нас используется asciidoctor.js.
Изображение мы храним в Git LFS.
Язык разметки также asciidoc, как и для миддл слоя.
Система контроля версий Bitbucket.
Для написания документации в качестве IDE преимущественно используем IDEA, но ограничений нет.
Проблема с фронтом также касалась и бэкенд слоя — здесь тоже есть изображения, которые необходимо описывать в документации. Нам остается только адаптировать форматы и можно будет приступать к пилоту по бэкенд слою.
Используете ли вы подход Docs as Code? Как ведет в этом случае документацию? Ведет ли документацию рядом с кодом? Как решаете проблему с изображениями?
Полезные ссылки:
Как Git LFS влияет на опыт ведения документации рядом с кодом
Инструменты подхода Docs-as-code
Как мы ведём требования к ПО: формализация
Курс на Stepik. Рекомендуем, если вы ещё не знакомы с ведением документации рядом с кодом, но хотели бы познакомиться с данным подходом.
Также подписывайтесь на Телеграм-канал Alfa Digital — там мы постим новости, опросы, видео с митапов, краткие выжимки из статей, иногда шутим.