Хабрахабр

[Из песочницы] Генерация OpenAPI спецификации на основе функциональных тестов

image

Разрабатывая API, наверняка не раз появлялись сложности с документацией: то её нет, то она не отображает поведение, описанное в коде.

Знакомо? С точки зрения разработчика, написание документации (одной только внутренней) занимает не меньше времени, чем написание самого кода. Тогда добро пожаловать под кат.

А проблема-то есть?

Наша команда давно разрабатывает API, который является основой нашего продукта, но живых пользователей у него, на тот момент, не было, поэтому и необходимости документировать что-то для внешнего использования никто не видел. Как и все команды, мы начали с внутренней документации — сначала один метод, потом другой. В нашем пространстве в Confluence можно найти десяток другой страниц, где отображена довольно шаблонная информация – что за метод API, какой у него query path, какие параметры и что мы получим на выходе.

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

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

Немного решений

Есть разные варианты, как могут быть взаимосвязаны код и спецификация кода, но я для себя выделяю два:

  • Code first, specification next
  • Specification first, code next

Начну со второго, как с варианта, который нам меньше всего подходил.

Specification first, code next — это про генерацию кода, на основе спецификации, то есть кода не существует, пока вы не напишите спецификацию.

Самый простой пример — Swagger Codegen.

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

Но тут встал вопрос — а если нам не хочется делать лишних движений, чтобы генерировалась спецификация? Code first, specification next — тут всё просто, сначала пишем код, потом спецификацию.

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

«Ты ж программист» — сказал я себе и решил написать небольшой прототип, который позволит не писать всю эту рутинную фигню.

Делая очередную задачу и написать n-ый функциональный тест, я понял, что вся информация для спецификации у нас уже есть.

У нас есть функциональные тесты, которые содержат практически всю нужную нам информацию:

  • Что вызывается
  • С чем вызывается (параметры, тело, заголовки и пр.)
  • Какой результат ожидается (статус код, тело ответа)

Почему бы не сделать собственный велосипед?

По сути, всё практически всё, что мы обычно пишем в спецификации у нас есть. Дело за малым — закодить это дело.

Используя немного магии рефлексии, собираем все доступные нам методы API, из функциональных тестов берем данные, извлекаем данные об авторизации и её типе. Поскольку наше приложение на php, то на помощь мне пришла рефлексия. Смешав всё это, приправив специфичными фичами для используемого в наших решениях фреймворка, мы за пару недель получаем решение, которое практически не требует дополнительного времени от разработчика. Из обычных аннотаций к методам, мы достаем само описание метода.

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

Но с таким решением есть немало рисков: Проблему, которая была изначально, мы решили.

  • Цена поддержи собственного велосипеда
  • Расширение необходимого функционала
  • Актуализация и синхронизация переводов

Эти риски нужно иметь в виду и, если они начинают срабатывать, то принимать меры.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть