Revert CQRS middleware response serialization responsibility approach - #802
Conversation
test: Run #2249
🎉 All tests passed!🔄 This comment has been updated |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## v10.0-preview #802 +/- ##
=================================================
+ Coverage 80.05% 80.07% +0.01%
=================================================
Files 230 231 +1
Lines 4343 4356 +13
Branches 344 338 -6
=================================================
+ Hits 3477 3488 +11
- Misses 782 784 +2
Partials 84 84 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This pull request reverts the CQRS middleware response serialization responsibility approach. The architectural change shifts serialization responsibility back to CQRSMiddleware (and CQRSResponseSerializerMiddleware for output caching scenarios), while middlewares now only need to set the ExecutionResult on the HttpContext or provide the complete HTTP response directly.
Key Changes
- Replaced
CompleteCQRSExecutionResult()withSetCQRSExecutionResult()- middlewares now set the execution result without handling serialization - Added
CQRSResponseSerializerMiddlewareto handle serialization after OutputCache middleware, ensuring cached responses are properly serialized - Introduced
IsHttpResponseSet()heuristic to detect if a middleware has already claimed the HTTP response, allowingCQRSMiddlewareto skip serialization when appropriate - Enhanced test coverage with a new parameterized test for exception handling after
CQRSPipelineFinalizerexecution
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
test/CQRS/LeanCode.CQRS.AspNetCore.Tests/Middleware/TestHelpers.cs |
Removed null-forgiving operator and extra whitespace |
test/CQRS/LeanCode.CQRS.AspNetCore.Tests/Middleware/CQRSValidationMiddlewareTests.cs |
Updated tests to use SetCQRSExecutionResult() and removed serialization assertions |
test/CQRS/LeanCode.CQRS.AspNetCore.Tests/Middleware/CQRSSecurityMiddlewareTests.cs |
Updated tests to use SetCQRSExecutionResult() and removed response checks |
test/CQRS/LeanCode.CQRS.AspNetCore.Tests/Middleware/CQRSOutputCachingObservabilityMiddlewareTests.cs |
Added CQRSResponseSerializerMiddleware to middleware chain and updated to use SetCQRSExecutionResult() |
test/CQRS/LeanCode.CQRS.AspNetCore.Tests/Middleware/CQRSMiddlewareTests.cs |
Converted exception test to Theory with two cases (before/after finalizer) and updated all tests to use SetCQRSExecutionResult() |
test/CQRS/LeanCode.CQRS.AspNetCore.Tests/Middleware/CQRSExceptionTranslationMiddlewareTests.cs |
Updated tests to use SetCQRSExecutionResult() and removed serialization assertions |
test/CQRS/LeanCode.CQRS.AspNetCore.Tests/Local/MiddlewareBasedLocalExecutorTests.cs |
Updated to use SetCQRSExecutionResult() |
test/CQRS/LeanCode.CQRS.AspNetCore.Tests.Integration/OutputCache/RemoteCQRSOutputCachingTests.cs |
Changed dictionary initialization syntax from collection initializer to indexer syntax |
src/CQRS/LeanCode.CQRS.Execution/HttpContextExtensions.cs |
Added SetCQRSExecutionResult() method with duplicate check; updated GetCQRSRequiredExecutionResult() to use custom exception |
src/CQRS/LeanCode.CQRS.Execution/ExecutionResult.cs |
Changed default status code from magic number 200 to StatusCodes.Status200OK |
src/CQRS/LeanCode.CQRS.AspNetCore/Middleware/CQRSValidationMiddleware.cs |
Updated to use SetCQRSExecutionResult() instead of CompleteCQRSExecutionResult() |
src/CQRS/LeanCode.CQRS.AspNetCore/Middleware/CQRSSecurityMiddleware.cs |
Updated to use SetCQRSExecutionResult() instead of CompleteCQRSExecutionResult() |
src/CQRS/LeanCode.CQRS.AspNetCore/Middleware/CQRSResponseSerializerMiddleware.cs |
New middleware for serializing responses after OutputCache middleware |
src/CQRS/LeanCode.CQRS.AspNetCore/Middleware/CQRSPipelineFinalizer.cs |
Updated to use SetCQRSExecutionResult() instead of CompleteCQRSExecutionResult() |
src/CQRS/LeanCode.CQRS.AspNetCore/Middleware/CQRSMiddleware.cs |
Added conditional serialization logic using IsHttpResponseSet() check |
src/CQRS/LeanCode.CQRS.AspNetCore/Middleware/CQRSExceptionTranslationMiddleware.cs |
Updated to use SetCQRSExecutionResult() instead of CompleteCQRSExecutionResult() |
src/CQRS/LeanCode.CQRS.AspNetCore/HttpContextExtensions.cs |
Refactored serialization into public SerializeCQRSResultAsync() and added IsHttpResponseSet() heuristic |
src/CQRS/LeanCode.CQRS.AspNetCore/CQRSApplicationBuilder.cs |
Added CQRSResponseSerializerMiddleware to CacheOutput() chain |
docs/cqrs/pipeline/index.md |
Updated documentation to reflect new serialization approach and middleware responsibilities |
docs/cqrs/pipeline/adding_custom_middlewares.md |
Updated custom middleware guidance with new SetCQRSExecutionResult() API and short-circuiting patterns |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
So now we kind of went back with what we're requiring from the CQRS middlewares. They either:
ExecutionResulton theHttpContextHttpResponseif they know what they're doing, as it might begin to be sent to client right awaySo
CQRSMiddlewarewill again serialize theExecutionResult, if non other middleware has "claimed" the HttpResponse (detected with hopefully reasonable heuristics), which is a new twist I guess.To ensure that
OutputCachingMiddlewarealways has theHttpResponseprepared to be stored into cache, aCQRSResponseSerializerMiddlewareis always added after it, which has the same serialization logic as inCQRSMiddleware.Aaaand the detected case, of pipeline returning status code 200 after some exception was thrown after
CQRSPipelineFinalizerwas run, has a dedicated test.