Skip to content

Design Overview

This document describes the conceptual design of the integration layer.

The integration layer provides transport-independent messaging abstractions, typed message exchange, and backend-specific transport implementations behind a common interface.

The design focuses on:

  • explicit error handling
  • separation of concerns
  • transport independence
  • typed application messaging
  • extensible transport backends
  • predictable behavior

The API reference for concrete classes and functions is provided separately through the generated Doxygen documentation.

Status and Result Model

The integration layer uses an explicit value-or-error model for reporting operation outcomes.

Operations do not throw exceptions. Instead, they return either:

  • a status object for operations without a return value
  • a result object containing either a value or an error status

Errors are represented independently of transport and protocol layers.

Configuration

The integration layer provides reusable support for application configuration.

Generic configuration handling is separated from application-specific configuration definitions. Applications define their own configuration model, defaults, environment-variable mapping, and command-line options, while the common configuration layer performs loading, validation, precedence handling, and process-wide storage.

Configuration values are applied in the following order:

  • build-time defaults
  • environment variables
  • command-line options

Values from later sources override values from earlier sources. This allows applications to provide stable defaults while supporting deployment-specific and per-invocation overrides.

Configuration values are converted to application-specific types before use. Invalid values and configuration lifecycle errors are reported through the common status and result model.

The resulting configuration is stored as an immutable process-wide object. Applications typically define their configuration in a local configuration header and use the common configuration layer to load, initialize, and access it.

Message Model

The integration layer defines a transport-independent message model used to exchange data between components. Payload encoding is separated from message delivery, and optional transport features are exposed without forcing uniform semantics.

Address

An address identifies a transport-specific endpoint.

The interpretation of an address depends on the transport backend. Examples include queue names, topics, service identifiers, or logical endpoints.

Envelope

An envelope represents a transport-neutral encoded message.

It contains:

  • a serialized payload
  • message metadata
  • optional routing or correlation information

The payload remains opaque at this layer and is interpreted by codecs.

Message

A message represents a delivered transport message.

Depending on transport capabilities, a message may support transport-specific completion operations such as acknowledgment or rejection.

Optional features that are not supported by a transport are reported explicitly.

Typed Messages and Encoding

Application code operates on typed messages rather than serialized payloads.

Typed messages are converted to and from transport envelopes using codecs. Message formats can evolve independently from transports.

Codec

A codec defines how a typed application message is encoded into a transport envelope and decoded back into a typed representation.

Encoding and decoding failures are reported using the common status model.

Format

Encoding formats identify the representation used by a codec.

Examples include:

  • binary Protocol Buffers
  • JSON representations

Encoding format selection is independent of the transport backend.

Protocol Types

Application message types are defined using Protocol Buffers and exposed through stable library-level abstractions.

Transport Interface

The transport layer provides a generic abstraction for message delivery between components. The transport interface intentionally remains minimal and focuses on basic delivery semantics. Detailed behavior such as ordering guarantees, persistence, or broker-specific features is defined by individual transport implementations.

Overview

The transport abstraction defines two core operations:

  • sending messages to a destination
  • receiving messages from a source

Higher-level messaging patterns are expected to be implemented on top of these primitives.

Capabilities

Transport implementations may provide optional capabilities such as:

  • manual acknowledgment
  • message requeue
  • send confirmation

Capabilities are transport-dependent and may be queried at runtime.

Backend Selection

Transport backends are selected using type-level configuration. Backend-specific configuration remains isolated. New backends can be introduced without modifying existing interfaces.

Each backend defines its own configuration and capability model while exposing the common transport abstraction.

In-Memory Transport

The in-memory transport provides a simple transport implementation for use within a single process.

It is primarily intended for testing, prototyping, and validation of higher layers without requiring external infrastructure.

The implementation prioritizes deterministic behavior and minimal complexity over production-oriented messaging features. It serves as a reference implementation of the transport contract.

Behavior

  • Messages are delivered in FIFO order per address.
  • Receive operations support blocking and bounded-wait semantics.
  • Message delivery is performed entirely in-process.
  • Shutdown unblocks pending receive operations.

Capabilities

The in-memory transport does not provide advanced transport features such as:

  • manual acknowledgment
  • requeue semantics
  • send confirmation

Unsupported operations are reported explicitly.

RabbitMQ Transport

The RabbitMQ transport provides a transport implementation based on a RabbitMQ message broker.

It enables communication across process and system boundaries while preserving the common transport abstraction.

Behavior

  • Message delivery is managed by the broker.
  • Queue semantics and ordering follow RabbitMQ behavior.
  • Receive operations support blocking and bounded-wait semantics.
  • Connections and channels are managed internally by the transport layer.

Capabilities

The RabbitMQ transport supports broker-backed features such as:

  • manual acknowledgment
  • negative acknowledgment and requeue

Capability availability depends on broker behavior and transport configuration.

Configuration

The transport is configured through backend-specific option structures that define connection parameters and transport settings.

Messenger

The messenger provides a typed messaging interface built on top of the transport and codec layers. The messenger separates typed application logic from transport-specific message delivery details.

It combines:

  • a transport backend
  • a message encoding format

Overview

The messenger enables application code to exchange typed messages without interacting directly with transport envelopes or serialized payloads.

Encoding, decoding, and transport interaction are coordinated internally by the messenger layer.

Behavior

  • Typed messages are encoded before transport delivery.
  • Received transport messages are decoded into typed messages.
  • Transport and codec errors are propagated through the common status model.