Меня зовут Игорь Савинов, я работаю системным аналитиком в Альфа-Банке более 5 лет. Последние несколько лет занимаюсь новым интернет-банком для юридических лиц в части внешнеэкономической деятельности, а до этого развивал внутренние сервисы. Сначала немного упомяну о Docs as Code и миддловой документации, чтобы при сравнении были хорошо видны проблемы фронтовой документации (и про решение тоже расскажу).
![](https://habrastorage.org/getpro/habr/upload_files/c66/134/878/c66134878dd5d4152b14c9de9d91ff5e.png)
Кратко о документации и Docs as Code
Docs as Code — это подход к разработке документации с использованием тех же инструментов и процессов, что и для написания кода. Например, мы используем одни и те же инструменты с разработчиками: Git, IDE, CI/CD и другие различные аббревиатуры. С Docs as Code мы можем автоматизировать сборку документации в различных форматах и её публикацию, автоматизировать как часть документации, так и всю, а ещё снижается процент расхождения документации и кода.
Но с другой стороны:
Нужно изучить один или несколько языков разметки, инструменты разработчиков, освоить системы контроля версий. Порог вхождения для специалистов повышается.
Там, где у нас есть автоматизация, необходим процесс настройки и поддержки всего процесса.
Документация в Альфа-Банке делится по слоям: фронт, миддл и бэкенд.
![](https://habrastorage.org/getpro/habr/upload_files/150/d96/7a2/150d967a287442d592906b0527f95ce0.png)
Фронт — слой микросервисов UI-приложения. Здесь мы ведём документацию в Confluence. Также можем использовать различные плагины, например, PlantUML.
Бэкенд — это у нас ABS банка. По ней долгое время документация велась в Word и Excel, но, к счастью, мигрировала в Confluence.
Миддл — это слой микросервисов. Здесь мы применяем Docs as Code, в качестве языка разметки используем AsciiDoc, для генерации диаграмм PlantUML, а для отслеживания изменений и ревью — Bitbucket.
Документация на миддл-слой ведётся так:
![](https://habrastorage.org/getpro/habr/upload_files/93c/90a/785/93c90a7854acc27b4a786555f95ce72a.png)
На каждый сервис есть свой git-репозиторий.
В каждом репозитории есть отдельная папка для ведения документации и любой из членов команды разработки может внести свои изменения.
После того, как изменения успешно попадают в ветку master, запускается пайплайн. В качестве системы CI/CD у нас собственная платформа на базе Jenkins.
Далее собирается билд, а итоговый артефакт в формате HTML публикуем в своем хранилище JFrog Artifactory.
Немного о формате и структуре.
![](https://habrastorage.org/getpro/habr/upload_files/692/f62/c1b/692f62c1ba63996812ab3c613691932d.png)
index.adoc. В корне папки docs/asciidoc есть файл index.adoc, в котором перечисляются все методы API с кратким пояснением, и ссылкой на более подробное описание.
![Пример index.html Пример index.html](https://habrastorage.org/getpro/habr/upload_files/56b/04a/831/56b04a831c8eb0d8c016417ea5401051.png)
db.adoc. Отдельный файл для описания структур БД, где также могут описываться, например, kafka топики.
config.adoc. Файл для описания конфигов: ссылка на сервис конфигов, или текстовое описание, которое в дальнейшем может использоваться для описания метода сервиса.
_external. В этой папке находится документация на внешний сервис — примеры и вызовы внешних сервисов. Внешний сервис — это любой сервис, по отношению к нашему текущему, который мы описываем.
currencyPayments — каталог, который есть у каждого метода сервиса. В таком каталоге у нас есть 4 файла.
№1. Одноименный файл с каталогом с расширением .adoc. В нем описана вся логика, бизнес-описание, схема, пошаговый алгоритм, маппинги обработки кодов ошибок.
№2. Файл diagram.puml. В нём может быть диаграмма активностей или последовательности.
№3. request.adoc — пример запроса метода сервиса.
№4. response.adoc – примеры ответа метода сервиса.
Последние два файла включаются внутрь основного файла с использованием специальной команды include
.
Итоговый билд в формате .html.
![currencyPayments.html currencyPayments.html](https://habrastorage.org/getpro/habr/upload_files/fac/a94/213/faca94213c02bb5522ba1e7c306129ec.gif)
Проблемы и решения фронтовой документации
Единственным отличием и проблемой документации фронт слоя от миддл стало наличие изображений экранных форм.
При сохранении изображений и их изменений в Git они сохраняются в истории коммитов, увеличивая размер нашего репозитория.
Например, пусть одно изображение весит 300 КБ, а в проекте их может быть также 300, то это уже будет 90 МБ репозитория. Предположим, что мы будем апдейтить 30% документации один раз в месяц — через месяц репозиторий будет весить 117 МБ, а через год практически 1,5 ГБ. При этом стандартный фронтовый репозиторий весит 6 МБ (не учитывая всякие зависимости).
Чтобы избежать данной проблемы, решили использовать Git LFS. Это расширение для Git, которое заменяет большие файлы на текстовые указатели, а само содержимое файлов сохраняет в удалённом хранилище.
Например, при добавлении файла в репозитории, Git LFS заменит его на текстовый указатель, а сам файл сохранит в локальном хранилище Git LFS.
![Источник: https://www.atlassian.com/git/tutorials/git-lfs Источник: https://www.atlassian.com/git/tutorials/git-lfs](https://habrastorage.org/getpro/habr/upload_files/bba/4dd/020/bba4dd020677a73fc1e84c3aa55198f6.png)
Когда мы захотим отправить новый коммит, где есть указатели Git LFS, которые ссылаются на эти коммиты, мы перенесем их файлы из локального хранилища в удалённое, которое будет привязано и настроено к нашему репозиторию.
![Источник: https://www.atlassian.com/git/tutorials/git-lfs Источник: https://www.atlassian.com/git/tutorials/git-lfs](https://habrastorage.org/getpro/habr/upload_files/5a7/04a/1cf/5a704a1cf64e63abbafc35f602a5759a.png)
При переключении на какие-то коммиты, которые содержат указатели Git LFS, мы уже заменим наши текстовые указатели из локального хранилища или из удаленного.
![Источник: https://www.atlassian.com/git/tutorials/git-lfs Источник: https://www.atlassian.com/git/tutorials/git-lfs](https://habrastorage.org/getpro/habr/upload_files/d67/125/e7c/d67125e7cec72d8179c78b0c94e41380.png)
Стоит отметить, что Git LFS работает незаметно для пользователя — не надо специально выполнять эти самые команды, всё происходит фоном при выполнении стандартных команд. Например, при команде git pull
, когда мы хотим получить изменения к себе в рабочую копию, Git LFS автоматически подтянет только те файлы, на которые он ссылается, а не все существующие версии.
Первоначально мы хотели хранить сами файлы также в JFrog Artifactory, но от этого варианта отказались, потому что Bitbucket ничего не знает про Artifactory. Когда мы просматривали файлы с изображениями в Bitbucket, файл не отображался — была ошибка с указанием на то, что файл хранится в каком-то удалённом хранилище LFS.
![](https://habrastorage.org/getpro/habr/upload_files/0ed/d43/38e/0edd4338ea46949eae8d4afd55a5aece.png)
Ну раз Bitbucket ничего не знает про Artifactory, то сам про себя-то он что-то знает? И решили использовать стандартное хранилище на Bitbucket сервере для хранения файлов в Git LFS. Поэтому к уже знакомой схеме по миддл-документации добавляется Git LFS.
![](https://habrastorage.org/getpro/habr/upload_files/8a9/b2b/c79/8a9b2bc7938d00dc5e75c5625034dbaf.png)
Структура документации на фронт практически такая же, как и на миддл.
![](https://habrastorage.org/getpro/habr/upload_files/ec9/b8a/0df/ec9b8a0df075e3f8f7ea366766bd0934.png)
Также есть файл index.adoc, где есть краткое описание спецификации.
Есть папка _еxternal, где у нас находятся запросы внешних сервисов.
Каждая спецификация также располагается в отдельном каталоге.
В каждом таком каталоге появляется папка images, в которой мы сохраняем непосредственно наши изображения.
Есть небольшие отличия в том, что у нас в каждом каталоге нет примеров запросов и ответов, потому что для фронтового вызова это будет какой-то внешний сервис и он будет описан в папке _еxternal.
Также нет каких-то файлов типа db.adoc, потому что мы взаимодействуем с ними через миддл-слой.
Вот как это выглядит в коде:
Есть описание сценария.
Внутри сценария указываем якорь ссылки на макеты.
Под каждым пунктом есть макеты, их скрываем в html элемент
<details>
с помощью команды[%collapsible]
, в этом блоке описываем уже непосредственно ссылку на изображение.Дополнительно для каждого изображения можно указать атрибуты, например, ширина и признак открытия изображения в новом окне.
![](https://habrastorage.org/getpro/habr/upload_files/9f7/aad/b39/9f7aadb390de448cb2a5b727fe56caea.png)
Как выглядит результат
Итак:
В начале блок с общей информацией, в котором располагаются ссылки на архитектурную документацию, макеты, задачи, другие связанные документы.
Далее блок с описанием бизнес-процесса.
Описание самой фичи, где по действиям расписаны шаги пользователя с примерами запросов и ответов сервисов.
Также под каждым действием есть макеты.
В конце идет описание экранных форм. Здесь описываются общие элементы со страницы, например, фильтры или календарь.
![](https://habrastorage.org/getpro/habr/upload_files/aef/9d6/179/aef9d61794a0dff5472d164063740a65.gif)
В итоге получается, что документацию по миддл слою мы ведём где-то с 2017 года. По фронтовой документации прошли пилот, теперь можем успешно её автоматически собирать, тестировать и измерять метрики работы аналитика.
![](https://habrastorage.org/getpro/habr/upload_files/566/76c/de1/56676cde1c7b1aaa085dcbbafc089f4d.png)
Примечание про пилот.
Вообще, на первом этапе мы решили вести документацию для фронта в отдельном репозитории — почти рядом с кодом.
![](https://habrastorage.org/getpro/habr/upload_files/b26/87b/427/b2687b42761d6d93daa98a35ad8ce9aa.png)
В Альфа-Банке уже имелся настроенный asciidoctor gradle plugin, который мы использовали для сборки документации на Java-сервисах. Чтобы не тащить gradle в проекты с фронтом, мы решили доработать фронтовый пайплайн и использовать специальный плагин asciidoctor.js. И пока у нас дорабатывался пайплайн, решили не терять время и переносить документацию с Confluence в Git с использованием разметки asciidoc.
В дальнейшем можно будет из этого репозитория перенести документацию просто копипастом в текущий репозиторий с кодом или использовать специальные команды Git для миграции.
Сейчас мы в активной части пилота, где документация располагается рядом с кодом.
Для сборщика у нас используется asciidoctor.js.
Изображение мы храним в Git LFS.
Язык разметки также asciidoc, как и для миддл слоя.
Система контроля версий Bitbucket.
Для написания документации в качестве IDE преимущественно используем IDEA, но ограничений нет.
Проблема с фронтом также касалась и бэкенд слоя — здесь тоже есть изображения, которые необходимо описывать в документации. Нам остается только адаптировать форматы и можно будет приступать к пилоту по бэкенд слою.
Используете ли вы подход Docs as Code? Как ведет в этом случае документацию? Ведет ли документацию рядом с кодом? Как решаете проблему с изображениями?
Полезные ссылки:
Курс на Stepik. Рекомендуем, если вы ещё не знакомы с ведением документации рядом с кодом, но хотели бы познакомиться с данным подходом.
Также подписывайтесь на Телеграм-канал Alfa Digital — там мы постим новости, опросы, видео с митапов, краткие выжимки из статей, иногда шутим.