Response Routing
When the InteractionResponse arrives at the server on the callback topic, it must be validated, routed to the waiting requester, and trigger post-receive hooks. This page explains exactly how that routing works.
Callback Topic Architecture
Each interaction has a unique callback topic: interactions.callback.{interactionId}. When the server publishes a request, it simultaneously subscribes to this topic via EdgeStream. The subscription persists until one of these events occurs:
- A valid
InteractionResponsearrives - An
InteractionTimeoutfires - The server shuts down (subscription is re-registered on restart)
Server-Side Response Reception
EdgeStream Delivers the Response
The InteractionResponse arrives on interactions.callback.{interactionId}. The InteractionPipeline's EdgeStream subscription handler fires.
Respondent Validation
The pipeline verifies that respondedBy is a legitimate recipient of the original request (was the target user, or a member of the targeted role at publish time). Invalid respondents are rejected.
Response Validation Hook
The ResponseValidationHook checks that the outcome is valid for the interaction type and that the data matches the expected schema. Invalid responses return an error to the client.
Post-Receive Hooks Run
All registered IInteractionHook.OnAfterRespond() implementations run: audit logging, metrics emission, business-specific side effects.
TaskCompletionSource Resolves
The PublishAndWaitAsync() call's internal TaskCompletionSource<InteractionResponse> is resolved with the response. The awaiting server code resumes with the full response object.
Custom Callback Topics
In most cases, the default callback topic interactions.callback.{interactionId} is the right choice. Custom callback topics are useful when:
- You have an existing EdgeStream subscription infrastructure and want responses to arrive there
- You are building a custom response aggregator (e.g., for multi-approval scenarios)
- You want to route the response to a different service than the one that sent the request
// Custom callback topic
const request: InteractionRequest = {
type: 'approval',
targetUserId: 'usr_abc',
title: '...',
payload: { ... },
timeoutMs: 86_400_000,
// Route response to a custom aggregator service
callbackTopic: 'my-service/approval-responses'
};
Multi-Service Scenarios
If your server is distributed (multiple service instances), the InteractionPipeline handles response routing across instances using the EdgeStream broker:
- The callback topic subscription is registered at the EdgeStream broker level — not tied to a specific server instance
- The response will be delivered to whichever server instance is subscribed, regardless of which instance originally sent the request
- For
PublishAndWaitAsync()to work correctly across instances, the pipeline uses a distributedTaskCompletionSourcebacked by the EdgeStream broker's in-memory pub/sub