Используйте go-swagger для автоматического создания документации swagger для API golang.

задняя часть Go API Swagger
Используйте go-swagger для автоматического создания документации swagger для API golang.

Что такое чванство?

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

Как выглядит документ swagger?

Пример простейшей документации swagger:

swagger: "2.0"

info:
  version: 1.0.0
  title: Simple API
  description: A simple API to learn how to write OpenAPI Specification

schemes:
  - https
host: simple.api
basePath: /openapi101

paths: {}

Советы: Предпосылка чтения этой статьи состоит в том, чтобы предположить, что вы уже знаете, как писать документы swagger.Конечно, если вы этого еще не знаете, это не имеет значения, вы можете перейти кофициальный сайт чванстваОзнакомьтесь с документацией, чтобы узнать, и вот набор«Чванство от входа к мастерству»прикреплять.

Предыстория этой статьи

Причина написания этой статьи заключается в том, что компания требует, чтобы документы API использовали формат swagger, а проект написан на golang.Как ленивый программист, как вы можете написать такой сложный документ swagger? Есть ли инструмент генерации в один клик? Погуглите, действительно есть, т.go-swaggerпроект. Одной из многих особенностей go-swagger являетсяGenerate a spec from source, то есть генерация документов через исходный код, что соответствует моим потребностям.

Ниже приведено краткое введение в то, как добавить аннотации swagger в проект, а затем сгенерировать документацию по API одним щелчком мыши.

Перед запуском необходимо установить два инструмента:

  • swagger-editor: используется для написания документов swagger, отображения пользовательского интерфейса, генерации кода и т. д.
  • go-swagger: для создания документации API одним щелчком мыши

Установите swagger-editor, я использую docker для запуска здесь, другие способы установки, пожалуйста, проверьтеофициальная документация:

docker pull swaggerapi/swagger-editor
docker run --rm -p 80:8080 swaggerapi/swagger-editor

Установите go-swagger, я использую brew для установки здесь, другие способы установки, пожалуйста, проверьтеофициальная документация

brew tap go-swagger/go-swagger
brew install go-swagger

Что ж, теперь мы, наконец, подошли к делу: начинаем программировать!!!

начать писать заметки

1. Предположим, что есть user.server, который предоставляет некоторые REST API для добавления, удаления, изменения и проверки пользовательских данных.

Например, вотgetOneUserИнтерфейс для запроса информации о пользователе:

package service

import (
    "encoding/json"
    "fmt"
    "net/http"
    "strconv"
    "user.server/models"
    "github.com/Sirupsen/logrus"
)

type GetUserParam struct {
    Id int `json:"id"`
}

func GetOneUser(w http.ResponseWriter, r *http.Request) {
    defer r.Body.Close()
    decoder := json.NewDecoder(r.Body)
    var param GetUserParam
    err := decoder.Decode(&param)
    if err != nil {
        WriteResponse(w, ErrorResponseCode, "request param is invalid, please check!", nil)
        return
    }

    // get user from db
    user, err := models.GetOne(strconv.Itoa(param.Id))
    if err != nil {
        logrus.Warn(err)
        WriteResponse(w, ErrorResponseCode, "failed", nil)
        return
    }
    WriteResponse(w, SuccessResponseCode, "success", user)
}

Согласно спецификации документа swagger, документ swagger должен сначала иметь версию swagger и информационную информацию. Чтобы использовать go-swagger, вам нужно всего лишь добавить следующие комментарии перед объявлением пакета:

// Package classification User API.
//
// The purpose of this service is to provide an application
// that is using plain go code to define an API
//
//      Host: localhost
//      Version: 0.0.1
//
// swagger:meta
package service

Затем в корневом каталоге проекта используйтеswagger generate spec -o ./swagger.jsonгенерация командswagger.jsonдокумент:

Эта команда найдет входной файл main.go, затем просмотрит все исходные файлы, проанализирует и сгенерирует файл swagger.json.

{
  "swagger": "2.0",
  "info": {
    "description": "The purpose of this service is to provide an application\nthat is using plain go code to define an API",
    "title": "User API.",
    "version": "0.0.1"
  },
  "host": "localhost",
  "paths": {}
}

2. С базовой информацией, то должны быть маршруты, запросы, ответы и т.д. Для интерфейса getOneUser написаны следующие аннотации swagger:

// swagger:parameters getSingleUser
type GetUserParam struct {
    // an id of user info
    //
    // Required: true
    // in: path
    Id int `json:"id"`
}

func GetOneUser(w http.ResponseWriter, r *http.Request) {
    // swagger:route GET /users/{id} users getSingleUser
    //
    // get a user by userID
    //
    // This will show a user info
    //
    //     Responses:
    //       200: UserResponse
    decoder := json.NewDecoder(r.Body)
    var param GetUserParam
    err := decoder.Decode(&param)
    if err != nil {
        WriteResponse(w, ErrorResponseCode, "request param is invalid, please check!", nil)
        return
    }

    // get user from db
    user, err := models.GetOne(strconv.Itoa(param.Id))
    if err != nil {
        logrus.Warn(err)
        WriteResponse(w, ErrorResponseCode, "failed", nil)
        return
    }
    WriteResponse(w, SuccessResponseCode, "success", user)
}

можно увидеть вGetUserParamДобавьте строку в структуруswagger:parameters getSingleUserИнформация комментария, который является комментарием входного параметра для объявления интерфейса. Несколько строк комментариев внутри структуры указывают на то, что параметр id является обязательным, а идентификатор параметра запроса находится в пути URL. Для подробного использования, пожалуйста, обратитесь к: swagger:params

существуетGetOneUserВ функции:

  • swagger:routeУкажите используемый http-метод, маршрут, метку и идентификатор операции. Подробнее об использовании см.: swagger:route
  • ResponsesУказывает код и тип возвращаемого значения

Затем объявите ответ:

// User Info
//
// swagger:response UserResponse
type UserWapper struct {
    // in: body
    Body ResponseMessage
}

type ResponseMessage struct {
    Code    int         `json:"code"`
    Message string      `json:"message"`
    Data    interface{} `json:"data"`
}

использоватьswagger:responseСинтаксис объявляет возвращаемое значение, а две верхние строки представляют собой описание возвращаемого значения (я не знаю, почему информация описания должна быть написана выше, добро пожаловать в объяснение), подробное использование, см.; swagger:response

затем доступ к браузеруlocalhost, чтобы просмотреть интерфейс редактора swagger, нажмите на панели инструментовFile->Impoprt Fileзагрузить только что созданныйswagger.jsonфайл, вы можете увидеть интерфейс:

Генерируется такой простой документ API

3. Как это?是不是很简单?可是又感觉那里不对,嗯,注释都写在代码里了,很不美观,而且不易维护。想一下go-swagger的原理是扫描目录下的所有go文件,解析注释信息。那么是不是可以把api注释都集中写在单个文件内,统一管理,免得分散在各个源码文件内。

Создать новыйdoc.goфайл, здесь есть еще один интерфейсUpdateUser, то объявляем аннотацию API этого интерфейса в файле doc.go. Первый взглядUpdateUserКод интерфейса:

func UpdateUser(w http.ResponseWriter, r *http.Request) {
    defer r.Body.Close()
    // decode body data into user struct
    decoder := json.NewDecoder(r.Body)
    user := models.User{}
    err := decoder.Decode(&user)
    if err != nil {
        WriteResponse(w, ErrorResponseCode, "user data is invalid, please check!", nil)
        return
    }

    // check if user exists
    data, err := models.GetUserById(user.Id)
    if err != nil {
        logrus.Warn(err)
        WriteResponse(w, ErrorResponseCode, "query user failed", nil)
        return
    }
    if data.Id == 0 {
        WriteResponse(w, ErrorResponseCode, "user not exists, no need to update", nil)
        return
    }

    // update
    _, err = models.Update(user)
    if err != nil {
        WriteResponse(w, ErrorResponseCode, "update user data failed, please try again!", nil)
        return
    }
    WriteResponse(w, SuccessResponseCode, "update user data success!", nil)
}

Затем напишите следующий оператор в файле doc.go:

package service

import "user.server/models"

// swagger:parameters UpdateUserResponseWrapper
type UpdateUserRequest struct {
    // in: body
    Body models.User
}

// Update User Info
//
// swagger:response UpdateUserResponseWrapper
type UpdateUserResponseWrapper struct {
    // in: body
    Body ResponseMessage
}

// swagger:route POST /users users UpdateUserResponseWrapper
//
// Update User
//
// This will update user info
//
//     Responses:
//       200: UpdateUserResponseWrapper

Таким образом извлекается аннотация объявления API, а затем используется командаswagger generate spec -o ./swagger.jsonСоздайте файл json, вы можете увидеть результат следующим образом:

Это очень просто, напишите несколько строк комментариев со ссылкой на документацию, а затем сгенерируйте документацию по API одной командой. Евангелие от ленивого программиста-рака~

Весь пример кода для этой статьи размещен по адресуздесь, оригиналадрес

Ссылаться на: