How-To: Local Macroservice Development
When developing macroservices locally, you often need to run multiple services (e.g., finance, inventory, shell) as independent processes. Framework M enables zero-config discovery for this scenario using a local file-sharing protocol.
NATS-Based Local Discovery
When FRAMEWORK_MODE=MACROSERVICE is active, Framework M uses NATS JetStream KV for real-time service discovery. This ensures that even on localhost, discovery remains deterministic and mirrors production behavior.
How it works
- Startup: Every service you start connects to NATS (default:
nats://localhost:4222) and publishes its manifest to them_discoveryKV bucket. - Shared State: The NATS KV bucket acts as the "discovery oracle," storing the endpoints and owned DocTypes for every active process.
- Real-time Updates: The Shell and other services maintain a watcher on the NATS KV bucket. When you start or stop a service locally, the discovery state is updated in milliseconds across all processes.
Local Requirements
You must have a NATS server with JetStream enabled running locally.
# Start NATS with JetStream via Docker
docker run -d -p 4222:4222 -p 8222:8222 nats:latest -js
Bypassing Discovery (SKIP_DISCOVERY)
In some scenarios (e.g., debugging a specific component in isolation), you may want to skip the discovery handshake entirely.
- Env Var:
FRAMEWORK_M_SKIP_DISCOVERY=true - Effect: The
DiscoveryClientwill not attempt to ping the gateway oracle or read the local discovery file. It will assume all resources are local to the currentAPI_URL.
Troubleshooting Local Discovery
If a service is "invisible" to the shell:
- Check the File: Run
cat ~/.framework_m_discovery.json. Ensure your service name and port are listed. - Check the Mode: Ensure both the shell and the service are running with
FRAMEWORK_MODE=MACROSERVICE. - Purge State: If the file contains stale entries from crashed processes, you can safely delete it:
rm ~/.framework_m_discovery.json. It will be recreated on the next service start.