Designing an API Layer and BFF Architecture for a Large-Scale Supply Chain System
This article examines the challenges of a complex supply‑chain system built on Spring Cloud, proposes an API aggregation layer and a Backend‑for‑Frontend (BFF) pattern to reduce service coupling and client‑specific adaptation, and discusses practical implementation details and team organization.
In a previously designed supply‑chain system that includes products, sales orders, franchisees, store operations, and work orders, many user roles (headquarters product management, store management, franchisee staff, store personnel, etc.) are involved, and the system provides two client apps: one for customers and one for company employees and franchisees.
The overall architecture consists of a gateway layer responsible for routing, authentication, monitoring, and rate‑limiting/circuit‑breaking, as illustrated in the first diagram.
Case One : Multiple UI pages need data from several services (e.g., work‑order count, recent orders, low‑stock products). The team initially placed the first interface in the store service and the second interface in the work‑order service, leading to unclear responsibility boundaries.
Case Two : A single user action (e.g., submitting a work order) often requires updates across multiple services (inventory, sales order status, work order). This creates tangled dependencies among services, as shown in the second diagram.
To address these problems, the team introduced an API layer that satisfies three requirements for client interfaces: aggregation, distributed calls, and decoration.
Aggregation: a single endpoint combines data from multiple backend services.
Distributed calls: an endpoint may sequentially invoke several services to modify data.
Decoration: the API can filter or reshape backend data before returning it to the client.
The new architecture places all requests (after the gateway) into a shared API layer that has no own database; its main duty is to call other backend services.
Benefits observed include reduced indecision about where to place an interface and a drastic reduction in inter‑service dependencies, as only the API layer now calls backend services.
Fewer debates on interface placement : aggregation, decoration, and distributed‑call logic stay in the API layer; data‑persistence logic remains in the owning service.
Reduced backend coupling : backend services no longer call each other directly.
However, client‑specific adaptation still poses challenges because different clients (App, H5, PC, mini‑program) have varying data‑detail requirements, leading to three issues: divergent UI needs, frequent minor field changes, and increased compatibility complexity in the API layer.
To solve this, the team adopts the Backend‑for‑Frontend (BFF) pattern, creating a dedicated API service for each client type.
Each BFF can be optimized for its client, eliminating generic compatibility logic and allowing independent release cycles.
Given the system’s scale (nearly 100 services and hundreds of developers), the organization further splits API responsibilities per department, resulting in a more granular architecture.
The technical stack remains Spring Cloud‑based, with Zuul as the gateway (registered in ZooKeeper) and Feign for inter‑service calls.
Gateway: Spring Cloud Zuul, registers services in ZooKeeper and forwards requests via Feign.
API Service: a Spring Web service without its own database, responsible for aggregation, distributed calls, and decoration.
Backend Service: a Spring Web service with its own database and cache.
Code duplication between API services (e.g., PC API vs. App API) is handled in three ways: sharing a common JAR, extracting a separate CommonAPI service, or keeping duplicate code when the maintenance cost is lower.
For pure proxy APIs that merely forward requests, the team considered bypassing the API layer or adding an interceptor, but both approaches increased complexity, so they retained the simple proxy code.
Team division: a dedicated API development team owns all API services, while backend services are split into domain‑specific groups.
Overall, the architecture demonstrates how an API aggregation layer combined with BFF can improve modularity, reduce coupling, and support large‑scale, multi‑client supply‑chain systems.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.