Roadmap › .NET Full Stack Developer Interview — End to End › Module: End-to-End Request Flow
Lessons in this course (10)

3. From a button click to SQL Server and back

Intermediate★ Must knowLesson 3 of 10

Follow one request — "Load page 1 of orders for customer 42":

1. UI (Angular) — the component asks a service; the service calls the API:

typescript
// order.service.ts
@Injectable({ providedIn: 'root' })
export class OrderService {
  private http = inject(HttpClient);
  getOrders(customerId: number, page = 1, size = 20) {
    return this.http.get<PagedResult<OrderDto>>(`/api/customers/${customerId}/orders`, { params: { page, size } });
  }
}

2. Browser → server — HTTPS request; an interceptor adds Authorization: Bearer <token>; for another origin the browser first sends a CORS preflight (OPTIONS).

3. ASP.NET Core pipeline — Kestrel receives it → middleware in order: exception handler → HTTPS redirection → routing → CORS → authentication → authorization → endpoint.

4. Controller / endpoint — model binding, validation, call the service:

csharp
[ApiController]
[Route("api/customers/{customerId:int}/orders")]
public class OrdersController(IOrderService orders) : ControllerBase
{
    [HttpGet]
    public async Task<ActionResult<PagedResult<OrderDto>>> Get(int customerId, [FromQuery] int page = 1, [FromQuery] int size = 20, CancellationToken ct = default)
        => Ok(await orders.GetPageAsync(customerId, page, Math.Clamp(size, 1, 100), ct));
}

5. Service + EF Core — LINQ is translated to one SQL query; AsNoTracking for read-only; project to a DTO so only needed columns travel:

csharp
public async Task<PagedResult<OrderDto>> GetPageAsync(int customerId, int page, int size, CancellationToken ct)
{
    var query = db.Orders.AsNoTracking().Where(o => o.CustomerId == customerId);
    var total = await query.CountAsync(ct);
    var items = await query.OrderByDescending(o => o.OrderDate)
        .Skip((page - 1) * size).Take(size)
        .Select(o => new OrderDto(o.Id, o.OrderDate, o.Status, o.Lines.Sum(l => l.Qty * l.Price)))
        .ToListAsync(ct);
    return new PagedResult<OrderDto>(items, total, page, size);
}

6. SQL Server — runs the generated query (ORDER BY ... OFFSET ... FETCH), ideally an index seek on (CustomerId, OrderDate DESC).

7. Back up the stack — DTOs serialised to JSON by System.Text.Json → 200 OK → Angular deserialises → the template renders with @for.

Interview tip: Mention async all the way (frees threads while waiting for SQL), CancellationToken (stops work when the user navigates away), AsNoTracking and projection. These four show production experience.