Вступление
Программирование в основном связано с коммуникацией, и одной из наиболее трудоемких частей этого аспекта разработки является передача информации о том, как функционируют API-интерфейсы сервисов. Если это сделано плохо, то документы могут устареть или быть настолько расплывчатыми, что разработчики потратят слишком много времени на ответы на вопросы о том, как работает их API.
В этом посте описан процесс, который мы в Sonalake нашли для автоматизации создания документации REST API. Это сделано таким образом, что после запуска не потребуется слишком много усилий вручную, потому что большая часть деталей документации будет получена из работы, которую вы уже выполняете для тестирования сервиса. Мы предоставили рабочий пример этого в проекте sonalake-autodoc-example .
Движущей силой создания этого процесса была цель предоставить нашим собственным разработчикам, а также нашим клиентам и партнерам хороший опыт разработки (DX) путем предоставления хорошей документации, которая:
- Описывает, что конкретно содержится в API
- Приведены примеры использования API
- Содержит список изменений о том, как API развивался между версиями
Такие инструменты, как Swagger , отлично справляются с автоматизацией документации по пункту 1, но когда дело доходит до пунктов 2 и 3, эти типы документации обычно пишутся вручную (или, что более вероятно, вообще не пишутся).
Создавая документацию из источника, мы обнаружили, что она позволяет автоматически генерировать значительную часть документации API. Создавая документированные примеры из модульных тестов, мы можем гарантировать, что эти примеры всегда соответствуют реальности приложения.
Это также позволяет разработчикам обновлять документацию без необходимости покидать среду разработки, а также выпускать и публиковать документы так же, как и любой другой артефакт разработки.
Как нам это сделать?
Некоторые части документации написаны разработчиками вручную в AsciiDoc . Ожидается, что эти части документации не будут сильно меняться между выпусками и ограничены такими вещами, как:
- Представляем, что такое API
- Описание того, как пройти аутентификацию
- Описание общего набора шагов варианта использования без каких-либо фактических примеров кода (образцы кода будут автоматически сгенерированы во время сборки с использованием данных, переданных в модульные тесты).
Остальная часть процесса создаст следующие разделы, также в AsciiDoc формат.
- Swagger документация, касающаяся путей и объектов
- Примеры кода для шагов варианта использования, сгенерированные на основе модульных тестов
- Журнал изменений история различий между опубликованными версиями swagger.json
Наконец, файлы AsciiDoc сопоставляются и публикуются в одном файле PDF с использованием Asciidoctor PDF .
На высоком уровне основными шагами являются следующие:
Определите Тему | Тема в вышеупомянутом проекте представляет собой простой, чистый макет, подходящий для рендеринга большинства документов, и содержит стандартные элементы отслеживания документов, такие как версии документов. При этом используются стандартные конфигурации темы AsciiDoctor-PDF. |
Генерировать Примеры Фрагментов Кода | Используйте spring-restdocs для документирования входов/выходов для запросов REST путем написания модульных тестов, которые используют API. Позже мы включим эти фрагменты в окончательную документацию. |
Сгенерировать файл swagger.json | Используйте тест весенней загрузки, чтобы запустить приложение в памяти и перенести файл swagger.json в локальный каталог. Для этого вы можете использовать тест из предыдущего шага. |
Создать Список изменений | Используйте плагин Sonalake swagger-changelog для анализа любых ранее опубликованных спецификаций API, сравните его с текущей версией разработчика и создайте список изменений в формате AsciiDoc. |
Авторский Рукописный Контент | Документ, содержащий: * Рукописный контент, который не будет меняться слишком часто. Например, введение. * Документ с примерами кода из простого текста, содержащий ссылки на сгенерированные фрагменты. * Напишите единый рамочный документ, который будет ссылаться как на рукописный, так и на сгенерированный контент. |
У нас есть разработанный пример проекта для демонстрации всех этих шагов: sonalake-autodoc-пример. Это очень простое приложение Spring Boot с тривиальным REST API с двумя методами GET. Остальная часть проекта посвящена исключительно автоматизации документации. Давайте пройдемся по этому вопросу.
Определите Тему
Основным инструментом для генерации AsciiDoctor в PDF является AsciiDoctor-PDF , и он поставляется с полным набором опций тематизации. Образец simple-theme.yml предоставляет простой, чистый профессиональный макет, который вы, вероятно, сможете использовать повторно, просто изменив изображение логотипа.
Генерировать Примеры Фрагментов Кода
Эта часть конвейера генерирует фрагменты в формате AsciiDoc из модульных тестов. Выходные данные содержат примеры вызовов REST с текстами запросов и ответами, которые всегда будут точными для текущей версии базы кода.
В примере проекта все это происходит в BaseWebTest . Он использует преимущества spring-restdocs и действует как базовый класс для всех других модульных веб-тестов.
Вызовы API будут проверяться обычным способом:
mockMvc.perform( get("/api/endpoint-a") .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON) .characterEncoding(StandardCharsets.UTF_8.name()) ).andExpect(status().isOk()).andReturn();
Модульный тест приведенной выше формы генерирует следующие фрагменты для сборки/сгенерированных фрагментов/${имя тестового класса}/${имя тестового метода}
-
Модульный тест приведенной выше формы генерирует следующие фрагменты для
- сборки/сгенерированных фрагментов/${имя тестового класса}/${имя тестового метода}
- Модульный тест приведенной выше формы генерирует следующие фрагменты для
сборки/сгенерированных фрагментов/${имя тестового класса}/${имя тестового метода}
-
Модульный тест приведенной выше формы генерирует следующие фрагменты для
- сборки/сгенерированных фрагментов/${имя тестового класса}/${имя тестового метода}
- Модульный тест приведенной выше формы генерирует следующие фрагменты для
сборки/сгенерированных фрагментов/${имя тестового класса}/${имя тестового метода}
Например, http-запрос на публикацию может выглядеть так:
[source,http,options="nowrap"] ---- POST /api/endpoint-a HTTP/1.1 Content-Type: application/json;charset=UTF-8 Accept: application/json Content-Length: 52 Host: autodoc.sonalake.com { "fieldA" : "sample A", "fieldB" : "sample B" } ----
На эти файлы можно ссылаться в ваших примерах документов, в результате чего примеры всегда будут актуальными.
Сгенерировать файл swagger.json
Эта часть конвейера генерирует обновленное представление путей и объектов REST в формате AsciiDoc. Сначала сгенерировав файл swagger.json, а затем переведя его в AsciiDoc.
Пример проекта содержит один тест, GenerateDocumentationTest.java , который запускает приложение как @SpringBootTest
в профиле test
и удаляет swagger.json
, созданный SwaggerConfig.java . Затем он запускает файл swagger.json через плагин swagger2markup-gradle , чтобы преобразовать его в формат AsciiDoc.
Это приведет к созданию следующих наборов файлов:
- Это приведет к созданию следующих наборов файлов:
Содержит некоторые метаданные из приложения.yml, такие как текст заголовка и информация о версии для включения на главной странице
- Содержит некоторые метаданные из приложения.yml, такие как текст заголовка и информация о версии для включения на главной странице
простая страница, описывающая, как должна быть настроена аутентификация, например заголовки HTTP
- простая страница, описывающая, как должна быть настроена аутентификация, например заголовки HTTP
Список всех ОСТАЛЬНЫХ вызовов и ответов, которые приложение примет и на которые ответит
- Список всех ОСТАЛЬНЫХ вызовов и ответов, которые приложение примет и на которые ответит
список всех организаций, которые приложение примет и ответит
Упростите отслеживание документации
Теги являются необязательным, но полезным инструментом для сбора связанных конечных точек вместе, даже если они реализованы в разных классах. По умолчанию Swagger будет называть ресурсы в честь их классов контроллеров, но теги позволяют присвоить им другое имя.
Например:
@Api(tags = {"Section A"}) @Description("Some operations in section A") public class ControllerA1 {
Создать Список изменений
Последняя часть автоматизированного процесса связана с тем, как создать журнал изменений. Предполагается, что ранее выпущенные версии Swagger публикуются под Nexus. Вся эта конфигурация содержится в build.gradle .
- Опубликуйте спецификацию Swagger в качестве артефакта Nexus с помощью плагинов maven-publish и maven-publish-auth.
- Создайте список изменений из истории Nexus с помощью плагина Sonalake swagger-changelog Gradle. Плагин извлечет все ранее опубликованные версии спецификации Swagger и создаст следующее:
- Файл вида
список изменений-0.0.1-0.0.2- МОМЕНТАЛЬНЫЙ СНИМОК.adoc
для каждой версии - Индексный файл,
список изменений.adoc
, перечисляющий все версии
- Файл вида
Авторский Рукописный Контент
Написание следующих документов завершит этот процесс.
- вступление.adoc – простое описание в одном или двух абзацах того, для чего предназначены приложения
- security.adoc – краткое описание того, как проходить аутентификацию и какие роли существуют в приложении, если таковые имеются. Обратите внимание, что при желании вы можете легко написать другие тесты, которые распечатают список таких ролей в формате AsciiDoc и включат их в этот файл.
Особым случаем рукописного документа является примеры.выше , где будет написано высокоуровневое описание общего потока вызовов REST. Например, чтобы подключить нового пользователя, вам нужно позвонить X, затем Y и тот самый Z. Однако этот документ не будет включать никаких фактических вызовов или параметров REST. Скорее, это будет относиться к результатам модульных тестов, которые вы написали для тестирования этих конечных точек.
[[examplesscheme]] == Examples What follows are some examples of the API usage === Endpoint A A get call include::{snippets}/endpoint-a-test/test-get-value/http-request.adoc[] Returns this include::{snippets}/endpoint-a-test/test-get-value/http-response.adoc[]
Поскольку общий поток вашего приложения вряд ли изменится – даже если URL–адреса и запросы/ответы изменятся – этот документ со временем останется относительно неизменным. Единственное, что вам, скорее всего, придется обновить, – это ваши модульные тесты, но вы все равно это сделаете. Верно?
Связывая все это Воедино
Вся эта работа выполняется в build.gradle – он определяет, куда записывать файлы в каталог сборки.
ext { asciiDocOutputDir = file("${buildDir}/asciidoc/generated") swaggerOutputDir = file("${buildDir}/swagger") snippetsOutputDir = file("${buildDir}/generated-snippets") }
Следующее указывает Gradle передавать системные свойства инструменту тестирования, чтобы задача создания документации могла знать текущую версию документа.
test { systemProperties = System.properties systemProperty 'sg.api.version', version useJUnitPlatform() }
Затем используйте swagger2markup для преобразования файла swagger.json в формат AsciiDoc
convertSwagger2markup { dependsOn test swaggerInput "${swaggerOutputDir}/swagger.json" outputDir asciiDocOutputDir config = [ 'swagger2markup.pathsGroupedBy' : 'TAGS', 'swagger2markup.extensions.springRestDocs.snippetBaseUri': snippetsOutputDir.getAbsolutePath() ] }
Далее, следующее указывает плагину swagger changelog, откуда извлекать информацию о версии и куда записывать файлы различий.
swaggerChangeLog { groupId = "${rootProject.group}" artifactId = "${rootProject.name}-API" // where to find the nexus repo nexusHome = 'http://atlanta.sonalake.corp:8081/nexus' // where to store the changelog targetdir = "${buildDir}/asciidoc/generated/changelog" // if we're building a snapshot version, then include it as the // end of the changelog snapshotVersionFile = "${buildDir}/swagger/swagger.json" }
Наконец, здесь плагин AsciiDoctor-PDF Gradle берет все созданные нами файлы AsciiDoc и преобразует их в pdf.
Обратите внимание, что при настройке baseDirFollowsSourceDir все пути указаны относительно основного индексного файла. Это делается потому, что позволяет ссылкам в файловой структуре AsciiDoc не беспокоиться о том, где они находятся в файловой системе.
// create a PDF from the asciidoc asciidoctorPdf { dependsOn convertSwagger2markup dependsOn generateChangeLog baseDirFollowsSourceDir() sources { include 'api-guide.adoc' } attributes = [ doctype : 'book', toc : 'left', toclevels : '3', numbered : '', sectlinks : '', sectanchors : '', hardbreaks : '', generated : '../../../build/asciidoc/generated', resources : '../../../src/main/resources', snippets : '../../../build/generated-snippets', changes : '../../../build/asciidoc/generated/changelog', imagesdir : 'theme', 'pdf-stylesdir': 'theme', 'pdf-style' : 'simple-theme.yml', revnumber : version ] }
Это оно. Вы можете перенести код из образца проекта в любой проект Spring Boot примерно за час и создать профессиональные, чистые документы. Мы надеемся, что вы найдете это таким же полезным, как и мы!
Оригинал: “https://dev.to/sonalake/the-code-speaks-for-itself-generating-api-docs-for-spring-applications-432d”