Message Handler Port¶
message_handler_port
¶
Inbound message-handling ports for the application blocks.
This module defines the contract for handling application messages
(commands, queries, and domain events). Message handlers sit at the
application boundary and orchestrate domain logic by invoking domain
services, aggregates, value objects, and outbound ports.
Responsibilities
- Process an incoming message of a specific type.
- Delegate work to domain logic and outbound ports.
- Execute asynchronously.
Non-Responsibilities
- Infrastructure concerns (transport, serialization, queues).
- Transaction management (handled externally, e.g., by Unit of Work).
- Persistence (handled by repositories).
MessageHandlerPort
¶
Bases: InboundPort
Inbound port for handling messages asynchronously.
A MessageHandlerPort defines the contract for processing a single message
and producing a typed result. Implementations must avoid infrastructure
dependencies and remain purely application-blocks logic.
Implementers typically
- Validate or transform the incoming message.
- Orchestrate domain operations.
- Invoke repositories, outbound ports, and publish domain events.
Example
Source code in src/forging_blocks/application/ports/inbound/message_handler_port.py
handle(message: MessageType) -> MessageHandlerResultType
abstractmethod
async
¶
Process a message and return an application result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
MessageType
|
The message instance to handle. |
required |
Returns:
| Type | Description |
|---|---|
MessageHandlerResultType
|
A value representing the result of the message processing. |
Raises:
| Type | Description |
|---|---|
ApplicationError
|
If processing fails due to business logic violations. |
Notes
This method is asynchronous and should not block. Infrastructure
concerns such as retry logic or message acknowledgment must be
handled externally.
Source code in src/forging_blocks/application/ports/inbound/message_handler_port.py
CommandHandlerPort
¶
Bases: MessageHandlerPort[Command[CommandPayloadType], None]
Inbound port for handling commands.
Commands are fire-and-forget: the handler returns None on
success and raises on failure.
Example
Source code in src/forging_blocks/application/ports/inbound/message_handler_port.py
QueryHandlerPort
¶
Bases: MessageHandlerPort[Query[QueryPayloadType], QueryResultType]
Inbound port for handling queries.
Queries return a typed result; the handler must not mutate
observable state.
Example
class GetOrder(Query[dict[str, object]]):
def __init__(self) -> None:
super().__init__()
@property
def _payload(self) -> dict[str, object]:
return {}
class GetOrderHandler(QueryHandlerPort[dict[str, object], dict[str, object]]):
async def handle(self, message: Query[dict[str, object]]) -> dict[str, object]: ...
Source code in src/forging_blocks/application/ports/inbound/message_handler_port.py
EventHandlerPort
¶
Bases: MessageHandlerPort[Event[EventPayloadType], None]
Inbound port for handling domain events.
Event handlers react to domain events; they return None and
may trigger side effects through outbound ports.