Skip to content
GuidesDocs 1.3.x

Connectum Runtime Architecture

Connectum is a modular service runtime, not a deployment platform. Its central composition boundary is createServer(): it registers routes, protocols, and interceptors; selects the network transport; and coordinates startup, drain, and shutdown for one service process.

This page explains the runtime relationships that matter when extending or operating that process. Exact configuration fields remain in the generated core API, while deployment products and platforms remain in their focused guides.

Boundary and ownership

The framework owns the behavior inside a Connectum service process:

  • transport selection and server lifecycle;
  • registration of typed services and protocol plugins;
  • the ordered server-interceptor chain;
  • the Context supplied to typed handlers;
  • local or remote service-call dispatch when a catalog is configured;
  • lifecycle integration for an explicitly supplied EventBus.

Connectum does not own a gateway, service mesh, scheduler, message broker, or telemetry backend. Those systems connect through documented seams and can be selected independently.

Runtime composition

Every inbound network request follows one shared execution path. TransportManager owns the selected Node transport, buildRoutes() composes services and protocol registrations, the configured server interceptors run in order, and the matched route invokes a typed handler with a Connectum Context.

Protocol modules such as Health Check and Reflection register additional routes through the same router contract. EventBus and OpenTelemetry are opt-in capabilities: the server coordinates the supplied EventBus lifecycle, while OTel instrumentation attaches through server/client interceptors and its provider.

Connectum service process composition RPC clients enter the createServer runtime through the network transport, shared ConnectRPC route tree, server interceptor chain, and typed handlers. Protocol plugins register with the route tree. Optional EventBus and OpenTelemetry capabilities remain explicit; their broker and telemetry sinks stay outside the Connectum service process. Connectum service process createServer() owns registration, startup, drain, and shutdown SHARED RPC EXECUTION PATH EXPLICIT CAPABILITIES · OPT-IN RPC clients Connect · gRPC TransportManager HTTP/1.1 · h2c · TLS buildRoutes() services + protocols serverInterceptors auth · validation · OTel Typed handlers Connectum Context ProtocolRegistration[] Health · Reflection custom registrations EventBus routing · middleware · adapter server-managed lifecycle OpenTelemetry server + client interceptors provider · traces · metrics · logs adapter I/O export Broker or memory NATS · Kafka · Redis · AMQP Telemetry sink OTLP collector · console
The solid route is the shared inbound RPC path. Dashed routes are explicit integrations: protocol registration and OpenTelemetry instrumentation. Brokers and telemetry sinks remain outside the service process.

Network and in-process parity

An in-process client does not open a socket. createLocalTransport() calls createRouterTransport(routes) and supplies the same serverInterceptors before reaching the handler. Client-side interceptors may additionally wrap the in-memory call.

This shared route and interceptor boundary is the parity invariant: application behavior should not depend on whether a locally mounted service was reached over HTTP or through the in-process transport. See In-Process Transport for the exact guarantee, limitations, and test utilities.

Catalog call routing

Handlers use the generated service catalog through ctx.call and ctx.stream. The per-server catalog dispatcher resolves the typed method and builds the outgoing call frame from the current handler context.

Routing then depends on where the target service is mounted:

  1. A locally mounted typeName uses the in-process transport and re-enters the same process's routes, server interceptors, and typed handler chain. One createServer() instance may register several service typeName values.
  2. A service not mounted locally is passed to remoteResolver, which supplies the ConnectRPC Transport used for the remote call. The request then crosses the process boundary and enters the remote server through its resolver-supplied Transport and connectNodeAdapter({ routes, interceptors }).

The incoming cancellation signal and remaining deadline cascade to catalog calls unless the caller supplies a stricter override. Inbound headers are not forwarded implicitly; only configured allow-listed headers and explicit call headers are propagated.

Local and remote Connectum service catalog routing A handler calls ctx.call or ctx.stream. CatalogDispatcher resolves a local target through createLocalTransport and createRouterTransport over routes with serverInterceptors. For a non-local typeName, remoteResolver supplies a ConnectRPC Transport that crosses to another createServer instance, where connectNodeAdapter applies routes and server interceptors before invoking the target handler. createServer() · caller and local services services filtered by enabledServices and registered in routes remote createServer() separate service process registeredServiceTypeNames registeredServiceTypeNames isLocal network handler Context ctx.call · ctx.stream CatalogDispatcher _resolveTransport() remoteResolver Transport | null createLocalTransport in-process · no socket createRouterTransport routes serverInterceptors local target handler matched typeName · other services behind Transport unary() · stream() connectNodeAdapter() routes + server interceptors remote target handler matched typeName
CatalogDispatcher selects the transport; it does not select a different handler contract. Both the in-process createRouterTransport() path and the remote connectNodeAdapter() path apply the target server's routes and server interceptors before the handler. Stacked cards represent additional registered service typeName values; response arrows are omitted for legibility.

The catalog is optional. A service process that hosts everything locally and makes no typed cross-service calls does not need one. Configuration and error semantics are owned by the Service Catalog guide, with resolver construction covered by Remote Resolvers.

Extension seams

CapabilityRuntime attachmentExternal dependency
Server interceptorsOrdered ConnectRPC request chainOptional identity, policy, or application services
Protocol pluginsRegister RPC routes and optional HTTP fallbacksProtocol-specific clients and tooling
Service catalogAdds typed ctx.call / ctx.stream dispatchResolver-supplied remote transports
EventBusSupplied to createServer() and started/stopped with itNone for Memory; NATS, Kafka, Redis, or AMQP broker otherwise
OpenTelemetryServer/client interceptors plus providerOTLP collector or console exporter

These are explicit capabilities rather than hidden runtime defaults. Install and compose only the modules required by the service.

Deployment boundary

Gateways, service meshes, Kubernetes, registries, and telemetry backends surround the process but are not framework prerequisites. Their placement depends on the deployment topology rather than on createServer() internals:

Build-time inputs

Proto schemas, generated service descriptors, and the optional generated service catalog are build-time inputs to this runtime. They are deliberately outside the process diagrams: they define and generate the contracts consumed by route and catalog registration, but they do not execute in the request path.

Start with Scaffolding for generation workflow and Service Communication for choosing between synchronous catalog calls and asynchronous events.