Nixys > Журнал > Автоматизируем документирование кода с помощью Swagger

Автоматизируем документирование кода с помощью Swagger

  • 1 октября 2019
  • #

Небольшая предыстория или была ли жизнь до Swagger?

Обслуживая много разных инфраструктур наших клиентов, мы стараемся не забывать и про свою собственную. За то время, что мы работаем (с 2011 года), наша инфраструктура прошла путь от 2-ух виртуалок, на которых крутились Redmine и Zabbix, до нескольких кластеров Kubernetes, кластера баз данных, распределённого файлового хранилища и ~40 различных самописных систем, инструментов и сервисов, задача которых максимально упростить наши админские будни и сделать обслуживание клиентских проектов удобным и эффективным.

С ростом количества разрабатываемых систем и их сложности, увеличивался и штат команды разработки. Вместе с этим вставали всё более “взрослые” проблемы, как построить оптимальный процесс разработки. Одной из таких проблем была документация. Каждая команда пилит свою систему. Нам очень хотелось, чтобы различные системы дружили друг с другом. Для этого у каждой системы есть API. Нужно было где-то хранить их описания, шарить между командами и поддерживать в актуальном состоянии.

Мы пробовали писать wiki. Какое-то время это работало, но когда проект разрастался и микросервисов становилось много, wiki просто забывали обновлять. В результате часто бывало так, что когда у кого-то из разработчиков находилось желание добавить свои последние изменения в wiki, он понимал, что она уже настолько старая, что для того, чтобы добавить последние изменения, нужно чуть ли не переписать её целиком. Но на это нужен не один час, а задач в стеке много… и у разработчика пропадало всякое желание что-то делать.

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

Сказать, что так делать неправильно — ничего не сказать. Такой подход порождал закономерные проблемы. Когда кто-то из разработчиков уходил, вместе с них уходила и так никогда и не описанная часть “документации”. В то же время, когда приходил новый разработчик, нужно было вводить его в проект и дать актуальную информацию по API системы, над которой он будет работать, а также API смежных систем, с которыми ему надо будет взаимодействовать.

Мы начали думать, что с этим делать, и так совпало, что у одного из клиентов стали возникать проблемы с сервисом по имени Swagger — он никак не хотел нормально работать в Kubernetes. На тот момент мы не знали, что такое этот Swagger, так как изначально ставили его разработчики клиента, и для нас он был просто одним из клиентских приложений, которые нужно завезти в Kubernetes и обеспечить стабильную работу. Со Swagger сходу так не получилось, поэтому мы были вынуждены начать копать, что это за софтина, для чего используется и как работает. И в итоге сделали для себя очень крутое открытие! Впоследствии мы начали использовать Swagger у себя в команде и это изменило нашу жизнь в самую лучшую сторону, в стане разработчиков стало спокойнее, по ощущениям они даже стали меньше материться 🙂

Что такое Swagger?

Итак, что такое этот Swagger? Если кратко, то это стандарт по созданию RESTful API и набор сопутствующих open-source и коммерческих инструментов для работы с ними: проектирования, прототипирования, документации, стандартизации, тестирования и даже деплоя.

Официальный сайт — https://swagger.io/. Проект развивается с 2010 года. Изначально его создатели ставили перед собой цель собрать лучшие практики и сформировать некий максимально удобный стандарт для проектирования RESTful API, который назвали Swagger Specification. У них это получилось, проект нашёл отклик у разработчиков. В 2015 году Swagger был приобретён американской компанией SmartBear Software, которая передала Swagger Specification в Linux Foundation. Впоследствии стандарт был переименован в OpenAPI Specification и с тех пор существует и развивается под этим именем.

Помимо стандарта Swagger также предоставляет набор open-source и коммерческих инструментов для проектирования, визуализации и тестирования API, а также для командной работы над ними (Swagger Codegen, Swagger Editor, Swagger UI, SwaggerHub, Swagger Inspector).

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

package main

import (
    "fmt" 
    "net/http" 

    "github.com/gorilla/mux" 
    "github.com/swaggo/http-swagger" 
)

const (
    requestMaxPOSTBodySize = 2048
)

func epRoutesSet(ctx selfContext) *mux.Router {

    r := mux.NewRouter()

    // swagger:operation POST /monitoring monitoring monitoringAdd
    //
    // Adds new server into Nixys Monitoring system
    // ---
    // consumes:
    // - application/json
    // produces:
    // - application/json
    // parameters:
    // - name: body
    //   description: Data to add new server into Nixys Monitoring system
    //   in: body
    //   required: true
    //   schema:
    //     $ref: '#/definitions/MonitoringAddSeverRequest'
    // security:
    // - apiKeyHeader: []
    // responses:
    //   '200':
    //     description: Successfully added new server into Nixys Monitoring system
    //     type: string
    //   '400':
    //     description: Bad request json. See response json for details
    //     type: string
    //   '413':
    //     description: Request entity too large. See response json for details
    //     type: string
    //   '500':
    //     description: Internal errors while adding new server into Nixys Monitoring system. See response json for details
    //     type: string
    //   'default':
    //     description: In all cases response will contain following json
    //     schema:
    //       $ref: '#/definitions/MonitoringAddSeverResponse'
    r.Handle("/monitoring", epMonAdd(ctx)).Methods("POST")

[...]
// Monitoring Add Sever Request model
//
// swagger:model MonitoringAddSeverRequest
type monAddServerReq struct {

    // New server name
    //
    // required: true
    // example: 585-test-cluster-web-v2
    Name string `json:"name"`

    // New server IP
    //
    // required: true
    // example: 10.1.1.2
    IP string `json:"ip"`

    // New server port
    //
    // required: true
    // example: 10150
    Port string `json:"port"`

    // New server alert type
    // Available values: slow | fast
    //
    // required: true
    // example: slow
    AlertType string `json:"alert_type"`
}

// Monitoring Add Sever Response model
//
// swagger:model MonitoringAddSeverResponse
type monAddServerResp struct {

    // Added server name
    // Has empty value on error
    //
    // required: true
    // example: 585-test-cluster-web-v2
    ServerName string `json:"server_name"`

    // Zabbix server
    // Has empty value on error
    //
    // required: true
    // example: https://monitor-1.nixys.ru
    ZabbixHost string `json:"zabbix_host"`

    // Additional response message
    // Message contains either 'success' or error message
    //
    // required: true
    // example: success
    Message string `json:"message"`
}

Swagger его подтягивает и создаёт раздел документации:

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

Swagger предоставляет простой и удобный интерфейс для просмотра документации ваших API — Swagger UI. В нём можно создавать проекты, просматривать спецификации API, примеры запросов, и даже простестировать работу отдельных методов:

Итого, получается, что мы можем полностью сосредоточиться на процессе разработки, при этом Swagger позаботится о документации за нас. Кроме этого, есть ещё один полезный побочный эффект — если раньше мы могли лениться писать подробные комментарии по коду, то теперь мы просто вынуждены это делать. Со временем это входит в привычку, в результате код становится гораздо более читабельным. В общем, сплошной профит!

Встраиваем Swagger в процессы CI/CD — автоматизируем документацию кода

Так как мы DevOps-ы, грех этим не воспользоваться. Чтобы сделать свою работу ещё удобнее, мы доработали наши процессы CI/CD и встроили генерацию необходимых файлов для Swagger одним из этапов в наш Gitlab CI. Теперь нам достаточно запушить коммит и документация обновится автоматически.

Вместо заключения

На текущий момент мы работаем со Swagger около полугода. Пока что впечатления очень положительные. Инструмент позволил нам решить давнюю проблему с поддержкой документации в актуальном состоянии. Разработчикам больше не надо отвлекать друг друга для того, чтобы получить всю необходимую для них документацию по интересующим API.