Skip to main content

Federated Composition (JIT)

Framework M utilizes Just-In-Time (JIT) Composition instead of the deprecated "Proxy Hydration" over the network.

The Anti-Pattern: Proxy Hydration

Under the "Proxy Hydration" pattern, if a finance.Invoice DocType has a link to crm.Customer, the backend makes a secondary HTTP call to the CRM microservice to resolve the customer object before returning the invoice. This creates significant latency, hidden N+1 queries, and severe backend bottlenecking.

The Solution: Raw IDs & Frontend Composition

To stop hiding the network, the backend composition adapter strictly returns the raw ID of the foreign key (e.g., {"customer_id": "123"}).

The responsibility for resolving cross-service linked entities lies exclusively with the frontend UI. The frontend makes explicit asynchronous requests to the appropriate service endpoints, maximizing browser connection concurrency, caching, and maintaining a clear network boundary.

Service Namespacing & API Prefixing

To facilitate frontend-led entity resolution across heterogeneous macroservices, the framework employs a dynamic namespacing strategy:

  1. Namespaced Resource Keys: Resources can be referenced using a service/resource pattern (e.g., finance/PurchaseInvoice).
  2. Dynamic API Resolution: The frontend DataProvider uses these namespaced keys to dynamically reconstruct the correct service-scoped API path (e.g., /api/finance/{version}/PurchaseInvoice).
  3. Architectural Isolation: This ensures that each macroservice maintains its own independent API namespace (/api/{service}/{version}) while the central Shell or other MFEs can still resolve and interact with resources across the entire federated ecosystem.
  4. Zero-Cliff Portability: MFEs remain agnostic of whether the backend is a monolith or a cluster of macroservices, as the URL resolution logic adapts automatically based on the environment configuration (FRAMEWORK_API_VERSION) and injected service context.

Discovery-Driven Routing

Instead of hardcoding service locations, the framework uses a Discovery Handshake at startup.

  • The Discovery Manifest: The Shell fetches a central manifest from /api/gateway/remotes containing DiscoveryUnit objects.
  • Dynamic Base URLs: Each service (e.g., finance) declares its own apiUrl and metaUrl.
  • Intelligent Dispatch: The DataProvider looks up these URLs in real-time. A request for finance/Invoice is automatically dispatched to the exact base URL declared by the finance service, even if it resides on a completely different domain.

This "Late Binding" of API endpoints allows developers to move services between Monolith and Macroservice modes without changing a single line of frontend code.