Skip to content

APiGen BFF (Backend For Frontend) Module

A Spring Boot module that provides Backend For Frontend (BFF) capabilities with query composition, client-specific response tailoring, and combined rate limiting.

Overview

The BFF pattern solves common challenges in microservice architectures:

  • Query Composition: Aggregate multiple microservice calls into single responses
  • Response Tailoring: Customize responses per client type (mobile/web/desktop/IoT/API)
  • Combined Rate Limiting: Apply rate limits across aggregated services
  • Reduced Round Trips: Optimize frontend requests and improve performance

Features

1. Query Composition

Compose multiple microservice calls with different strategies:

  • Parallel All: Execute all requests in parallel, fail if any fails
  • Parallel Best-Effort: Execute in parallel, return partial results on failure
  • Sequential: Execute one-by-one, stop on first failure
  • Sequential Best-Effort: Execute sequentially, continue on failure

2. Response Tailoring

Automatically optimize responses based on client capabilities:

  • Mobile: Excludes audit fields (createdAt, updatedAt, metadata) for smaller payloads
  • Web: Balanced payloads with full feature set
  • Desktop: Larger payloads with detailed information
  • IoT: Minimal payloads, essential data only
  • API: Full raw data without optimizations

3. Combined Rate Limiting

Smart rate limiting that considers the cost of aggregated requests:

  • Request weight based on number of services (3 services = 3x weight)
  • Sliding window algorithm for fair distribution
  • Per-endpoint and per-user tracking
  • Configurable limits and windows

Quick Start

1. Enable BFF Auto-Configuration

yaml
apigen:
  bff:
    enabled: true
    default-rate-limit: 60
    default-timeout-ms: 5000
    response-tailoring:
      enabled: true

2. Create a BFF Endpoint

java
@RestController
@RequestMapping("/api/bff")
public class ProductBffController {

    private final QueryCompositionService compositionService;

    @GetMapping("/product/{id}")
    @BffEndpoint(
        services = {"products", "reviews", "inventory"},
        strategy = CompositionStrategy.PARALLEL_ALL,
        supportedClients = {ClientType.MOBILE, ClientType.WEB}
    )
    public Mono<Map<String, Object>> getProductDetails(@PathVariable Long id) {
        List<ServiceRequest> requests = List.of(
            ServiceRequest.builder().serviceId("products").path("/api/products/" + id).build(),
            ServiceRequest.builder().serviceId("reviews").path("/api/reviews/product/" + id).build(),
            ServiceRequest.builder().serviceId("inventory").path("/api/inventory/product/" + id).build()
        );

        return compositionService.compose(requests, CompositionStrategy.PARALLEL_ALL);
    }
}

Client Type Headers

Specify the client type using the X-Client-Type header:

bash
# Mobile client
curl -H "X-Client-Type: MOBILE" http://localhost:8080/api/bff/endpoint

# Web client
curl -H "X-Client-Type: WEB" http://localhost:8080/api/bff/endpoint

Released under the MIT License.