Advanced Topics¶
-
Back to Chain of Responsibility Overview
Return to the Chain of Responsibility overview page with all topics.
Overview¶
You can also build chains manually using the build_chain() function:
from cqrs.requests.cor_request_handler import build_chain
# Create handler instances
handler1 = CreditCardHandler()
handler2 = PayPalHandler()
handler3 = DefaultPaymentHandler()
# Build chain manually
chain = build_chain([handler1, handler2, handler3])
# Use the chain
result = await chain.handle(
ProcessPaymentCommand(
amount=100.0,
payment_method="credit_card",
user_id="user1",
)
)
set_next(handler)¶
Sets the next handler in the chain. Returns the next handler to allow chaining:
next(request)¶
Passes the request to the next handler in the chain:
async def handle(self, request: ProcessPaymentCommand) -> PaymentResult | None:
if can_handle(request):
return process(request)
# Pass to next handler
return await self.next(request)
events Property¶
Returns the list of events generated by the handler. Must be implemented:
Chain of Responsibility is ideal for:
- Payment processing — Try different payment methods in order
- Authentication — Try multiple authentication strategies
- Validation — Multiple validation rules with fallback
- Error handling — Try different recovery strategies
- Feature flags — Try different implementations based on availability
-
Rate limiting — Multiple rate limiters with fallback
-
Order matters — Place handlers in order of preference or priority
- Always have a default — Include a default handler at the end of the chain
- Clear decision logic — Make it obvious when a handler can process a request
- Return early — Return immediately after processing, don't continue the chain
- Use
next()correctly — Only callnext()when you can't handle the request - Handle events — Collect events from handlers that process requests
| Feature | Regular Handler | COR Handler |
|---|---|---|
| Processing | Single handler | Multiple handlers in sequence |
| Decision | Always processes | Decides whether to process |
| Fallback | Not available | Built-in via chain |
| Use Case | Simple operations | Multiple strategies |
| Registration | Single handler | List of handlers |
Chain of Responsibility works well with:
- Dependency Injection — Handlers can be injected with dependencies
- Event Handling — Handlers can emit events when processing requests
- Middleware — Middleware can be applied to the entire chain
- Regular Handlers — COR handlers can be used alongside regular handlers
The Chain of Responsibility pattern provides a flexible way to handle requests with multiple processing strategies. By linking handlers together, you can:
- Try multiple strategies in order
- Implement fallback mechanisms
- Separate concerns across handlers
- Easily extend functionality by adding new handlers