如何为Spring Data REST自动生成的JPA端点添加OpenAPI文档?
给Spring Data REST自动生成的端点添加OpenAPI响应示例
针对Spring Data REST自动生成的GET /hosts、GET /hosts/{id}等无对应代码的端点,可通过以下两种方式添加包含HATEOAS自定义_links字段的响应示例:
方法一:使用OpenApiCustomiser自定义处理器
通过实现OpenApiCustomiser接口,直接修改spring-doc生成的OpenAPI模型,精准定位目标端点并注入自定义示例。这是最灵活的方案,完全可控HATEOAS结构细节。
示例代码
import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.media.Content; import io.swagger.v3.oas.models.media.MediaType; import io.swagger.v3.oas.models.responses.ApiResponse; import org.springdoc.core.customizers.OpenApiCustomiser; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SpringDocHostConfig { @Bean public OpenApiCustomiser hostEndpointExampleCustomiser() { return openApi -> { // 处理GET /hosts列表端点 PathItem hostsPath = openApi.getPaths().get("/hosts"); if (hostsPath != null && hostsPath.getGet() != null) { addHostListHateoasExample(hostsPath.getGet().getResponses().get("200")); } // 处理GET /hosts/{id}详情端点 PathItem hostDetailPath = openApi.getPaths().get("/hosts/{id}"); if (hostDetailPath != null && hostDetailPath.getGet() != null) { addHostDetailHateoasExample(hostDetailPath.getGet().getResponses().get("200")); } }; } private void addHostListHateoasExample(ApiResponse response) { if (response == null) return; Content content = response.getContent(); MediaType jsonType = content.get("application/json"); if (jsonType != null) { String listExample = """ { "_embedded": { "hosts": [ { "id": 1, "name": "prod-host-01", "ip": "172.16.0.10", "_links": { "self": {"href": "http://localhost:8080/hosts/1"}, "restart": {"href": "http://localhost:8080/hosts/1/restart"}, "metrics": {"href": "http://localhost:8080/hosts/1/metrics"} } } ] }, "_links": { "self": {"href": "http://localhost:8080/hosts"}, "create-host": {"href": "http://localhost:8080/hosts"} }, "page": { "size": 20, "totalElements": 1, "totalPages": 1, "number": 0 } } """; jsonType.setExample(listExample); } } private void addHostDetailHateoasExample(ApiResponse response) { if (response == null) return; Content content = response.getContent(); MediaType jsonType = content.get("application/json"); if (jsonType != null) { String detailExample = """ { "id": 1, "name": "prod-host-01", "ip": "172.16.0.10", "_links": { "self": {"href": "http://localhost:8080/hosts/1"}, "restart": {"href": "http://localhost:8080/hosts/1/restart"}, "back-to-list": {"href": "http://localhost:8080/hosts"} } } """; jsonType.setExample(detailExample); } } }
方法二:实体类上添加@Schema注解补充示例
如果你的Host实体继承了RepresentationModel(Spring HATEOAS基础类),可以直接在实体类上通过@Schema注解指定单实体的示例,作为自定义处理器的补充。
示例代码
import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.hateoas.RepresentationModel; @Schema(example = """ { "id": 1, "name": "prod-host-01", "ip": "172.16.0.10", "_links": { "self": {"href": "http://localhost:8080/hosts/1"}, "restart": {"href": "http://localhost:8080/hosts/1/restart"} } } """) public class Host extends RepresentationModel<Host> { private Long id; private String name; private String ip; // getter、setter方法 }
注意:此方法仅能定义单实体的示例,列表端点的_embedded和分页结构仍需通过自定义处理器补充。
内容的提问来源于stack exchange,提问作者Juliane
相关产品推荐
相关产品推荐

