← ClaudeAtlas

api-layer-boundarieslisted

Enforce layering in ASP.NET Core services - what belongs in controllers, application services, and repositories; DTO vs entity leakage; where transactions and validation live. Use when reviewing or designing API endpoints and service classes.
Sarmkadan/dotnet-senior-skills · ★ 0 · API & Backend · score 72
Install: claude install-skill Sarmkadan/dotnet-senior-skills
# API Layer Boundaries ## Controller / endpoint: translation only A controller method does exactly: bind + validate input shape, call one application-layer method, map result to an HTTP response. Budget: ~10 lines. Anything else has leaked. Reject in controllers: - `DbContext` or repository injection. The controller must not know persistence exists. - Business conditionals (`if (order.Total > limit)`), loops over domain data, price/permission calculations. - `SaveChanges`, transactions, `try/catch` that maps exceptions to status codes per-action - use exception-handling middleware / `IExceptionHandler` once, globally. - Composing multiple service calls into a workflow. A workflow is an application-service method; the controller calls it by name. ```csharp // WRONG: orchestration in controller [HttpPost] public async Task<IActionResult> Create(CreateOrderRequest req) { var customer = await _customers.GetAsync(req.CustomerId); if (customer.IsBlocked) return BadRequest("blocked"); var order = new Order { /* ... */ }; _db.Orders.Add(order); await _db.SaveChangesAsync(); await _email.SendAsync(customer.Email, "..."); return Ok(order); // entity leaked, lazy-load serialization bomb included } // RIGHT [HttpPost] public async Task<ActionResult<OrderDto>> Create(CreateOrderRequest req, CancellationToken ct) { var result = await _orderService.CreateAsync(req.ToCommand(), ct); return result is null ? Conflict() : CreatedAtAction(nameof(Get), new