| name | api-dto-review |
| description | Review API DTO implementations for contract/domain separation, mapping patterns, and REST compliance |
Purpose: Review API DTO implementations for contract/domain separation, mapping patterns, and REST compliance.
When to Use
- Reviewing PRs that introduce or modify Request/Response DTOs
- Validating DTO mapping patterns (ToResponse/ToModel helpers)
- Checking API contract decoupling from domain models
Review Checklist
1. DTO Structure
2. Mapping Pattern
3. Controller Integration
4. Validation & Error Handling
5. REST Compliance
6. Edge Cases
Common Issues
❌ Anti-Pattern: Route Parameter in Request DTO
public class TalkRequest
{
[Required] public int EngagementId { get; set; }
}
[HttpPost("{engagementId:int}/talks")]
public async Task<ActionResult> CreateTalkAsync(int engagementId, TalkRequest request)
Fix: Remove EngagementId from TalkRequest. Use route parameter in mapping:
var talk = ToModel(request, engagementId);
❌ Anti-Pattern: Returning Domain Models
[ProducesResponseType(StatusCodes.Status200OK, Type=typeof(Engagement))]
public async Task<ActionResult<Engagement>> GetEngagementAsync(int id)
{
return await _manager.GetAsync(id);
}
Fix: Map to Response DTO:
[ProducesResponseType(StatusCodes.Status200OK, Type=typeof(EngagementResponse))]
public async Task<ActionResult<EngagementResponse>> GetEngagementAsync(int id)
{
var engagement = await _manager.GetAsync(id);
return ToResponse(engagement);
}
Testing Verification
After DTO changes:
- Run existing API tests:
dotnet test --filter FullyQualifiedName~Api.Tests --no-build
- Check test count matches PR description (e.g., "all 45 API tests pass")
- Verify no new test failures introduced
Related Decisions
.squad/decisions/inbox/trinity-pr512-dtos.md — DTO mapping pattern (private static helpers)
.squad/decisions/inbox/neo-pr512-review-dto-route-params.md — Route parameters must not be in Request DTOs