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-time5. 使用命令行生成代码
准备好规范文件后,就可以使用命令行工具生成代码了。首先查看当前支持的语言列表:
java -jar swagger-codegen-cli.jar langs
输出结果会列出所有可用的语言生成器,例如 java、python、typescript-axios、go 等。
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<user> 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 实现代码的自动化生成,从而有效保证前后端接口的一致性,提升整体研发效率。
到此这篇关于swagger codegen 实战指南:从 openapi 规范到多语言代码生成的全过程的文章就介绍到这了,更多相关swagger codegen代码生成内容请搜索代码网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持代码网!
发表评论