Документирование #Микросервисов
Оригнинальная статья является размышления на тему почему документация в мире микросервисов критично необходима и как ее можно создавать и публиковать используя swagger. Пошаговой инструкцией по настройке она точно не является.
Вступление
Несколько месяцев назад один из наших бекенд разработчиков интернов получил задачу — разработать новый простой сервис. Сервис должен был генерировать емайл отчеты о пользовательской активности. В задаче не было ничего сложного и у интерна все получилось. Однако через несколько недель мы захотели включить в отчет более детальную информацию о некоторых конкретных пользователях. Я решил обновить этот сервис самостоятельно. «Просто получи данные из нашего пользовательского сервиса и вставь их в емайл», — думал тогда я.
На это у меня ушло несколько часов, и даже пришлось подключить двоих других разработчиков только для того, чтобы найти правильные REST endpoints и необходимые мен структуры. «Никогда больше. Должен быть более правильный метод это сделать…», — крутилось у меня в голове все это время.
Микросервисная архитектура подразумевает набор самостоятельных сервисов, которые общаются друг с другом, а для конечного пользователя выглядит как единая программа. Один из самых популярных протоколов для обмена сообщениями между микросервисами — это REST. Проблема в том, что REST не является само описательным протоколом. Это значит, что клиент должен знать конкретную комбинацию URL, HTTP метода и формата ответа. В некоторых случаях необходимо также знать также формат тела запроса. Обычно реализация REST интерфейса базируется на общих принципах и традициях, принятых в вашей организации. В любом случае, REST endpoints всегда должны быть описаны в одном конкретном документе, доступном для всех остальных разработчиков. О том, как и где хранить, мы поговорим чуть позже, а пока давайте обсудим основы — формат документации.
Swagger.
Документацию должно быть легко читать, писать, парсить, генерировать, исправлять, обновлять и прочее. Решение должно быть настолько простым, чтобы даже самые ленивые разработчики им пользовались. После небольшого исследования мы в Ataccama решили использовать Swagger для документирования наших REST APIs.
Swagger — это фреймворк и спецификация для определения REST APIs в формате, дружественном к пользователю и компьютеру (в нашем случае JSON или YAML). Но Swagger — это не просто спецификация. Основная его мощь заключается в дополнительных инструментах. Для Swagger существует огромное количество бесплатных утилит (как официальных, так и написанных сообществом), которые могут сделать жизнь (вашу и ваших коллег) немного более счастливой. Вы можете установить все это на свои собственные сервера и посмотреть, как это работает — например, попробовать работу с браузером документов или Swagger онлайн-редактором.
Как мы это делаем?
Если вы тоже думаете, что Swagger — это здорово, то читайте дальше. Сейчас будет немного подробностей о том, как мы используем его в Ataccama, в таинственном мире микросервисов.
У каждого микросервиса в определенной папке лежит файл со Swagger описанием и хранится это все прямо в git-репозитории. Описания могут быть как сгенерированы при помощи Swagger generator, так и записаны туда вручную. Прелесть заключается в том, что для записи определений используются JSON и YAML форматы. Их легко распарсить, и во время сборки проекта мы можем автоматически проверять соответствие REST endpoints и документации. Несоответствия будут генерировать предупреждения, и тем самым стимулировать разработчика поддерживать документацию в актуальном состоянии.
Хранение документации внутри микросервиса позволяет нам отображать её в любое время прямо из этого микросервиса в процессе работы. Это помогает тестировать и отлаживать REST endpoints в процессе развертывания сервиса на собственной машине. А ещё у Swagger есть инструмент с веб интерфейсом для тестирования REST endpoints.
Поскольку каждый микросервис предоставляет собственную документацию, мы можем настроить специальную задачу для Дженкинса (или любого другого CI сервера), которая сгенерирует полную документацию для всего проекта. Эта задача собирает Swagger файлы из всех микросервисов, производит некоторые минимальные модификации (дедупликация, удаление ненужных атрибутов) и на выходе генерирует единый Swagger файл, содержащий полную актуальную информацию для всего проекта.
Публикация документации.
Централизованное хранение и редактирование документации — это только первый шаг. Следующий — сделать ее доступной для всех разработчиков, тестеров и остальных заинтересованных людей в компании. И Swagger UI — это именно то, что вам для этого понадобится. При помощи небольшой JavaScript библиотеки Swagger UI генерирует HTML элементы для всех ваших REST endpoints, которые далее можно упорядочивать с помощью HTML разметки.
По умолчанию Swagger UI подгружает собственный Swagger файл с примерами. Все остальные API должны быть загружены вручную. Но конфигурация занимает всего несколько секунд.
var swaggerUi = new SwaggerUi({
url: ‘http://example.com/swagger.json',
dom_id: ‘swagger-ui-container’
});
swaggerUi.load();
Теперь у нас есть сгенерированная документация в читабельном виде. Время отправить её на сервер.
Некоторое время назад мы в Ataccama начали использовать Docker, и поэтому подумали, а почему бы не упаковать всю документацию в отдельный докер контейнер, загрузить его в наш частный репозитарий, а потом задеплоить в докер кластер? Дженкинc может это сделать буквально за несколько секунд. Как результат мы всегда имеем обновленную документацию доступную к просмотру через браузер.
Кроме того, использование докера дает нам еще несколько преимуществ:
- Каждый разработчик может просто загрузить документацию и запустить её на собственном компьютере всего одной командой.
- У каждого докер образа есть версия, и если вам нужна документация к более старому релизу, просто загрузите другой образ с другим докер тегом.
И это только начало.
Это только общая идея того как мы генерируем документацию для REST endpoints и публикуем ее при помощи докера для наших микросервисов. К сожалению, синхронный REST это не все, что нам надо документировать в этом лабиринте микросервисов. В какой-то момент хочется перейти на более продвинутые системы общения, на асинхронный обмен сообщениями, очереди, подписки на события и прочее.
Несмотря на расхваливание Swaggerа мы все еще не нашли удобного метода документирования асинхронных сообщений. По факту, в Атаккаме мы недовольны нашим текущим решением и все еще пытаемся найти что-нибудь более простое и красивое для описания очередей сообщений и их структур. Если у вас есть идеи как это можно сделать лучше, пишите в комментариях. Любые интересные идеи приветствуются.
Оригинал статьи находится здесь.Автор Lubos Palisek
Backend software developer in Ataccama. Greedy for new cloud based technologies and ideas.Ataccama Corporation — международная компания, производитель программного обеспечения, специализирующаяся в области решений по управлению качеством данных, управлению мастер-данными и управления данными предприятия (data governance), решениями которого уже воспользовались более 250 компаний, начиная от предприятий среднего размера и заканчивая международными компаниями из различных отраслей.
Все ваши вопросы и рекомендации с удовольствием переведу автору.
Комментарии (6)
23 февраля 2017 в 15:20
0↑
↓
Свагер это хорошо, хипстово, современно. Но жизнь чуточку сложнее — бывают сложные сценарии, когда нужно дергать последовательность ручек, вот отсюда из ответа надо взять ИД и передать сюда итд.Да и стороннему заказчику такое не отдашь, все равно приходится писать текстовое описание.
23 февраля 2017 в 15:42
0↑
↓
С этим не поспоришь и именно поэтому автор пишет, что ищет новое более гибкое и умное решение. Но пока что со своими функциями свагер справляется.>Да и стороннему заказчику такое не отдашь, все равно приходится писать текстовое описание.
У нас свагер используется в SAAS проекте, поэтому отдавать заказчику ничего не надо. А кроме того там хранится только документация для разработчиков. Для пользовательской используются совсем другие средства и даже другая команда.
23 февраля 2017 в 15:54
0↑
↓
Микросервисы могут быть написаны не с использованием REST, а, например, с использованием GraphQL или чего — то внутреннего и тогда swag бесполезен.Отличным местом для описания общения подходит Wiki, проверено. У этого способа описания API тоже есть свои недостатки. Основной, отсутствие генерации кода, зато можно описать что угодно.
23 февраля 2017 в 16:32
0↑
↓
может быть что угодно, но поскольку у нас REST почему бы не использовать подходящий для этого инструмент.Вики это хорошо, даже чуть лучше чем просто текстовый файлик на виндовой шаре, но автоматически проверять соответствие документации и существующих эндпоинтов он не может.
23 февраля 2017 в 16:01
0↑
↓
Ох щас выскажусь, об этом сервисе и опыте использования, он конечно может показаться однобоким, так как я не разворачивал его локально, а пользовался онлайн возможностями, но тем не менее. Задача была простой: во время написания сервиса на Flask, нужно было просто какой нить удобный и документированный «тестер запросов», плюс минимально еописание — что делает тото или иной роут, сам сервис небольшой — 40–50 REST API, теперь по порядку.
1. Уродливая система объявления. Куча обязательных параметров, навроде description и прочего, без которого не заводится скрипт, какая то «местозависимая» система объявления (обязательные параметры не выходило менять местами — на кой черт они тогда именованные?) —, но черт, мне нужно всего лишь отправить запрос
2. Ужасный онлайн редактор и вывод трейсбеков. Нельзя ровно ни скопировать ни вставить, ни потом запустить. Приходилось одно и тоже по 5 раз переписывать, понять где ошибка просто невозможно, табы/пробелы не различает не заменяет, короче боль. О автодополнении молчу.
3. Глючный UI JS. Создаем роут, описываем ответы, делаем запрос, если JS вдруг получит не то что ожидал (ну например у вас сервак что-то там запарился) — все, UI умирает, ничего отправить/принять нельзя. В хроме UI не работал СОВСЕМ.
4. Авторизация — да чуваки, в 2016 все пользовались только basic типом, и все, другого не дано. Ни совместную не сделать, ни отличную от того что предлагает сам «швагер», а скажите, как мне передать API ключ для всех запросов остальных?, а ни как, сначала запускаешь первый запрос, получаешь ключ, и потом его руками копируешь. А что делать если api_key временный?
5. Генерация. Это совсем отдельная песня, такое чувство что он не знает о существовании каких то правил в языках, по крайней мере в питоне, Пустые роуты я и сам могу написать.
Большего терпеть я не стал, и прекратил работу с данным сервисом. У меня все. Не знаю как сейчас у них дела, но все описанное было правдой на лето 2016 года.23 февраля 2017 в 16:34
0↑
↓
перевел ваш комментарий автору статьи, посмотрим что скажет.