三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Swagger Codegen 实战指南:从 OpenAPI 规范到多语言代码生成

Swagger Codegen 实战指南:从 OpenAPI 规范到多语言代码生成

1. 引言

在前后端分离的开发模式下,接口文档与代码实现的一致性一直是团队协作的痛点。Swagger Codegen 作为一款强大的代码生成工具,能够基于 OpenAPI(原 Swagger)规范文件自动生成客户端 SDK、服务端骨架代码以及 API 文档,帮助开发者大幅减少重复劳动,提升开发效率。

本文将围绕 Swagger Codegen 的核心概念、安装方式、命令行用法、Maven 插件集成以及常见自定义配置展开,并通过丰富的代码实例演示如何从一份 OpenAPI 规范生成 Java、Python、TypeScript 等多种语言的代码。

2. Swagger Codegen 简介

Swagger Codegen 是 Swagger 生态中的核心工具之一,它读取 OpenAPI 规范文件(JSON 或 YAML 格式),并根据内置的模板引擎生成对应语言的代码。其核心价值在于:

  • 多语言支持:支持 Java、Python、TypeScript、Go、C#、Ruby 等数十种语言和框架。
  • 一致性保障:接口定义与代码实现始终以规范文件为准,避免文档与代码脱节。
  • 可定制化:通过模板和配置项,可以调整生成代码的风格与结构。

需要注意的是,Swagger Codegen 目前分为两个主要版本:Swagger Codegen 2.x(基于 Swagger 2.0 规范)和Swagger Codegen 3.x(基于 OpenAPI 3.0 规范)。此外,社区还维护了功能更丰富的OpenAPI Generator分支。本文以 Swagger Codegen 3.x 为主进行讲解。

3. 环境准备与安装

Swagger Codegen 提供了多种安装方式,包括直接下载 JAR 包、使用 Homebrew、Docker 以及 Maven 插件等。下面分别介绍。

3.1 下载 JAR 包

最简单的方式是直接从 Maven 中央仓库下载可执行的 JAR 包:

# 下载 Swagger Codegen 3.x 最新版本 wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.46/swagger-codegen-cli-3.0.46.jar -O swagger-codegen-cli.jar 验证安装 java -jar swagger-codegen-cli.jar version

3.2 使用 Homebrew(macOS)

brew install swagger-codegen 查看版本 swagger-codegen version

3.3 使用 Docker

# 拉取镜像 docker pull swaggerapi/swagger-codegen-cli 查看帮助 docker run --rm swaggerapi/swagger-codegen-cli help

3.4 使用 Maven 插件

对于 Java 项目,推荐在 Maven 构建流程中集成 swagger-codegen-maven-plugin,实现代码生成的自动化:

<plugin> <groupId>io.swagger.codegen.v3</groupId> <artifactId>swagger-codegen-maven-plugin</artifactId> <version>3.0.46</version> <executions> <execution> <goals> <goal>generate</goal> </goals> <configuration> <inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec> <language>java</language> <output>${project.build.directory}/generated-sources</output> </configuration> </execution> </executions> </plugin>

4. 准备 OpenAPI 规范文件

在生成代码之前,我们需要先准备一份 OpenAPI 规范文件。下面以一份简单的用户管理 API 为例,创建api.yaml文件:

openapi: 3.0.0 info: title: User Management API version: 1.0.0 description: 用户管理接口示例 paths: /users: get: summary: 获取用户列表 operationId: getUsers parameters: - name: page in: query required: false schema: type: integer default: 1 - name: size in: query required: false schema: type: integer default: 20 responses: '200': description: 成功返回用户列表 content: application/json: schema: type: array items: $ref: '#/components/schemas/User' post: summary: 创建新用户 operationId: createUser requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/User' responses: '201': description: 用户创建成功 content: application/json: schema: $ref: '#/components/schemas/User' /users/{id}: get: summary: 根据 ID 获取用户 operationId: getUserById parameters: - name: id in: path required: true schema: type: integer responses: '200': description: 成功返回用户信息 content: application/json: schema: $ref: '#/components/schemas/User' '404': description: 用户不存在 components: schemas: User: type: object required: - id - name properties: id: type: integer format: int64 name: type: string email: type: string format: email createdAt: type: string format: date-time

5. 使用命令行生成代码

准备好规范文件后,就可以使用命令行工具生成代码了。首先查看当前支持的语言列表:

java -jar swagger-codegen-cli.jar langs

输出结果会列出所有可用的语言生成器,例如javapythontypescript-axiosgo等。

5.1 生成 Java 客户端代码

java -jar swagger-codegen-cli.jar generate \ -i api.yaml \ -l java \ -o ./generated/java-client \ --group-id com.example \ --artifact-id user-client \ --artifact-version 1.0.0 \ --library okhttp-gson

执行完成后,在./generated/java-client目录下会生成完整的 Java 客户端工程,包含pom.xml、API 接口类、模型类以及调用示例。

5.2 生成 Python 客户端代码

java -jar swagger-codegen-cli.jar generate \ -i api.yaml \ -l python \ -o ./generated/python-client \ --package-name user_client

5.3 生成 TypeScript(Axios)客户端代码

java -jar swagger-codegen-cli.jar generate \ -i api.yaml \ -l typescript-axios \ -o ./generated/ts-client

5.4 生成 Spring Boot 服务端代码

java -jar swagger-codegen-cli.jar generate \ -i api.yaml \ -l spring \ -o ./generated/spring-server \ --group-id com.example \ --artifact-id user-server \ --library spring-boot \ --additional-properties interfaceOnly=true

其中interfaceOnly=true表示只生成接口定义和模型类,不生成具体的实现逻辑,方便开发者在此基础上自行编写业务代码。

6. 生成代码的结构解析

以 Java 客户端为例,生成的代码结构如下:

generated/java-client/ ├── pom.xml ├── README.md ├── docs/ │ └── UsersApi.md ├── src/ │ └── main/ │ ├── java/com/example/client/ │ │ ├── api/ │ │ │ └── UsersApi.java │ │ ├── model/ │ │ │ └── User.java │ │ └── ... │ └── resources/ │ └── api.yaml └── .swagger-codegen/ └── VERSION

其中UsersApi.java是核心的 API 调用类,User.java是对应的数据模型。下面看一下生成的User.java模型类:

package com.example.client.model; import java.util.Objects; import com.fasterxml.jackson.annotation.JsonProperty; import java.time.OffsetDateTime; public class User { @JsonProperty("id") private Long id = null; @JsonProperty("name") private String name = null; @JsonProperty("email") private String email = null; @JsonProperty("createdAt") private OffsetDateTime createdAt = null; public User id(Long id) { this.id = id; return this; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public User name(String name) { this.name = name; return this; } public String getName() { return name; } public void setName(String name) { this.name = name; } public User email(String email) { this.email = email; return this; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public User createdAt(OffsetDateTime createdAt) { this.createdAt = createdAt; return this; } public OffsetDateTime getCreatedAt() { return createdAt; } public void setCreatedAt(OffsetDateTime createdAt) { this.createdAt = createdAt; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } User user = (User) o; return Objects.equals(this.id, user.id) && Objects.equals(this.name, user.name) && Objects.equals(this.email, user.email) && Objects.equals(this.createdAt, user.createdAt); } @Override public int hashCode() { return Objects.hash(id, name, email, createdAt); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class User {\n"); sb.append(" id: ").append(toIndentedString(id)).append("\n"); sb.append(" name: ").append(toIndentedString(name)).append("\n"); sb.append(" email: ").append(toIndentedString(email)).append("\n"); sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); sb.append("}"); return sb.toString(); } private String toIndentedString(Object o) { if (o == null) { return "null"; } return o.toString().replace("\n", "\n "); } }

7. 使用生成的 Java 客户端调用 API

生成代码后,我们可以直接在业务代码中调用生成的客户端。下面是一个简单的调用示例:

import com.example.client.ApiClient; import com.example.client.api.UsersApi; import com.example.client.model.User; import java.util.List; public class UserClientDemo { public static void main(String[] args) { // 初始化 API 客户端,设置服务端地址 ApiClient apiClient = new ApiClient(); apiClient.setBasePath("http://localhost:8080"); // 创建 API 实例 UsersApi usersApi = new UsersApi(apiClient); try { // 调用获取用户列表接口 List&amp;lt;User&amp;gt; users = usersApi.getUsers(1, 20); System.out.println("获取到 " + users.size() + " 个用户"); for (User user : users) { System.out.println("用户 ID: " + user.getId() + ", 姓名: " + user.getName()); } // 调用创建用户接口 User newUser = new User(); newUser.setName("张三"); newUser.setEmail("zhangsan@example.com"); User created = usersApi.createUser(newUser); System.out.println("创建成功,新用户 ID: " + created.getId()); // 调用根据 ID 查询用户接口 User fetched = usersApi.getUserById(created.getId()); System.out.println("查询到用户: " + fetched.getName()); } catch (Exception e) { e.printStackTrace(); } } }

8. 使用 Maven 插件集成到构建流程

在实际项目中,我们通常希望代码生成与构建流程集成,避免手动执行命令行。下面演示如何在 Maven 项目中配置 swagger-codegen-maven-plugin。

8.1 配置插件

<build> <plugins> <plugin> <groupId>io.swagger.codegen.v3</groupId> <artifactId>swagger-codegen-maven-plugin</artifactId> <version>3.0.46</version> <executions> <execution> <id>generate-client</id> <goals> <goal>generate</goal> </goals> <configuration> <inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec> <language>java</language> <library>okhttp-gson</library> <output>${project.build.directory}/generated-sources/swagger</output> <configOptions> <groupId>com.example</groupId> <artifactId>user-client</artifactId> <artifactVersion>1.0.0</artifactVersion> <dateLibrary>java8</dateLibrary> </configOptions> </configuration> </execution> </executions> </plugin> </plugins> </build>

8.2 添加 build-helper-maven-plugin 将生成代码加入编译路径

<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>${project.build.directory}/generated-sources/swagger/src/main/java</source> </sources> </configuration> </execution> </executions> </plugin>

8.3 执行构建

mvn clean compile

执行后,Maven 会先读取api.yaml生成客户端代码,再将其编译进项目,开发者可以直接在业务代码中引用生成的类。

9. 自定义代码生成模板

Swagger Codegen 允许通过自定义模板来调整生成代码的风格。首先将默认模板导出到本地:

java -jar swagger-codegen-cli.jar meta \ -o ./my-template \ -n myTemplate \ -p com.example.codegen

该命令会生成一个模板工程,其中包含src/main/resources目录下的模板文件。我们可以修改model.mustache等模板文件,然后通过-t参数指定自定义模板目录:

java -jar swagger-codegen-cli.jar generate \ -i api.yaml \ -l java \ -o ./generated/custom-client \ -t ./my-template/src/main/resources

10. 常见问题与注意事项

  • 版本兼容性:Swagger Codegen 2.x 与 3.x 的配置参数存在差异,使用前务必确认规范文件版本与工具版本匹配。
  • operationId 唯一性:OpenAPI 规范中的operationId必须唯一,否则生成的代码会出现方法名冲突。
  • 枚举类型处理:规范中的枚举值在生成代码时会映射为对应语言的枚举类型,注意保持枚举值命名规范。
  • 日期时间格式:建议在规范中明确format: date-time,并通过dateLibrary配置项指定目标语言的日期库。
  • 生成代码的维护:生成代码通常不应手动修改,如需定制应通过修改模板或配置项实现,避免重新生成时丢失改动。

11. 总结

Swagger Codegen 是连接 API 规范与多语言代码实现的重要桥梁。通过本文的实战演示,我们掌握了从 OpenAPI 规范文件生成 Java、Python、TypeScript 客户端以及 Spring Boot 服务端代码的完整流程,并了解了如何通过 Maven 插件将代码生成集成到自动化构建中。

在实际项目中,建议团队将 OpenAPI 规范文件作为接口契约的唯一事实来源,配合 Swagger Codegen 或 OpenAPI Generator 实现代码的自动化生成,从而有效保证前后端接口的一致性,提升整体研发效率。

← 返回列表