REST Clients: Contract-First Approach with OpenAPI + Feign

───

The Problem

In a microservices architecture, you have two paths: write HTTP clients by hand or generate them. The first path leads to constant errors, outdated models, and endless boilerplate.

We chose the contract-first approach. The OpenAPI specification is the single source of truth. Everything generates automatically.

───

Architecture

OpenAPI YAML → OpenAPI Generator → Feign Client → Reactive Wrapper → Resilience

───

1. OpenAPI Specification

openapi: 3.0.1 info: title: Order Service API paths: /orders: post: operationId: createOrder requestBody: content: application/json: schema: $ref: '#/components/schemas/OrderRequest' responses: "201": description: Order created content: application/json: schema: $ref: '#/components/schemas/

───

2. Maven Plugin

org.openapitools openapi-generator-maven-plugin 7.9.0

${basedir}/src/main/resources/schema

true spring-cloud

com.example.orderservice.dto com.example.orderservice.api spring

───

3. Generated Feign Client

@FeignClient( name = "${order-service.name:order-service}", url = "${order-service.url:http://localhost:8080}", configuration = ClientConfiguration.class) public interface OrderApiClient extends OrderApi { }

───

4. Reactive Interface

public interface ReactiveOrderApiClient {

Mono> createOrder(OrderRequest request);

Mono>> getOrders(String customerId); }

───

5. Circuit Breaker for Reactive Calls

public class ReactiveCircuitBreakerRecoverable {

public Mono mono(Supplier supplier) { return Mono.fromSupplier(supplier) .transformDeferred(CircuitBreakerOperator.of(circuitBreaker)); }

}

───

Usage Example

@Service @RequiredArgsConstructor public class OrderService {

private final ReactiveOrderApiClient orderClient;

public Mono placeOrder(OrderRequest request) { return orderClient.createOrder(request); }

public Mono> findCustomerOrders(String customerId) { return orderClient.getOrders(customerId); } }

───

Result

Developers get:

• Type-safe calls without HTTP boilerplate • Reactivity out of the box • Circuit Breaker with configured recoverable exceptions • DTO generation from OpenAPI schema

#openapi #feign #springcloud #microservices #java #restclient