CoApi - 同时支持响应式编程和同步编程模型的 HTTP 客户端
更新内容
特性:新增 BearerTokenFilter 过滤器,以支持自动认证、注入 BearerToken 到请求头。
特性:新增 HeaderSetFilter 过滤器,以支持自定义请求头。
特性:新增 ExpirableTokenProvider 过滤器,以支持 Token 过期后的自动重新刷新。
特性:支持在 CoApiProperties 自定义 baseUrl。
特性:仅当请求头中不存在 KEY 时才设置请求头值。
特性:支持根据定义判断是否添加负载均衡拦截器
特性: WebClientFactoryBean 支持自动注入负载均衡过滤器
依赖:升级 org.springframework.boot:spring-boot-dependencies 版本 v3.3.1
依赖:升级 org.springframework.cloud:spring-cloud-dependencies 版本 v2023.0.2
依赖:升级 org.jetbrains.dokka 版本 v1.9.20
依赖:升级 io.mockk:mockk 版本 v1.13.11
依赖:升级 kotlin 版本 v2.0.0
依赖:升级 detekt 版本 v1.23.6
依赖:升级 codecov/codecov-action 版本 v4
依赖:升级 gradle 版本 v8.8
依赖:升级 enricomi/publish-unit-test-result-action action 版本 v2.16.1
简介
在 Spring Framework 6 中,引入了全新的 HTTP 客户端 - Spring6 HTTP Interface。 该接口允许开发者通过使用 @HttpExchange 注解将 HTTP 服务定义为 Java 接口。
然而,当前版本尚未提供自动配置的支持,需要开发者自己实现配置。
虽然 Spring 生态中已经存在 Spring Cloud OpenFeign ,但它并未支持响应式编程模型。 为解决这个问题,Spring Cloud OpenFeign 推荐了替代方案 feign-reactive。然而,这个替代方案目前已处于不积极维护状态,并且不支持 Spring Boot 3.2.x。
CoApi 应运而生,它提供了类似于 Spring Cloud OpenFeign 的零样板代码自动配置的支持,同时支持响应式编程模型和同步编程模型。开发者只需定义接口,即可轻松使用。
安装
使用 Gradle(Kotlin) 安装依赖
implementation("me.ahoo.coapi:coapi-spring-boot-starter")
使用 Gradle(Groovy) 安装依赖
implementation 'me.ahoo.coapi:coapi-spring-boot-starter'
使用 Maven 安装依赖
<dependency>
<groupId>me.ahoo.coapi</groupId>
<artifactId>coapi-spring-boot-starter</artifactId>
<version>${coapi.version}</version>
</dependency>
使用
定义 CoApi - 第三方接口
baseUrl : 定义请求的基础地址,该参数可以从配置文件中获取,如:baseUrl = "${github.url}",github.url 是配置文件中的配置项 }
@CoApi(baseUrl = "${github.url}")
public interface GitHubApiClient {
@GetExchange("repos/{owner}/{repo}/issues")
Flux<Issue> getIssue(@PathVariable String owner, @PathVariable String repo);
}
配置文件:
github:
url: https://api.github.com
定义 CoApi - 客户端负载均衡
@CoApi(serviceId = "github-service")
public interface ServiceApiClient {
@GetExchange("repos/{owner}/{repo}/issues")
Flux<Issue> getIssue(@PathVariable String owner, @PathVariable String repo);
}
使用 CoApi
@RestController
class GithubController(
private val gitHubApiClient: GitHubApiClient,
private val serviceApiClient: ServiceApiClient
) {
@GetMapping("/baseUrl")
fun baseUrl(): Flux<Issue> {
return gitHubApiClient.getIssue("Ahoo-Wang", "CoApi")
}
@GetMapping("/serviceId")
fun serviceId(): Flux<Issue> {
return serviceApiClient.getIssue("Ahoo-Wang", "CoApi")
}
}
案例参考
https://gitee.com/AhooWang/CoApi/blob/main/example
服务提供者
https://gitee.com/AhooWang/CoApi/blob/main/example/example-provider-server
TodoApi : 规定了客户端消费方与服务提供者之间的共同契约,旨在防范重复冗余定义的风险,同时消除了服务提供者实现与客户端 SDK 的不一致性。
TodoClient : 客户端消费方通过 TodoClient 访问服务提供者的 API。
TodoController : 服务提供者负责实现 TodoApi 接口。
定义 API
@HttpExchange("todo")
interface TodoApi {
@GetExchange
fun getTodo(): Flux<Todo>
}
定义 Client
@CoApi(serviceId = "provider-service")
interface TodoClient : TodoApi
实现 API
@RestController
class TodoController : TodoApi {
override fun getTodo(): Flux<Todo> {
return Flux.range(1, 10)
.map {
Todo("todo-$it")
}
}
}
服务消费者
https://gitee.com/AhooWang/CoApi/blob/main/example/example-consumer-server
服务消费者通过 @EnableCoApi 注解开启 CoApi 的自动配置。
@EnableCoApi(clients = [TodoClient::class])
@SpringBootApplication
class ConsumerServer
@RestController
class TodoController(private val todoClient: TodoClient) {
@GetExchange
fun getProviderTodo(): Flux<Todo> {
return todoClient.getTodo()
}
}