What is CoApi?
Overview
CoApi exists because Spring 6 introduced the HTTP Interface (@HttpExchange) but left a critical gap: there is no auto-configuration. Developers must manually wire HttpServiceProxyFactory, choose between WebClient and RestClient, handle URL resolution, and manage bean lifecycles. Meanwhile, OpenFeign — the de facto standard for declarative HTTP clients in Spring Cloud — lacks reactive programming support. Its recommended alternative, feign-reactive, is unmaintained and incompatible with Spring Boot 3.2+.
CoApi fills this gap with annotation-driven, zero-boilerplate auto-configuration. Define an interface, annotate it with @CoApi, and CoApi automatically registers the HTTP client bean, the JDK proxy, and all supporting infrastructure. It supports both reactive (WebClient) and synchronous (RestClient) models with a single annotation, and integrates client-side load balancing via Spring Cloud LoadBalancer.
At a Glance
| Component | Responsibility | Key File | Source |
|---|---|---|---|
@CoApi | Marks interfaces as HTTP clients, provides baseUrl/serviceId/name | CoApi.kt | CoApi.kt |
@LoadBalanced | Marks interface for client-side load balancing | LoadBalanced.kt | LoadBalanced.kt |
CoApiDefinition | Parsed metadata: name, apiType, baseUrl, loadBalanced | CoApiDefinition.kt | CoApiDefinition.kt |
CoApiRegistrar | Registers WebClient/RestClient + proxy beans per interface | CoApiRegistrar.kt | CoApiRegistrar.kt |
CoApiFactoryBean | Creates JDK proxy via HttpServiceProxyFactory | CoApiFactoryBean.kt | CoApiFactoryBean.kt |
CoApiAutoConfiguration | Boot auto-configuration entry point | CoApiAutoConfiguration.kt | CoApiAutoConfiguration.kt |
Why CoApi?
The Spring ecosystem has three approaches to declarative HTTP clients. Here is how they compare:
| Feature | CoApi | Spring Cloud OpenFeign | Manual HTTP Interface |
|---|---|---|---|
| Auto-configuration | Zero config | Zero config | Manual setup per client |
| Reactive support (WebClient) | Built-in | None | Manual |
| Synchronous support (RestClient) | Built-in | Built-in | Manual |
| Load balancing | Built-in | Built-in | Manual |
| Spring Boot 4.x / Spring 7.x | Supported | Supported | Supported |
| Annotation-driven | @CoApi | @FeignClient | @HttpExchange only |
| Dual-mode switching | coapi.mode property | N/A | Code change required |
How It Works
graph LR
subgraph "1. Define"
A["@CoApi Interface"]
end
subgraph "2. Discover"
B[AutoCoApiRegistrar]
C[EnableCoApiRegistrar]
end
subgraph "3. Register"
D["WebClient / RestClient Bean"]
E[Proxy Bean]
end
subgraph "4. Use"
F["Inject & Call"]
end
A --> B
A --> C
B --> D
B --> E
C --> D
C --> E
D --> E
E --> FThe Two-Bean-Per-Interface Pattern
CoApi registers two beans for every @CoApi-annotated interface:
sequenceDiagram
autonumber
participant Registrar as CoApiRegistrar
participant Registry as BeanDefinitionRegistry
participant WCF as WebClientFactoryBean
participant CFB as CoApiFactoryBean
participant Proxy as JDK Proxy
Registrar->>Registry: registerBeanDefinition(name + ".HttpClient", WebClientFactoryBean)
Registrar->>Registry: registerBeanDefinition(name + ".CoApi", CoApiFactoryBean)
Note over WCF: Creates WebClient instance
Note over CFB: Creates interface proxy
CFB->>WCF: get HttpClient bean
CFB->>Proxy: HttpServiceProxyFactory.createClient(apiType)
Proxy-->>CFB: Proxy implementing @CoApi interface- HTTP Client Bean (
name.HttpClient) — aWebClientorRestClientconfigured with base URL, filters/interceptors, and optional load balancing. - Proxy Bean (
name.CoApi) — a JDK dynamic proxy implementing the annotated interface, generated by Spring'sHttpServiceProxyFactory.
Client Mode Inference
flowchart TD
A[Application Starts] --> B{"coapi.mode property?"}
B -->|REACTIVE| C["WebClient + WebClientAdapter"]
B -->|SYNC| D["RestClient + RestClientAdapter"]
B -->|AUTO or unset| E{org.springframework.web.reactive.HandlerResult on classpath?}
E -->|Yes| C
E -->|No| DModule Architecture
graph BT
subgraph "Library Modules"
API["api<br>@CoApi, @LoadBalanced"]
SPRING["spring<br>Registrar, FactoryBean, Client SPI"]
STARTER["spring-boot-starter<br>Auto-configuration, Properties"]
end
subgraph "Support"
BOM["bom<br>Bill of Materials"]
DEPS["dependencies<br>Version management"]
end
subgraph "Examples"
PROV["example-provider-*"]
CONS["example-consumer-*"]
SYNC["example-sync"]
end
SPRING --> API
STARTER --> SPRING
BOM --> API
BOM --> SPRING
BOM --> STARTER
DEPS --> API
DEPS --> SPRING
PROV --> API
CONS --> STARTER
SYNC --> STARTERVersion Compatibility
| CoApi Version | Spring Boot | Spring Framework | JDK |
|---|---|---|---|
| 1.x | 3.2.x | 6.x | 17+ |
| 2.x | 4.x | 7.x | 17+ |
Current version: 2.0.1 (gradle.properties:21)
Key Features
- Zero-boilerplate — one annotation, full auto-configuration
- Dual-mode — reactive (
WebClient) or synchronous (RestClient) via property or classpath inference - Load balancing — integrated with Spring Cloud LoadBalancer
- Customizable —
WebClientBuilderCustomizer/RestClientBuilderCustomizerSPI for global and per-client customization - Authentication — built-in
BearerTokenFilterwith JWT-awareCachedExpirableTokenProvider - Filter/interceptor — per-client filter chains configurable via YAML properties
Related Pages
- Installation & Setup — add CoApi to your project
- Quick Start — define your first HTTP client
- Configuration Reference — all properties explained
- Architecture Overview — deep dive into registration flow
References
- CoApi Annotation —
api/src/main/kotlin/me/ahoo/coapi/api/CoApi.kt - CoApiDefinition —
spring/src/main/kotlin/me/ahoo/coapi/spring/CoApiDefinition.kt - CoApiRegistrar —
spring/src/main/kotlin/me/ahoo/coapi/spring/CoApiRegistrar.kt - CoApiFactoryBean —
spring/src/main/kotlin/me/ahoo/coapi/spring/CoApiFactoryBean.kt - ClientMode —
spring/src/main/kotlin/me/ahoo/coapi/spring/ClientMode.kt - README.md — Project overview and usage examples