← Назад к вопросам

Как реализовывал единый интерфейс?

2.0 Middle🔥 121 комментариев
#ООП и паттерны проектирования

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как я реализовывал единый интерфейс (унифицированный API)

В контексте C# Backend-разработки единый интерфейс обычно означает создание унифицированного, согласованного API (часто RESTful) для взаимодействия между различными компонентами системы (клиентами, сервисами, внешними системами). Я реализовывал это через несколько ключевых подходов.

Ключевые принципы и шаблоны проектирования

  1. Абстрактные классы и интерфейсы для стандартизации поведения:
public interface IApiService<TRequest, TResponse> where TResponse : ApiResponse
{
    Task<TResponse> ExecuteAsync(TRequest request);
    ApiResponse Validate(TRequest request);
}

public abstract class BaseApiService<TRequest, TResponse> : IApiService<TRequest, TResponse>
{
    public virtual ApiResponse Validate(TRequest request)
    {
        // Базовая валидация для всех запросов
        return ApiResponse.Success();
    }
    
    public abstract Task<TResponse> ExecuteAsync(TRequest request);
}
  1. Медиатор (Mediator) через MediatR для единообразной обработки запросов:
public class UnifiedApiController : ControllerBase
{
    private readonly IMediator _mediator;

    [HttpPost("process/{type}")]
    public async Task<IActionResult> Process([FromBody] UnifiedRequest request)
    {
        var command = new ProcessCommand(request.Type, request.Data);
        var result = await _mediator.Send(command);
        
        return result.ToActionResult();
    }
}

Архитектурные подходы

Стратегия единой точки входа с использованием:

  • API Gateway для маршрутизации запросов к соответствующим микросервисам
  • Единого формата ответов для всех конечных точек
  • Стандартизированной обработки ошибок
public class UnifiedResponse<T>
{
    public bool Success { get; set; }
    public T Data { get; set; }
    public ApiError Error { get; set; }
    public DateTime Timestamp { get; set; }
    
    public static UnifiedResponse<T> CreateSuccess(T data)
    {
        return new UnifiedResponse<T>
        {
            Success = true,
            Data = data,
            Timestamp = DateTime.UtcNow
        };
    }
}

Практическая реализация в ASP.NET Core

[ApiController]
[Route("api/v1/[controller]")]
[Produces("application/json")]
public abstract class BaseApiController : ControllerBase
{
    // Единый обработчик для всех запросов
    protected async Task<IActionResult> HandleRequest<T>(Func<Task<T>> action)
    {
        try
        {
            var result = await action();
            return Ok(UnifiedResponse.CreateSuccess(result));
        }
        catch (ValidationException ex)
        {
            return BadRequest(UnifiedResponse.CreateError("VALIDATION_ERROR", ex.Message));
        }
        catch (Exception ex)
        {
            return StatusCode(500, UnifiedResponse.CreateError("INTERNAL_ERROR", ex.Message));
        }
    }
}

Специфические реализации

Для работы с различными внешними API создавал адаптеры единого интерфейса:

public class ExternalApiAdapter : IExternalService
{
    private readonly HttpClient _client;
    private readonly ILogger<ExternalApiAdapter> _logger;
    
    public async Task<UnifiedResponse<OrderData>> GetOrderAsync(string orderId)
    {
        // Преобразование разных форматов к единому
        var externalResponse = await _client.GetAsync($"orders/{orderId}");
        var externalData = await externalResponse.Content.ReadFromJsonAsync<ExternalOrder>();
        
        // Адаптация к единому формату
        return UnifiedResponse.CreateSuccess(new OrderData
        {
            Id = externalData.OrderIdentifier,
            Total = externalData.Amount,
            Status = MapStatus(externalData.StatusCode)
        });
    }
}

Автоматизация и инфраструктурные компоненты

С использованием middleware для сквозной функциональности:

public class UnifiedApiMiddleware
{
    private readonly RequestDelegate _next;
    
    public async Task InvokeAsync(HttpContext context)
    {
        // Логирование всех запросов
        LogRequest(context.Request);
        
        // Установка корреляционных идентификаторов
        context.Items["CorrelationId"] = Guid.NewGuid().ToString();
        
        // Единая обработка исключений
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }
}

Преимущества такого подхода

  • Согласованность – все клиенты получают данные в едином формате
  • Упрощение поддержки – стандартная обработка ошибок и логирование
  • Легкость расширения – добавление новых endpoints не нарушает существующих клиентов
  • Улучшенный мониторинг – единые метрики и логи для всех запросов
  • Безопасность – централизованная аутентификация и авторизация

Пример использования в реальном проекте

В проекте электронной коммерции мы реализовали единый Product API, который обслуживал:

  • Мобильное приложение
  • Веб-сайт
  • Партнерские интеграции
  • Административную панель

Через единый интерфейс все клиенты получали одинаково структурированные данные о продуктах, но с возможностью кастомизации ответов через параметры запроса (поля, фильтрация, пагинация).

Такой подход сократил время разработки новых интеграций на 40% и значительно упростил сопровождение системы, так как изменения в бизнес-логике требовали правок только в одном месте, а не во всех клиентских приложениях отдельно.

Как реализовывал единый интерфейс? | PrepBro