Перейти к основному содержимому

Разработка контроллера веб-API сервиса бизнес-логики

Разработка контроллера веб-API сервиса бизнес-логики имеет некоторые особенности, которые описаны в этой статье.

Методы HTTP

Для вызова методов API сервиса бизнес-логики рекомендуется использовать HTTP-метод POST. Этот метод упрощает взаимодействие с другими сервисами и пользовательским интерфейсом.

[Route("/api/[controller]")]
[ApiController]
public class MyFirstController : ControllerBase
{
...

[Route("Greeting")]
[HttpPost]
public HelloApiResult Greeting(string name) {
...

В методах API можно получить доступ к программным сервисам через внедрение зависимостей (Dependency Injection (DI)).

[Route("/api/[controller]")]
[ApiController]
public class MyFirstController : ControllerBase
{
private readonly ILogger _logger;
private readonly IConfiguration _config;

public MyFirstController(ILogger<MyFirstController> logger, IConfiguration config)
{
_logger = logger;
_config = config;
...

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

Следующий блок кода демонстрирует добавление методу Create следующих атрибутов:

  • [SwaggerOperation(OperationId = "Create", Tags = [Constants.EventTypesTag])] для настройки описания метода в Swagger-документации;
  • [SwaggerResponse(200, "Результат выполнения операции", Type = typeof(EventTypeApiResult))] для описания возможного ответа метода при успешном выполнении (код состояния 200).
[HttpPost]
[Route("create")]
[Produces("application/json")]
[SwaggerOperation(OperationId = "Create", Tags = [Constants.EventTypesTag])]
[SwaggerResponse(200, "Результат выполнения операции", Type = typeof(EventTypeApiResult))]
public async Task<EventTypeApiResult> Create([FromBody] EventTypeParameter data)
{
...

Результат метода

Результаты, возвращаемые методами API сервиса бизнес-логики, должны являться наследниками класса ASE.MD.Platform.Utils.ModelsBase.ApiResults.ApiResult<TResult>, где TResult — класс возвращаемого методом результата. Такой подход обеспечивает формирование принятого в Платформе формата передачи информации между сервисами о результатах выполнения вызовов и об ошибках.

Класс ApiResult имеет несколько конструкторов, позволяющих создавать экземпляр с информацией о результате или об ошибке в процессе вызова.

Следующий блок кода демонстрирует пример класса ApiResult.

public class EventTypeApiResult : ApiResult<EventTypeResult>
{
/// <summary>
/// Конструктор без параметров
/// </summary>
public EventTypeApiResult()
: base()
{ }

/// <summary>
/// Конструктор с аргументом-возвращаемым значением
/// </summary>
/// <param name="result">Результат вызова</param>
public EventTypeApiResult(EventTypeResult result)
: base(result)
{ }

/// <summary>
/// Конструктор с аргументом-исключением
/// </summary>
/// <param name="e">информация об ошибке</param>
public EventTypeApiResult(Exception e)
: base(e, errorCode)
{ }

/// <summary>
/// Конструктор с аргументами-исключением и кодом ошибки
/// </summary>
/// <param name="e">информация об ошибке</param>
/// <param name="errorCode">код ошибки</param>
public EventTypeApiResult(Exception e, string errorCode)
: base(e, errorCode)
{ }
}

Следующий блок кода демонстрирует пример использования наследника класса ApiResult для передачи результата выполнения вызова.

public async Task<EventTypeApiResult> Create([FromBody] EventTypeParameter data)
{
// логика метода
...
var result = ...
...

// результат
return new EventTypeApiResult(result);
}

Следующий блок кода демонстрирует пример с обработкой исключений и возвратом информации об ошибках.

public async Task<EventTypeApiResult> Create([FromBody] EventTypeParameter data)
{
try
{
...
var result = ...
...
return new EventTypeApiResult(result);
}
catch (BaseException ex)
{
_logger.LogError(ex, "Неизвестная ошибка.");
return new EventTypeApiResult(ex);
}
catch (Exception ex)
{
_logger.LogError(ex, "Неизвестная ошибка.");
return new EventTypeApiResult(ex, "CustomErrorCode");
}
}

Обработка исключений

Исключения, генерируемые методами сервиса бизнес-логики, рекомендуется описывать с помощью наследников класса ASE.MD.Platform.Base.Error.Exceptions.BaseException. Этот класс имеет дополнительное свойство для кода ошибки, которое автоматически обрабатывается при возврате информации об ошибке.

Следующий блок кода демонстрирует пример класса-исключения.

[Serializable]
public class EventTypeException : BaseException
{
/// <summary>
/// Конструктор без параметров
/// </summary>
public EventTypeException()
{ }

/// <summary>
/// Конструктор с аргументом-исключением
/// </summary>
/// <param name="e">информация об ошибке</param>
public EventTypeException(string message)
: base(message, "MyErrorCode")
{ }

/// <summary>
/// Конструктор с аргументами-исключениями и кодом ошибки
/// </summary>
/// <param name="e">информация об ошибке</param>
/// <param name="errorCode">код ошибки</param>
public EventTypeException(string message, string errorCode)
: base(message, errorCode)
{ }
}