如果您正在使用 Spring Boot 开发 RESTful API,您希望让其他开发人员尽可能容易地理解和使用您的 API。文档是必不可少的,因为它为将来的更新提供了参考,并帮助其他开发人员与您的 API 集成。很长一段时间以来,记录 REST API 的方法是使用 Swagger,这是一个开源软件框架,使开发人员能够设计、构建、记录和使用 RESTful Web 服务。2018 年,为了解决与 Swagger 等传统 API 文档工具相关的代码侵入性和依赖性问题,我们开发并将其开源给社区。smart-doc

在本文中,我们将探讨如何使用 Spring Boot REST API 生成文档。Smart-doc

什么是 Smart-doc?

    Smart-doc是 Java 项目的接口文档生成工具。它主要从 Java 源代码中分析和提取注释以生成 API 文档。Smart-doc 扫描代码中的标准 Java 注释,无需像 Swagger 中使用的注释那样进行专门的注释,从而保持代码的简单性和非侵入性。它支持多种格式的文档输出,包括 、 、 、 等。这种灵活性允许开发人员根据自己的需要选择适当的文档格式。此外,Smart-doc 可以扫描代码以生成 JMeter 性能测试脚本。MarkdownHTML5Postman CollectionOpenAPI 3.0

更多功能请参考官方文档。

使用 Smart-doc 记录 API 的步骤

第 1 步:Maven 项目

  • 使用最新版本的 Spring Boot 创建 Maven 项目
  • 将 Web 依赖项添加到项目

使用 Smart-doc 记录 Spring REST API_User

第 2 步:将 Smart-doc 添加到项目中

  • 添加到项目的smart-doc-maven-pluginpom.xml

XML格式

<plugin>
     <groupId>com.ly.smart-doc</groupId>
     <artifactId>smart-doc-maven-plugin</artifactId>
     <version>[latest version]</version>
     <configuration>
         <configFile>./src/main/resources/smart-doc.json</configFile>
         <projectName>${project.description}</projectName>
     </configuration>
</plugin>
  • 在项目启动类所在的模块的 resources 目录中创建文件。smart-doc.json

JSON的

{
     "outPath": "/path/to/userdir"
}

步骤 3:创建 Rest 控制器

现在,让我们创建一个控制器类来处理 HTTP 请求并返回响应。

  • 创建一个控制器类,该类将作为 JSON 响应发送。

爪哇岛

public class User {

    /**
     * user id
     * 
     */
    private long id;

    /**
     * first name
     */
    private String firstName;

    /**
     * last name
     */
    private String lastName;

    /**
     * email address
     */
    private String email;


    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
  • 现在创建一个服务类

爪哇岛

@Repository
public class UserRepository {

    private static final Map<Long, User> users = new ConcurrentHashMap<>();

    static {
        User user = new User();
        user.setId(1);
        user.setEmail("123@gmail.com");
        user.setFirstName("Tom");
        user.setLastName("King");
        users.put(1L,user);
    }

    public Optional<User> findById(long id) {
        return Optional.ofNullable(users.get(id));
    }

    public void add(User book) {
        users.put(book.getId(), book);
    }

    public List<User> getUsers() {
        return users.values().stream().collect(Collectors.toList());
    }

    public boolean delete(User user) {
        return users.remove(user.getId(),user);
    }
}
  • 创建 RestController 类。

爪哇岛

/**
 * The type User controller.
 *
 * @author yu 2020/12/27.
 */
@RestController
@RequestMapping("/api/v1")
public class UserController {

    @Resource
    private UserRepository userRepository;

    /**
     * Create user.
     *
     * @param user the user
     * @return the user
     */
    @PostMapping("/users")
    public ResponseResult<User> createUser(@Valid @RequestBody User user) {
        userRepository.add(user);
        return ResponseResult.ok(user);
    }

    /**
     * Get all users list.
     *
     * @return the list
     */
    @GetMapping("/users")
    public ResponseResult<List<User>> getAllUsers() {
        return ResponseResult.ok().setResultData(userRepository.getUsers());
    }

    /**
     * Gets users by id.
     *
     * @param userId the user id|1
     * @return the users by id
     */
    @GetMapping("/users/{id}")
    public ResponseResult<User> getUsersById(@PathVariable(value = "id") Long userId) {
        User user = userRepository.findById(userId).
                orElseThrow(() -> new ResourceNotFoundException("User not found on :: " + userId));
        return ResponseResult.ok().setResultData(user);
    }


    /**
     * Update user response entity.
     *
     * @param userId      the user id|1
     * @param userDetails the user details
     * @return the response entity
     */
    @PutMapping("/users/{id}")
    public ResponseResult<User> updateUser(@PathVariable(value = "id") Long userId, @Valid @RequestBody User userDetails) {
        User user = userRepository.findById(userId).
                orElseThrow(() -> new ResourceNotFoundException("User not found on :: " + userId));
        user.setEmail(userDetails.getEmail());
        user.setLastName(userDetails.getLastName());
        user.setFirstName(userDetails.getFirstName());
        userRepository.add(user);
        return ResponseResult.ok().setResultData(user);
    }

    /**
     * Delete user.
     *
     * @param userId the user id|1
     * @return the map
     */
    @DeleteMapping("/user/{id}")
    public ResponseResult<Boolean> deleteUser(@PathVariable(value = "id") Long userId) {
        User user = userRepository.findById(userId).
                orElseThrow(() -> new ResourceNotFoundException("User not found on :: " + userId));
        return ResponseResult.ok().setResultData(userRepository.delete(user));
    }
}

第 4 步:生成文档

您可以使用 Smart-doc 插件生成所需的文档,例如 、 等。IntelliJ IDEAOpenAPIMarkdown

使用 Smart-doc 记录 Spring REST API_spring_02

当然,您也可以使用 Maven 命令生成:

mvn smart-doc:html
//  Generate document output to Markdown
mvn smart-doc:markdown
// Generate document output to Adoc
mvn smart-doc:adoc
// Generate Postman.
mvn smart-doc:postman
// Generate OpenAPI 3.0+
mvn smart-doc:openapi

第 4 步:导入到 Postman

这里我们用 生成一个 ,然后将其导入以查看效果。Smart-docPostman.jsonPostman

使用 Smart-doc 记录 Spring REST API_java_03

    由于 smart-doc 支持生成多种格式的文档,您可以选择生成然后使用或导入到一些专业的 API 文档系统中进行显示。OpenAPISwagger UI

结论

    从前面的例子可以看出,Smart-doc 通过扫描代码中的标准 Java 注释来生成文档,不需要像 Swagger 这样的专门注解,从而保持了代码的简单性和非侵入性,也不影响服务 Jar 包的大小。它支持多种格式的文档输出,包括、、、、等。这种灵活性允许开发人员根据自己的需要选择适当的文档格式进行输出。smart-doc 提供的 or 插件还方便用户将文档生成集成到 .MarkdownHTML5Postman CollectionOpenAPI 3.0MavenGradleDevops pipelines

    目前,Swagger 也有其优势,例如更强大的 UI 功能,以及对 Springboot Webflux 的更好支持。