- 开发工具
- 代码生成
- API设计
【免费下载链接】swagger-codegen
swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
导读
StoreApi是 swagger-codegen 为 Petstore 示例生成的 Jersey1 Java 客户端中负责“商店(Store)”业务域的 API 类,封装了订单下单、订单查询、订单删除与库存查询四个接口。本文以 samples/client/petstore/java/jersey1/docs/StoreApi.md 为骨架,结合该示例工程中生成的源码、模型与测试用例,逐接口讲解调用方式、参数约束、认证配置与底层实现原理,帮助你掌握如何阅读和使用这类自动生成的客户端 API 文档,并理解其背后的代码生成逻辑。
一、StoreApi 概览:接口清单与基线地址
StoreApi 中所有接口的 URIs 都相对http://petstore.swagger.io:80/v2这一基线地址(base path),四个方法及其 HTTP 映射如下:
| Method | HTTP request | Description |
|---|---|---|
deleteOrder(orderId) | DELETE/store/order/{order_id} | Delete purchase order by ID |
getInventory() | GET/store/inventory | Returns pet inventories by status |
getOrderById(orderId) | GET/store/order/{order_id} | Find purchase order by ID |
placeOrder(body) | POST/store/order | Place an order for a pet |
从工程结构看,这四个方法对应生成的 Java 类 StoreApi.java,其构造函数支持两种方式:
public StoreApi() { this(Configuration.getDefaultApiClient()); } public StoreApi(ApiClient apiClient) { this.apiClient = apiClient; }- 无参构造使用
Configuration.getDefaultApiClient()返回的全局默认客户端; - 带参构造允许传入自定义的
ApiClient,从而覆盖基线地址、认证信息、超时等配置; - 类中还提供了
getApiClient()/setApiClient()用于运行期替换客户端实例。
对应地,README(samples/client/petstore/java/jersey1/README.md)也给出建议:多线程环境下推荐每个线程单独创建ApiClient实例,以避免潜在的状态共享问题。
二、deleteOrder:删除指定 ID 的订单
接口说明
deleteOrder用于按订单 ID 删除一笔订单。文档特别提示:只有小于 1000 的整数 ID 才能得到正常响应,大于 1000 或非整数 ID 会触发 API 错误,这是 Petstore 测试服务端的约定。
调用示例
// Import classes: //import io.swagger.client.ApiException; //import io.swagger.client.api.StoreApi; StoreApi apiInstance = new StoreApi(); String orderId = "orderId_example"; // String | ID of the order that needs to be deleted try { apiInstance.deleteOrder(orderId); } catch (ApiException e) { System.err.println("Exception when calling StoreApi#deleteOrder"); e.printStackTrace(); }参数说明
| Name | Type | Description |
|---|---|---|
| orderId | String | ID of the order that needs to be deleted |
- 必填参数,传
null会抛出ApiException(400, "Missing the required parameter 'orderId' when calling deleteOrder"); - 注意路径中的占位符是
{order_id},但方法参数名是orderId,二者在代码生成阶段完成了映射。
返回与响应
- Return type:
null(空响应体)。当服务端返回204 NO_CONTENT时,invokeAPI直接返回null; - Authorization:无需认证;
- HTTP 请求头:Content-Type 未定义;Accept 为
application/xml, application/json。
源码实现要点
在 StoreApi.java 中,deleteOrder通过三步完成请求构造:
- 校验必填参数:
orderId == null时抛出 400 异常; - 路径替换:
"/store/order/{order_id}".replaceAll("\\{order_id\\}", apiClient.escapeString(orderId.toString())),其中escapeString负责对路径片段做 URL 编码; - 调用
apiClient.invokeAPI(path, "DELETE", ..., null),最后一个参数为null,表示不需要返回类型,对应文档中的“空响应体”。
三、getInventory:按状态返回宠物库存
接口说明
getInventory无需任何参数,返回状态码到数量的映射,即Map<String, Integer>。例如{"available": 5, "pending": 2}。
调用示例(含 API Key 认证配置)
// Import classes: //import io.swagger.client.ApiClient; //import io.swagger.client.ApiException; //import io.swagger.client.Configuration; //import io.swagger.client.auth.*; //import io.swagger.client.api.StoreApi; ApiClient defaultClient = Configuration.getDefaultApiClient(); // Configure API key authorization: api_key ApiKeyAuth api_key = (ApiKeyAuth) defaultClient.getAuthentication("api_key"); api_key.setApiKey("YOUR API KEY"); // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null) //api_key.setApiKeyPrefix("Token"); StoreApi apiInstance = new StoreApi(); try { Map<String, Integer> result = apiInstance.getInventory(); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling StoreApi#getInventory"); e.printStackTrace(); }参数与返回
- Parameters:无;
- Return type:
Map<String, Integer>; - Authorization:需要
api_key(见 README 认证章节:API key 类型,参数名api_key,位置为 HTTP header); - HTTP 请求头:Content-Type 未定义;Accept 为
application/json。
源码实现要点
从源码看,getInventory是唯一带认证的 Store 接口,其关键差异点有两处:
- 认证名数组:
String[] localVarAuthNames = new String[] { "api_key" };,其余三个 Store 接口均为空数组; - 泛型返回:通过
new GenericType<Map<String, Integer>>() {}声明返回类型,交给 Jersey 反序列化 JSON 响应。
ApiKeyAuth 的底层机制
认证的具体注入逻辑在 ApiKeyAuth.java:
@Override public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) { if (apiKey == null) { return; } String value; if (apiKeyPrefix != null) { value = apiKeyPrefix + " " + apiKey; } else { value = apiKey; } if ("query".equals(location)) { queryParams.add(new Pair(paramName, value)); } else if ("header".equals(location)) { headerParams.put(paramName, value); } }- 未设置 API Key 时静默跳过,不注入任何参数;
- 设置了
apiKeyPrefix(如"Token")时,实际发送值为prefix + " " + apiKey;未设置时直接发送 apiKey 本身; - 由于 Petstore 的
api_key位于 header,最终会写入请求头api_key: <value>。
该认证参数在invokeAPI中被updateParamsForAuth遍历应用(见 ApiClient.java),随后进入实际 HTTP 调用。
四、getOrderById:按 ID 查询订单
接口说明
getOrderById按订单 ID 查询订单详情。文档提示:ID 取 ≤ 5 或 > 10 的整数才能得到正常响应,其他值会触发异常,同样是 Petstore 测试服务端人为设定的行为。
调用示例
// Import classes: //import io.swagger.client.ApiException; //import io.swagger.client.api.StoreApi; StoreApi apiInstance = new StoreApi(); Long orderId = 789L; // Long | ID of pet that needs to be fetched try { Order result = apiInstance.getOrderById(orderId); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling StoreApi#getOrderById"); e.printStackTrace(); }参数说明
| Name | Type | Description |
|---|---|---|
| orderId | Long | ID of pet that needs to be fetched |
- 与
deleteOrder不同,这里的orderId是Long类型; - 必填参数,传
null同样抛出 400ApiException。
返回与响应
- Return type:Order,即生成的
Order模型; - Authorization:无需认证;
- HTTP 请求头:Content-Type 未定义;Accept 为
application/xml, application/json(服务端可能返回 XML 或 JSON,由ApiClient.selectHeaderAccept依据优先级协商)。
源码实现要点
getOrderById在 StoreApi.java 中的实现与deleteOrder高度相似,唯一区别是:
- 使用
GenericType<Order>声明返回类型; invokeAPI返回Order对象,由 Jersey 将响应体反序列化为模型实例。
Order 模型字段
依据 Order.md,Order模型包含以下可选字段:
| Name | Type | Description |
|---|---|---|
| id | Long | |
| petId | Long | |
| quantity | Integer | |
| shipDate | OffsetDateTime | |
| status | StatusEnum | Order Status |
| complete | Boolean |
其中StatusEnum的取值固定为三个枚举:
| Name | Value |
|---|---|
| PLACED | "placed" |
| APPROVED | "approved" |
| DELIVERED | "delivered" |
五、placeOrder:为宠物下单
接口说明
placeOrder以Order对象为请求体,创建一笔订单,返回服务端生成(含 id)的完整订单。
调用示例
// Import classes: //import io.swagger.client.ApiException; //import io.swagger.client.api.StoreApi; StoreApi apiInstance = new StoreApi(); Order body = new Order(); // Order | order placed for purchasing the pet try { Order result = apiInstance.placeOrder(body); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling StoreApi#placeOrder"); e.printStackTrace(); }参数说明
| Name | Type | Description |
|---|---|---|
| body | Order | order placed for purchasing the pet |
- 必填参数,传
null抛出 400ApiException; - 请求体对象会被序列化并作为
POST请求的 body 发送。
返回与响应
- Return type:Order;
- Authorization:无需认证;
- HTTP 请求头:Content-Type 未定义;Accept 为
application/xml, application/json。
源码实现要点
在 StoreApi.java 中,placeOrder与其余三个方法的差异在于:
- 请求体:
Object localVarPostBody = body;,即把Order直接作为 body; - 路径:
/store/order(无路径参数,因此不需要replaceAll替换); - 方法:
POST,invokeAPI中builder.type(contentType).post(...),序列化逻辑见 ApiClient.java 的serialize方法——当 Content-Type 为 JSON 时交给 Jersey/JAXB 处理,若是表单或 multipart 则走对应的参数编码路径。
六、测试用例:接口之间的真实调用关系
StoreApiTest.java 是这四个接口的最佳实践演示,它直接印证了接口间的协作流程:
测试初始化
@Before public void setup() { api = new StoreApi(); // setup authentication ApiKeyAuth apiKeyAuth = (ApiKeyAuth) api.getApiClient().getAuthentication("api_key"); apiKeyAuth.setApiKey("special-key"); // set custom date format that is used by the petstore server api.getApiClient().setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")); }要点:测试中通过api.getApiClient().getAuthentication("api_key")拿到认证器并设置测试 Key"special-key",并为 petstore 服务端定制日期格式(yyyy-MM-dd'T'HH:mm:ss.SSSZ),否则shipDate的序列化可能与服务端不兼容。
库存测试
@Test public void testGetInventory() throws Exception { Map<String, Integer> inventory = api.getInventory(); assertTrue(inventory.keySet().size() > 0); }验证getInventory返回非空映射,即鉴权成功后能拿到库存数据。
下单与回查测试
@Test public void testPlaceOrder() throws Exception { Order order = createOrder(); api.placeOrder(order); Order fetched = api.getOrderById(order.getId()); assertEquals(order.getId(), fetched.getId()); assertEquals(order.getPetId(), fetched.getPetId()); assertEquals(order.getQuantity(), fetched.getQuantity()); assertTrue(order.getShipDate().isEqual(fetched.getShipDate())); }完整的“下单 → 按 ID 回查 → 字段一致性校验”链路,说明placeOrder与getOrderById应当搭配使用。
删除闭环测试
@Test public void testDeleteOrder() throws Exception { Order order = createOrder(); api.placeOrder(order); Order fetched = api.getOrderById(order.getId()); assertEquals(fetched.getId(), order.getId()); api.deleteOrder(String.valueOf(order.getId())); try { api.getOrderById(order.getId()); // fail("expected an error"); } catch (ApiException e) { // ok } }演示完整生命周期:下单 → 确认存在 → 删除 → 再次查询应抛出ApiException,正好呼应文档中“大于 1000 或非整数 ID 会产生 API 错误”的行为说明。
构造测试订单
private Order createOrder() { Order order = new Order(); order.setPetId(200L); order.setQuantity(13); order.setShipDate(OffsetDateTime.now().withNano(123000000)); order.setStatus(Order.StatusEnum.PLACED); order.setComplete(true); // 通过反射设置 id(petstore 服务端存在小数位 bug,需固定 3 位小数) ... return order; }注意源码注释:Ensure 3 fractional digits because of a bug in the petstore server——即 petstore 测试服务端要求shipDate保留 3 位小数,因此测试用withNano(123000000)固定纳秒值。
七、如何阅读这类自动生成的 API 文档
StoreApi.md是 swagger-codegen 依据 OpenAPI/Swagger 定义自动生成的接口文档,其结构对仓库中其他 API 文档(如 PetApi.md、UserApi.md)完全一致,可按以下套路快速上手:
- 看头部表格:确定方法签名、HTTP 方法与路径模板,路径中的
{param}即方法参数; - 看 Parameters 表:确认参数类型(String / Long / 模型对象)与是否必填,类型决定了调用时的强类型约束;
- 看 Return type:
null表示无返回体(如 deleteOrder),Order、Map<String, Integer>等表示返回模型的类型; - 看 Authorization:无认证的接口可直接调用;带认证的接口(如
getInventory的api_key)需先通过Configuration.getDefaultApiClient().getAuthentication(...)配置凭证; - 看 HTTP 请求头:了解服务端支持的响应格式(Accept)与请求格式(Content-Type),涉及 XML/JSON 协商或表单提交时尤其重要;
- 对照源码:文档中的每个接口都能在
src/main/java/io/swagger/client/api/下找到同名实现类与对应方法,参数校验、路径替换、认证数组、泛型返回类型均可逐行核对。
八、工程集成与运行环境
该示例客户端是一个完整的 Maven 工程(pom.xml),坐标io.swagger:swagger-java-client:1.0.0,基于 Jersey 1.x(com.sun.jersey)实现。集成方式:
- Maven:在依赖中加入
io.swagger:swagger-java-client:1.0.0(compile scope); - Gradle:
compile "io.swagger:swagger-java-client:1.0.0"; - 本地安装:执行
mvn install安装到本地仓库,或mvn package后手动引入target/swagger-java-client-1.0.0.jar与target/lib/*.jar; - 测试运行:
mvn test即可运行包括StoreApiTest在内的全部单元测试(surefire 已配置-Xms512m -Xmx1500m与 per-test fork 模式)。
需要说明:本文涉及的 Petstore 示例面向在线测试服务http://petstore.swagger.io/v2(StoreApi.md 基线为http://petstore.swagger.io:80/v2),如自建服务端,可通过自定义ApiClient的basePath覆盖基线地址。
总结
StoreApi 覆盖了业务域中最典型的四类接口形态:无参查询(getInventory)、路径参数查询(getOrderById)、路径参数删除(deleteOrder)与请求体写入(placeOrder),并完整演示了 API Key 认证的配置方式。通过将自动生成的 StoreApi.md 与 StoreApi.java、StoreApiTest.java 对照阅读,你可以快速掌握 swagger-codegen 生成客户端的文档阅读方法、调用范式与底层请求管线,并将其推广到仓库中任意语言、任意业务域的生成代码上。
- 开发工具
- 代码生成
- API设计
【免费下载链接】swagger-codegen
swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
相关推荐
Swagger Codegen Bash 客户端 StoreApi 实战指南:用 petstore-cli 调用 Petstore 订单与库存接口
Swagger Codegen Bash 客户端 StoreApi 实战指南:用 petstore cli 调用 Petstore 订单与库存接口 导读 本指南
开发工具代码生成API设计swagger-codegen 生成的 C 客户端 StoreApi 使用指南:Petstore 订单与库存接口全解析
swagger codegen 生成的 C 客户端 StoreApi 使用指南:Petstore 订单与库存接口全解析 导读 本篇技术指南聚焦 swagger
开发工具代码生成API设计Swagger Codegen 生成的 Dart Flutter Petstore StoreApi 使用指南:订单与库存接口实战
Swagger Codegen 生成的 Dart Flutter Petstore StoreApi 使用指南:订单与库存接口实战 导读 StoreApi 是
开发工具代码生成API设计
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考