Shape your topology
So far the shop is one frond. This guide splits it in three — the catalog, the prices, the cart — has them call each other, then runs the catalog in its own process without changing their code.
Fronds
A frond is a directory under fronds/. It holds its own entities, handlers, services and
repositories:
fronds/
catalog/ Product, ProductHandler
pricing/ PriceHandler
cart/ CartHandler
A frond does not import another's files. It asks for another frond's facade, by type:
// fronds/pricing/handlers/PriceHandler.ts
import type { Facade } from '@fougere/core';
import type ProductHandler from '@fronds/catalog/handlers/ProductHandler.js';
export default class PriceHandler {
constructor(private catalog: Facade<ProductHandler>) {}
async getTotal(): Promise<number> {
const products = await this.catalog.list();
return products.items.reduce((sum, product) => sum + product.cents, 0);
}
}
// fronds/cart/handlers/CartHandler.ts
import type { Facade } from '@fougere/core';
import type PriceHandler from '@fronds/pricing/handlers/PriceHandler.js';
export default class CartHandler {
constructor(private pricing: Facade<PriceHandler>) {}
async getSummary(): Promise<{ cents: number }> {
return { cents: await this.pricing.getTotal() };
}
}
fougere graph prints the three fronds and which one calls which.
→ Frond
Moving a frond
To run the catalog in its own process, start it alone:
fougere dev catalog --port 4620 # in production: fougere build, then fougere serve
and give it that address in fougere.config.ts:
export default defineFougere({
fronds: { catalog: 'http://127.0.0.1:4620' },
});
PriceHandler keeps calling this.catalog.list() the same way; the call now crosses the
network. Remove the line and the catalog runs in the app's process again.
→ The gradient · CLI