You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Document CQRS command/query separation rule for API endpoints
Adds explicit guidance that command endpoints must not return domain
data — only a status code — and that queries are the sole place to
read state. Updates the REST controller example to show a command
returning 201 with no body alongside a query returning data, and adds
the pattern to the anti-patterns list.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
├── Sudoku.ServiceDefaults/ # Default service configurations
21
-
└── Tests/ # Unit and integration tests
21
+
└── Tests/ # Unit and integration tests
22
22
```
23
23
24
24
### Key Architectural Principles
@@ -34,14 +34,12 @@ Sudoku.sln
34
34
### C# Coding Standards
35
35
36
36
-**Naming Conventions**:
37
-
38
37
- Use PascalCase for public members, classes, and methods
39
38
- Use camelCase for private fields and local variables
40
39
- Use UPPER_CASE for constants
41
40
- Prefix private fields with underscore: `_fieldName`
42
41
43
42
-**File Organization**:
44
-
45
43
- One public class per file
46
44
- File name should match class name
47
45
- Group related classes in appropriate namespaces
@@ -295,30 +293,42 @@ public static class ServiceCollectionExtensions
295
293
296
294
## API Design Guidelines
297
295
296
+
### CQRS Command vs Query Separation
297
+
298
+
This is a CQRS application. Command endpoints and query endpoints are strictly separate:
299
+
300
+
-**Command endpoints** (`POST`, `PUT`, `PATCH`, `DELETE`) mutate state and **must not return domain data**. Return only an HTTP status code — `201 Created` with a `Location` header for creates, `204 No Content` for updates and deletes.
301
+
-**Query endpoints** (`GET`) read state and return data.
302
+
303
+
If a client needs the updated resource after a command, it issues a separate GET request. Mixing the two breaks the CQRS separation.
304
+
298
305
### REST API Controllers
299
306
300
307
```csharp
301
-
[ApiController]
302
-
[Route("api/[controller]")]
303
-
publicclassGamesController : ControllerBase
308
+
// COMMAND endpoint — mutates state, returns no data
@@ -419,6 +429,7 @@ public class GameByPlayerSpecification : ISpecification<Game>
419
429
5.**Magic Numbers**: Use constants or enums instead of magic numbers
420
430
6.**Long Methods**: Keep methods focused and under 20 lines when possible
421
431
7.**Deep Nesting**: Avoid deeply nested if statements and loops
432
+
8.**Returning data from command endpoints**: Command endpoints mutate state — they must not return domain data. If the client needs the updated resource after a command, it should issue a separate GET request. This keeps commands and queries cleanly separated.
422
433
423
434
Remember: This is a learning project focused on TDD, clean architecture, and modern .NET development practices. Prioritize code quality, testability, and maintainability over quick solutions.
0 commit comments