如何用openapi-generator客户端请求spring-data-rest关联实体
用openapi-generator的typescript-axios模板对接Spring Data REST时,不需要额外写后端投影,也不用手动写axios请求读_links地址,下面两个方案都能直接复用生成的客户端能力:
方案1:直接调用自动生成的关联资源接口
Spring Data REST默认会给实体关联关系暴露嵌套资源接口,路径格式就是/persons/{personId}/addresses这类。只要你生成客户端时拉取的是服务端实时生成的OpenAPI元数据(比如Springdoc输出的/v3/api-docs),openapi-generator会自动把这类嵌套接口生成到关联实体对应的API工厂类里,不需要额外配置。
直接调用就行:
// 初始化API实例 const personApi = PersonEntityControllerApiFactory(configuration); const addressApi = AddressEntityControllerApiFactory(configuration); // 查询Person实体 const personResp = await personApi.getItemResourcePersonGet('5000'); const person = personResp.data; // 直接调用Address类下自动生成的关联查询方法,传入personId即可 const addressResp = await addressApi.getCollectionResourceAddressGet( undefined, // 分页参数,不需要就传undefined undefined, // 排序参数 person.id // 对应路径中/persons/{id}/addresses的id参数 ); // 拿返回的地址集合 const addresses = addressResp.data._embedded.addresses;
这个方案全程用生成的客户端方法,所有入参、返回值都有完整TS类型校验,也符合HATEOAS设计,后端不需要写任何额外代码。
方案2:扩展模板实现关联资源自动拉取
如果项目里关联关系很多,不想每次手动找对应关联实体的API方法,可以轻量修改typescript-axios的生成模板,给所有生成的模型加一个通用的关联查询方法,自动读取_links里的地址,复用客户端内置的axios实例发请求,不用单独初始化axios。
扩展完之后调用逻辑非常简洁:
const personResp = await personApi.getItemResourcePersonGet('5000'); const person = personResp.data; // 直接传入关联字段名,指定返回类型即可 const addresses = await person.fetchRelation<Address[]>('addresses');
这个方案既贴合HAL的动态链接设计,又复用了生成客户端已经配置好的baseURL、鉴权拦截器、错误处理逻辑,不会出现手动写axios带来的配置不一致问题。
踩坑提示:如果生成的API里找不到嵌套关联的方法,先检查Spring Data REST配置有没有关闭关联资源暴露,默认配置下所有关联资源都会自动注册接口、出现在OpenAPI文档里,只要生成客户端时OpenAPI地址配置正确就能扫到。
内容的提问来源于stack exchange,提问作者Matthias Simon

