Overview
Transports provide the lowest-level communication adapters in ONECMS.
They are intentionally boring.
Their role is to move data across process or network boundaries while enforcing architectural invariants and preventing misuse.
What Is a Transport?
A transport is a thin adapter that:
- executes a request
- applies minimal, shared defaults
- enforces execution constraints
Examples:
- HTTP transport → REST-style requests
- GraphQL transport → GraphQL operation execution
- Signal transport → In-process pub/sub events
What Transports Are Not
Transports must not:
- contain business logic
- orchestrate workflows
- manage UI state
- infer domain intent
- depend on framework lifecycle
Anything beyond request execution belongs in:
- services
- modules
- feature shells
Transport Types
HTTP Transport
- Generic request adapter
- Environment-aware
- Callable from multiple execution contexts
- Used for REST-style APIs and non-GraphQL endpoints
GraphQL Transport
- Browser-only execution
- Strict operation ownership
Signal Transport
- In-process pub/sub over PubSubJS
- Typed topic registry (
SignalTopicType) - Used for decoupled intra-tab communication between components, modules, and services
- Service-only consumption
- Explicit misuse guards
Layering and Ownership
UI / Modules -> Services -> Transports -> External APIs
Key rules:
- UI never talks to transports directly
- Services bind transports to domain intent
- Transports remain framework-agnostic
Why This Matters
By keeping transports dumb and strict:
- execution is predictable
- misuse is caught early
- refactors are safer
- architectural boundaries remain intact
Transports should fade into the background — if you are debugging business logic inside a transport, something has gone wrong.