# How to Integrate CoApi into Spring Boot Applications: A Step-by-Step Guide

> Integrate CoApi into Spring Boot apps easily. Follow our step-by-step guide to add the starter dependency, enable CoApi, define interfaces, and inject clients for seamless integration.

- Repository: [Ahoo Wang/coapi](https://github.com/ahoo-wang/coapi)
- Tags: how-to-guide
- Published: 2026-02-23

---

**Integrate CoApi into your Spring Boot applications by adding the `coapi-spring-boot-starter` dependency, annotating your main class with `@EnableCoApi`, defining HTTP interfaces with `@CoApi`, and injecting the generated clients as Spring beans.**

CoApi is a zero-boilerplate auto-configuration library for Spring 6's HTTP Interface that lets you declare remote APIs as plain Kotlin or Java interfaces. This guide walks you through integrating CoApi (ahoo-wang/coapi) into existing Spring Boot applications to create type-safe, reactive or synchronous HTTP clients without writing implementation code.

## Step 1: Add the CoApi Starter Dependency

Add the `coapi-spring-boot-starter` to your build configuration to pull in the necessary auto-configuration beans.

**Gradle (Kotlin DSL):**

```kotlin
implementation("me.ahoo.coapi:coapi-spring-boot-starter")

```

**Gradle (Groovy DSL):**

```groovy
implementation 'me.ahoo.coapi:coapi-spring-boot-starter'

```

**Maven:**

```xml
<dependency>
    <groupId>me.ahoo.coapi</groupId>
    <artifactId>coapi-spring-boot-starter</artifactId>
    <version>${coapi.version}</version>
</dependency>

```

## Step 2: Enable CoApi Auto-Configuration

Annotate your `@SpringBootApplication` or a `@Configuration` class with `@EnableCoApi` to trigger the auto-configuration mechanism. According to the source code in [`spring/src/main/kotlin/me/ahoo/coapi/spring/EnableCoApi.kt`](https://github.com/ahoo-wang/coapi/blob/main/spring/src/main/kotlin/me/ahoo/coapi/spring/EnableCoApi.kt), this annotation imports `EnableCoApiRegistrar`, which scans the `clients` attribute and registers a `CoApiDefinition` for each interface.

```kotlin
import me.ahoo.coapi.spring.EnableCoApi
import org.springframework.boot.autoconfigure.SpringBootApplication

@EnableCoApi(clients = [GitHubApiClient::class, TodoClient::class])
@SpringBootApplication
class MyApplication

```

If you omit the `clients` attribute, Spring will scan for interfaces annotated with `@CoApi` automatically.

## Step 3: Define a CoApi Interface

Create an interface annotated with `@CoApi` (or Spring's generic `@HttpExchange`) to declare your remote API. The [`CoApiDefinition.kt`](https://github.com/ahoo-wang/coapi/blob/main/CoApiDefinition.kt) file handles the metadata extraction from these annotations, supporting both `baseUrl` configuration and `serviceId` for load balancing.

```kotlin
import me.ahoo.coapi.spring.CoApi
import org.springframework.web.service.annotation.GetExchange
import org.springframework.web.bind.annotation.PathVariable
import reactor.core.publisher.Flux

@CoApi(baseUrl = "\${github.url}")
interface GitHubApiClient {

    @GetExchange("repos/{owner}/{repo}/issues")
    fun getIssues(@PathVariable owner: String,
                  @PathVariable repo: String): Flux<Issue>
}

```

Configure the base URL in your [`application.yml`](https://github.com/ahoo-wang/coapi/blob/main/application.yml):

```yaml
github:
  url: https://api.github.com

```

## Step 4: Inject and Use the Generated Client

Spring automatically creates a bean implementation of your interface. Simply constructor-inject it and call methods as if they were local service calls. The [`example/example-consumer-server/src/main/kotlin/me/ahoo/coapi/example/consumer/ConsumerServer.kt`](https://github.com/ahoo-wang/coapi/blob/main/example/example-consumer-server/src/main/kotlin/me/ahoo/coapi/example/consumer/ConsumerServer.kt) file demonstrates this pattern in practice.

```kotlin
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class GithubController(private val gitHubApiClient: GitHubApiClient) {

    @GetMapping("/issues")
    fun listIssues() = gitHubApiClient.getIssues("Ahoo-Wang", "CoApi")
}

```

## How CoApi Works Behind the Scenes

The integration relies on two core components that handle client registration and mode selection.

**`AbstractCoApiRegistrar`** determines whether to create a **reactive** or **synchronous** client by reading the `coapi.client-mode` property (default is reactive). It then registers the appropriate `HttpExchangeAdapterFactory`—either `ReactiveHttpExchangeAdapterFactory` or `SyncHttpExchangeAdapterFactory`. This logic is implemented in [`spring/src/main/kotlin/me/ahoo/coapi/spring/AbstractCoApiRegistrar.kt`](https://github.com/ahoo-wang/coapi/blob/main/spring/src/main/kotlin/me/ahoo/coapi/spring/AbstractCoApiRegistrar.kt).

**`CoApiDefinition`** holds the metadata for each client, including `baseUrl` and `serviceId`, derived from the `@CoApi` annotation and the Spring `Environment`. The registrar creates a bean definition for each interface based on this metadata, as defined in [`spring/src/main/kotlin/me/ahoo/coapi/spring/CoApiDefinition.kt`](https://github.com/ahoo-wang/coapi/blob/main/spring/src/main/kotlin/me/ahoo/coapi/spring/CoApiDefinition.kt).

## Optional: Configure Load Balancing

To integrate with Spring Cloud LoadBalancer, specify a `serviceId` instead of a hardcoded URL:

```kotlin
@CoApi(serviceId = "github-service")
interface LoadBalancedGitHubClient {
    @GetExchange("repos/{owner}/{repo}/issues")
    fun getIssues(@PathVariable owner: String,
                  @PathVariable repo: String): Flux<Issue>
}

```

Add the LoadBalancer starter to your dependencies:

```kotlin
implementation("org.springframework.cloud:spring-cloud-starter-loadbalancer")

```

CoApi will now resolve the service via Spring Cloud LoadBalancer using the logical service name.

## Summary

- Add `coapi-spring-boot-starter` to your build file to enable auto-configuration.
- Use `@EnableCoApi` on your main application class to trigger the registration process handled by `EnableCoApiRegistrar`.
- Define HTTP clients as interfaces with `@CoApi`, specifying either `baseUrl` or `serviceId`.
- Inject the generated beans directly into your controllers or services.
- Configure `coapi.client-mode` to switch between reactive (default) and synchronous execution.
- Enable Spring Cloud LoadBalancer support by adding the load balancer starter and using service IDs.

## Frequently Asked Questions

### What is the difference between CoApi and Spring's standard HTTP Interface?

CoApi provides zero-boilerplate auto-configuration for Spring 6's HTTP Interface. While Spring requires manual `HttpServiceProxyFactory` configuration, CoApi automatically registers client implementations as beans through `AbstractCoApiRegistrar` when you use `@EnableCoApi`, eliminating the need for explicit proxy creation.

### How do I switch between reactive and synchronous client modes?

Set the `coapi.client-mode` property in your [`application.yml`](https://github.com/ahoo-wang/coapi/blob/main/application.yml) to `sync` or `reactive`. The default is reactive. The `AbstractCoApiRegistrar` reads this property and instantiates either `SyncHttpExchangeAdapterFactory` or `ReactiveHttpExchangeAdapterFactory` accordingly.

### Can I use CoApi with Spring Cloud LoadBalancer?

Yes. Specify `serviceId` in your `@CoApi` annotation instead of `baseUrl`, and include `spring-cloud-starter-loadbalancer` in your dependencies. CoApi automatically integrates with Spring Cloud LoadBalancer to resolve logical service names to physical endpoints.

### Which Spring Boot versions support CoApi?

CoApi supports Spring Boot 3.2+ for the current stable line. For CoApi 2.x releases, Spring Boot 4.x (when available) will be the target platform. Check the repository's compatibility matrix for specific version requirements.