Шаг 17: OrdersController
Controller принимает HTTP-запросы и делегирует обработку через MediatR. Контроллер максимально тонкий -- три действия: принять запрос, создать Command/Query, вернуть результат.
OrdersController.cs
В папке Controllers проекта API:
using MediatR;
using Microsoft.AspNetCore.Mvc;
using OrderManagement.Application.Orders.Commands.CancelOrder;
using OrderManagement.Application.Orders.Commands.ConfirmOrder;
using OrderManagement.Application.Orders.Commands.CreateOrder;
using OrderManagement.Application.Orders.DTOs;
using OrderManagement.Application.Orders.Queries.GetCustomerOrders;
using OrderManagement.Application.Orders.Queries.GetOrder;
namespace OrderManagement.API.Controllers;
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
private readonly IMediator _mediator;
public OrdersController(IMediator mediator) =>
_mediator = mediator;
[HttpPost]
[ProducesResponseType(typeof(Guid), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create(
[FromBody] CreateOrderCommand command,
CancellationToken ct)
{
var orderId = await _mediator.Send(command, ct);
return CreatedAtAction(
nameof(GetById), new { id = orderId }, orderId);
}
[HttpGet("{id:guid}")]
[ProducesResponseType(typeof(OrderDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetById(
Guid id, CancellationToken ct)
{
var order = await _mediator.Send(
new GetOrderQuery(id), ct);
return Ok(order);
}
[HttpGet("customer/{customerId}")]
[ProducesResponseType(typeof(List<OrderDto>), StatusCodes.Status200OK)]
public async Task<IActionResult> GetByCustomer(
string customerId, CancellationToken ct)
{
var orders = await _mediator.Send(
new GetCustomerOrdersQuery(customerId), ct);
return Ok(orders);
}
[HttpPost("{id:guid}/confirm")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Confirm(
Guid id, CancellationToken ct)
{
await _mediator.Send(new ConfirmOrderCommand(id), ct);
return NoContent();
}
[HttpPost("{id:guid}/cancel")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Cancel(
Guid id, [FromBody] CancelRequest request,
CancellationToken ct)
{
await _mediator.Send(
new CancelOrderCommand(id, request.Reason), ct);
return NoContent();
}
}
public record CancelRequest(string Reason);
[ApiController] включает автоматическую валидацию ModelState. [Route("api/[controller]")] -- URL /api/orders. CreatedAtAction возвращает 201 с заголовком Location. CancellationToken передаётся ASP.NET Core автоматически.