Все еще используете Swagger2 для создания документации Restful API? Приходите попробовать Api2Doc!

задняя часть

В этой статье представлен очень полезный инструмент для автоматического создания документации Restful API — Api2Doc, который основан на SpringBoot, в принципе похож на Swagger2, но проще и удобнее в использовании, чем Swagger2.

Этот проект был размещен в github, друзья, которым нужен исходный код, пожалуйста, нажмитездесь

содержание

  • история проекта
  • Введение в Api2Doc
  • Внедрить зависимость Api2Doc
  • Включить службу Api2Doc
  • Добавьте аннотации документации к классу контроллера.
  • Подробности аннотации @Api2Doc
  • Подробности аннотации @ApiComment
  • Подробности аннотации @ApiError
  • Сортировка пунктов меню документа
  • Дополнительная пользовательская документация
  • Приветственная страница пользовательской документации
  • Настройте заголовок и значок документа
  • Закройте службу Api2Doc.

история проекта

В процессе исследований и разработки программного обеспечения для Интернета/мобильного Интернета большинство групп НИОКР имеют очень четкое разделение работы переднего и заднего плана. Интерфейсы HTTPS Restful API, в то время как фронтенд-инженеры отвечают за Android и iOS. , Разработка страницы H5, вам нужно вызвать интерфейс Restful API.

Для этого требуется набор документов Restful API, чтобы помочь двум сторонам общаться в интерфейсе API и достигать консенсуса. В основном работа по написанию документации ложится на бэкенд-инженеров, ведь они предоставляют API.

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

Поэтому некоторые отраслиАвтоматически генерировать документацию Restful API из кодаSwagger2 – это проект с открытым исходным кодом, который лучше всего сочетается с Spring Boot. Swagger2 автоматически создает документы API, считывая аннотацию в коде контроллера, что может значительно сократить объем работы по написанию документов вручную.

Автор этого проекта и раньше использовал Swagger2, но обнаружил, что в Swagger2 тоже есть много неудобных мест:

Первый,Аннотации Swagger2 очень раздуты, давайте посмотрим на этот код:


@RestController
@RequestMapping(value = "/user3")
public class UserController2Swagger2 {

    @ApiOperation(value = "获取指定id用户详细信息",
            notes = "根据user的id来获取用户详细信息",
            httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "用户名",
                    paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "用户密码",
                    paramType = "query", required = true, dataType = "String")
    })
    @RequestMapping(name = "用户注册", value = "/regist",
            method = RequestMethod.GET)
    public UserInfo regist(@RequestParam("userName") String userName,
                           @RequestParam("password") String password) {
        return new UserInfo();
    }
}

@ApiOperation и @ApiImplicitParam — это аннотации, предоставляемые Swagger2 для определения информации об API. На самом деле сам метод API содержит много информации, такой как HTTP-метод, имя параметра, тип параметра и т. д. Например, в @ApiImplicitParam, кроме полезного атрибута value, повторяются другие описания.

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

В-третьих, в Swagger2 все еще есть много деталей, которые не были сделаны хорошо, например, глядя на эту картинку:

swgger2-1.png

API в красной рамке на самом деле соответствует одному и тому же методу Причина, по которой их так много, заключается в том, что метод не указан при написании этого метода:

@RestController
@RequestMapping(value = "/user2")
public class UserController2Swagger2 {
    
    @RequestMapping(value = "/do_something")
    public void doSomethingRequiredLogon() {
    }
    
    // 其它方法,这里省略...
}

(Если метод не указан, Spring Boot заставит этот интерфейс поддерживать все методы по умолчанию)

Поэтому, учитывая, что лучше потратить некоторое время на создание более качественной «автоматизированной системы документирования», чем долго терпеть различные неудобства Swagger2, родился этот проект: Api2Doc.

Введение в Api2Doc

Api2Doc ориентирован на автоматическую генерацию документов Restful API.Его принцип аналогичен Swagger2.Он генерирует документы путем отражения и анализа информации в контроллере, но намного лучше, чем Swagger2.

Самые большие отличия:Api2Doc пишет намного меньше кода, чем Swagger2.

Например, код с использованием Swagger2 выглядит так:


@RestController
@RequestMapping(value = "/user")
public class UserController {

    @ApiOperation(value = "添加用户", httpMethod = "POST",
            notes = "向用户组中添加用户,可以指定用户的类型")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "group", value = "用户组名",
                    paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "name", value = "用户名",
                    paramType = "query", required = true, dataType = "String"),
            @ApiImplicitParam(name = "type", value = "用户类型",
                                paramType = "query", required = true, dataType = "String")
    })
    @RequestMapping(value = "/addUser", method = RequestMethod.POST)
    public User addUser(String group, String name, String type) {
        return null; // TODO:  还未实现。
    }
}

Давайте посмотрим на код, украшенный аннотациями Api2Doc:

@Api2Doc(id = "users")
@ApiComment(seeClass = User.class)
@RestController
@RequestMapping(value = "/api2doc/demo2")
public class UserController2 {

    @ApiComment("向用户组中添加用户,可以指定用户的类型")
    @RequestMapping(name = "添加用户",
            value = "/user", method = RequestMethod.POST)
    public User addUser(String group, String name, String type) {
        return null; // TODO:  还未实现。
    }
    
    // 其它方法,这里省略...
}

См., API2DOC необходимо только добавить очень небольшое количество кода, такого как @ API2DOC @apicomment Antotionations к методам, но документация, которую она генерирует, может быть однозначной, как показано на следующем рисунке:

api2doc-2-1.png api2doc-2-2.png

Некоторым друзьям это может показаться очень странным: описания и примеры значений на странице документации не прописаны в коде, откуда они берутся?

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

Это немного абстрактно, давайте ответим на этот вопрос в лоб, обратите внимание, что на этот класс есть аннотация:

@ApiComment(seeClass = User.class)

Это означает: при отсутствии информации описания в методе API обратитесь к информации описания, определенной в классе User.

Вот код для класса User:

public class User {

    @ApiComment(value = "用户id", sample = "123")
    private Long id;

    @ApiComment(value = "用户名", sample = "terran4j")
    private String name;

    @ApiComment(value = "账号密码", sample = "sdfi23skvs")
    private String password;

    @ApiComment(value = "用户所在的组", sample = "研发组")
    private String group;

    @ApiComment(value = "用户类型", sample = "admin")
    private UserType type;

    @ApiComment(value = "是否已删除", sample = "true")
    @RestPackIgnore
    private Boolean deleted;

    @ApiComment(value = "创建时间\n也是注册时间。")
    private Date createTime;

    // 省略  getter / setter 方法。
}

Ты понимаешь? Если параметр в методе API имеет то же имя, что и атрибут класса User, он будет автоматически заполнен информацией описания @ApiComment атрибута класса.

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

Конечно, это лишь одна из особенностей, которыми Api2Doc лучше, чем Swagger2, и есть много вещей, которые лучше, чем Swagger2.

Далее мы подробно объясним его использование, надеясь помочь разработчикам избавиться от горького моря написания документации.

Внедрить зависимость Api2Doc

Если это maven, добавьте зависимость в pom.xml следующим образом:

        <dependency>
            <groupId>com.github.terran4j</groupId>
            <artifactId>terran4j-commons-api2doc</artifactId>
            <version>${api2doc.version}</version>
        </dependency>

Если это gradle, добавьте зависимость в build.gradle следующим образом:

compile "com.github.terran4j:terran4j-commons-api2doc:${api2doc.version}"

Последняя стабильная версия ${api2doc.version}, см.здесь

Включить службу Api2Doc

Пример кода для этого руководства находится в com.terran4j.demo.api2doc в каталоге src/test/java, или вы можете загрузить его сздесьполученный.

Во-первых, нам нужно добавить аннотацию @EnableApi2Doc к классу, аннотированному @SpringBootApplication, чтобы включить службу Api2Doc, как показано в следующем коде:

package com.terran4j.demo.api2doc;

import com.terran4j.commons.api2doc.config.EnableApi2Doc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

//  文档访问地址: http://localhost:8080/api2doc/home.html
@EnableApi2Doc
@SpringBootApplication
public class Api2DocDemoApp {

    public static void main(String[] args) {
        SpringApplication.run(Api2DocDemoApp.class, args);
    }

}

Добавьте аннотации документации к классу контроллера.

Затем мы добавляем аннотацию @Api2Doc в класс RestController и добавляем аннотацию @ApiComment там, где требуется документация, как показано ниже:

package com.terran4j.demo.api2doc;

import com.terran4j.commons.api2doc.annotations.Api2Doc;
import com.terran4j.commons.api2doc.annotations.ApiComment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@Api2Doc(id = "demo1", name = "用户接口1")
@ApiComment(seeClass = User.class)
@RestController
@RequestMapping(value = "/api2doc/demo1")
public class UserController1 {

    @ApiComment("添加一个新的用户。")
    @RequestMapping(name = "新增用户",
            value = "/user", method = RequestMethod.POST)
    public User addUser(String group, String name,
                        @ApiComment("用户类型") UserType type) {
        return null; // TODO:  还未实现。
    }
}

Тип возвращаемого значения этого метода класса User определяется как:

public class User {

    @ApiComment(value = "用户id", sample = "123")
    private Long id;

    @ApiComment(value = "用户名", sample = "terran4j")
    private String name;

    @ApiComment(value = "账号密码", sample = "sdfi23skvs")
    private String password;

    @ApiComment(value = "用户所在的组", sample = "研发组")
    private String group;

    @ApiComment(value = "用户类型", sample = "admin")
    private UserType type;

    @ApiComment(value = "是否已删除", sample = "true")
    @RestPackIgnore
    private Boolean deleted;

    @ApiComment(value = "创建时间\n也是注册时间。")
    private Date createTime;

    // 省略  getter / setter 方法。
}

А тип атрибута type, то есть класс UserType определяется как:

package com.terran4j.demo.api2doc;

import com.terran4j.commons.api2doc.annotations.ApiComment;

public enum UserType {

    @ApiComment("管理员")
    admin,

    @ApiComment("普通用户")
    user
}

После написания кода запускаем функцию main для перехода на главную страницу Api2Doc:

http://localhost:8080/api2doc/home.html

Страница документации выглядит следующим образом:

api2doc-3-1.png api2doc-3-2.png

Объясните, что сервис Api2Doc работает, это так просто!

Подробности аннотации @Api2Doc

Api2Doc имеет в общей сложности 3 аннотации: @Api2Doc, @ApiComment и @ApiError.

@Api2Doc используется для управления созданием документации.

@Api2Doc оформлен в классе, что указывает на то, что этот класс будет участвовать в процессе создания документа. Служба Api2Doc будет сканировать все классы Controller в контейнере Spring. Только классы с @Api2Doc в классе будут генерировать документы. Один класс соответствует Элемент меню первого уровня в левой части страницы, атрибут имени @Api2Doc представляет имя этого пункта меню.

@Api2Doc также можно изменить в методах, но @Api2Doc в методах обычно можно опустить.Служба Api2Doc просканирует все методы с @RequestMapping в этом классе, и каждый такой метод соответствует вторичному меню в левой части страницы документа. , имя пункта меню принимает атрибут имени @RequestMapping, конечно, вы все еще можете использовать атрибут имени @Api2Doc для переопределения метода.

Подробности аннотации @ApiComment

@ApiComment используется для описания API, его можно оформить во многих местах:

  • Он оформлен на классе, указывая на то, что эта группа API-интерфейсов описана;
  • Изменено на методе, то есть для описания интерфейса API;
  • Модифицировано по параметрам, то есть для описания параметров запроса данного интерфейса API;
  • Изменено свойство возвращаемого типа, указывающее описание возвращаемого поля этого интерфейса API;
  • Изменено в элементе перечисления с указанием описания элемента перечисления;

Если описание поля атрибута или параметра с тем же именем и значением было определено в другом месте, атрибут seeClass @ApiComment может использоваться для указания информации описания в поле с тем же именем указанного класса, как в этом код:

@Api2Doc(id = "demo1", name = "用户接口1")
@ApiComment(seeClass = User.class)
@RestController
@RequestMapping(value = "/api2doc/demo1")
public class UserController1 {

    @ApiComment("添加一个新的用户。")
    @RequestMapping(name = "新增用户",
            value = "/user", method = RequestMethod.POST)
    public User addUser(String group, String name, UserType type) {
        return null; // TODO:  还未实现。
    }
}

Хотя три параметра группы, имени и типа не описываются с помощью @ApiComment, поскольку в этом классе есть @ApiComment (см. Класс = User.class), если класс User имеет поля группы, имени, типа и описание @ApiComment. Вот и все.

Подробности аннотации @ApiError

@ApiError используется для определения кодов ошибок. Некоторые методы API будут генерировать ошибки при выполнении бизнес-логики. После возникновения ошибки код ошибки будет включен в возвращаемое сообщение, чтобы упростить дальнейшую обработку клиентом в соответствии с кодом ошибки. Описание код ошибки показан выше.

Следующий код демонстрирует использование @ApiError:

@Api2Doc(id = "demo", name = "用户接口", order = 0)
@ApiComment(seeClass = User.class)
@RestController
@RequestMapping(value = "/src/test/resources/demo")
public class UserController {
    
    @Api2Doc(order = 50)
    @ApiComment("根据用户id,删除指定的用户")
    @ApiError(value = "user.not.found", comment = "此用户不存在!")
    @ApiError(value = "admin.cant.delete", comment = "不允许删除管理员用户!")
    @RequestMapping(name = "删除指定用户",
            value = "/user/{id}", method = RequestMethod.DELETE)
    public void delete(@PathVariable("id") Long id) {
    }
}

Атрибут value @ApiError представляет код ошибки, а комментарий представляет описание кода ошибки.

Информация о коде ошибки будет отображаться в конце документа, и эффект будет следующим:

api2doc-7.png

Сортировка пунктов меню документа

Мы можем использовать свойство порядка в @Api2Doc для упорядочения элементов меню, чем меньше значение порядка, тем больше элемент меню находится впереди, например, для этого кода:

package com.terran4j.demo.api2doc;

import com.terran4j.commons.api2doc.annotations.Api2Doc;
import com.terran4j.commons.api2doc.annotations.ApiComment;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@Api2Doc(id = "demo2", name = "用户接口2", order = 1)
@ApiComment(seeClass = User.class)
@RestController
@RequestMapping(value = "/api2doc/demo2")
public class UserController2 {

    @Api2Doc(order = 10)
    @ApiComment("添加一个新的用户。")
    @RequestMapping(name = "新增用户",
            value = "/user", method = RequestMethod.POST)
    public User addUser(
            @ApiComment("用户组名称") String group,
            @ApiComment("用户名称") String name,
            @ApiComment("用户类型") UserType type) {
        return null; // TODO:  还未实现。
    }

    @Api2Doc(order = 20)
    @ApiComment("根据用户id,查询此用户的信息")
    @RequestMapping(name = "查询单个用户",
            value = "/user/{id}", method = RequestMethod.GET)
    public User getUser(@PathVariable("id") Long id) {
        return null; // TODO:  还未实现。
    }

    @Api2Doc(order = 30)
    @ApiComment("查询所有用户,按注册时间进行排序。")
    @RequestMapping(name = "查询用户列表",
            value = "/users", method = RequestMethod.GET)
    public List<User> getUsers() {
        return null; // TODO:  还未实现。
    }

    @Api2Doc(order = 40)
    @ApiComment("根据指定的组名称,查询该组中的所有用户信息。")
    @RequestMapping(name = "查询用户组",
            value = "/group/{group}", method = RequestMethod.GET)
    public UserGroup getGroup(@PathVariable("group") String group) {
        return null; // TODO:  还未实现。
    }
}

Отображаемый результат:

api2doc-3.png

@Api2Doc в классе также может сортировать меню первого уровня, правила те же, и я не буду это здесь демонстрировать.

Дополнительная пользовательская документация

Иногда кажется, что автоматически сгенерированная API-документация не идеальна, может быть, мы хотим добавить что-то еще, например: предысторию проекта, описание технической архитектуры и т. д. Как это сделать?

Api2Doc позволяет документировать вручную с синтаксисом md и интегрировать в автоматически создаваемую документацию API следующим образом:

Сначала определите атрибут id в @Api2Doc для класса, например, для следующего класса:

package com.terran4j.demo.api2doc;

import com.terran4j.commons.api2doc.annotations.Api2Doc;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Api2Doc(id = "demo3", name = "用户接口3")
@RestController
@RequestMapping(value = "/api2doc/demo3")
public class UserController3 {

    @Api2Doc(order = 10)
    @RequestMapping(name = "接口1", value = "/m1")
    public void m1() {
    }

    @Api2Doc(order = 20)
    @RequestMapping(name = "接口2", value = "/m2")
    public void m2() {
    }
}

@ API2DOC (ID = "DEMO3", Name = "User Interface 3") Указывает, что соответствующий ID меню первого уровня "User Interface 3" — Demo3.

Затем мы создаем каталог api2doc/demo3 в src/main/resources.Предыдущий api2doc является фиксированным, а последний demo3 указывает, что документы в этом каталоге добавляются в меню документов первого уровня с идентификатором demo3.

Затем мы записываем документ в формате md в каталог api2doc/demo3, как показано на следующем рисунке:

api2doc-4.png

Формат имени файла ${order}-${document name}.md, то есть число перед знаком - указывает порядок документа, который совпадает с атрибутом order в @Api2Doc, а за знаком - следует название документа, а также название вторичного меню.

Поэтому окончательный документ будет выглядеть так:

api2doc-5.png

Видите ли, рукописная дополнительная документация и автоматически сгенерированная документация по API, отсортированные по порядку, кажутся гармоничными.

Приветственная страница пользовательской документации

Каждое посещение страницы документацииhttp://localhost:8080/api2doc/home.html, содержание в середине представляет собой очень простое предложение:

欢迎使用 Api2Doc !

Это может показаться немного плохим, но ничего страшного, мы можем написать нашу собственную приветственную страницу.

Метод очень простой, в каталоге api2doc каталога src/main/resources создайте файл с именем welcome.md (это имя фиксированное), а затем напишите содержимое в синтаксисе md.

Настройте заголовок и значок документа

Заголовок и значок документа можно настроить в application.yml следующим образом:

api2doc:
  title: Api2Doc示例项目——接口文档
  icon: https://spring.io/img/homepage/icon-spring-framework.svg

Значок представляет собой полный URL-адрес или относительный URL-адрес этого сайта.

Эффект отображения после настройки:

api2doc-6.png

Закройте службу Api2Doc.

Вы настраиваете свойство api2doc.enabled в application.yml для включения или отключения службы Api2Doc, например:

# 本地环境
api2doc:
  title: Api2Doc示例项目——接口文档
  icon: https://spring.io/img/homepage/icon-spring-framework.svg

---
# 线上环境
spring:
  profiles: online

api2doc:
  enabled: false

api2doc.enabled имеет значение false, чтобы закрыть службу Api2Doc, не написано или true, чтобы включить.

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