Files
sms-task-one/src/ApiClient/Http/HttpSmsClient.cs
Пытков Роман 1b85ec5ce8 Улучшения, теперь работает http и grpc
Но ещё требуется ревью и чистка
2026-06-01 18:10:42 +03:00

113 lines
3.7 KiB
C#

using System.Net;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using Contracts;
using Contracts.Menu;
using Contracts.Orders;
using Contracts.Requests;
using Contracts.Responses;
using Domain.Entities;
namespace ApiClient.Http;
public sealed class HttpSmsClient : ISmsClient, IDisposable
{
private readonly HttpClient _httpClient;
public HttpSmsClient(HttpSmsClientOptions options)
{
_httpClient = new HttpClient { BaseAddress = new Uri(options.BaseUrl) };
var credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{options.Username}:{options.Password}"));
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
}
public async Task<GetMenuApiResponse> GetMenuAsync(bool withPrice = true, CancellationToken cancellationToken = default)
{
var request = new GetMenuApiRequest
{
CommandParameters = new GetMenuParameters(withPrice),
};
var response = await SendAsync(request, cancellationToken);
return ToGetMenuResponse(response);
}
public async Task<SendOrderApiResponse> SendOrderAsync(Order order, CancellationToken cancellationToken = default)
{
var request = new SendOrderApiRequest
{
CommandParameters = new SendOrderParameters
{
OrderId = order.Id.ToString(),
MenuItems = order.Items.ToList(),
},
};
var response = await SendAsync(request, cancellationToken);
return ToSendOrderResponse(response);
}
public void Dispose() => _httpClient.Dispose();
private async Task<ApiResponse> SendAsync(ApiRequest request, CancellationToken cancellationToken)
{
var json = JsonSerializer.Serialize(request, request.GetType(), ApiJsonOptions.Instance);
using var content = new StringContent(json, Encoding.UTF8, "application/json");
using var httpResponse = await _httpClient.PostAsync("/", content, cancellationToken);
if (httpResponse.StatusCode == HttpStatusCode.Unauthorized)
{
return new ApiResponse
{
Command = request.Command,
Success = false,
ErrorMessage = "Требуется аутентификация.",
};
}
var responseJson = await httpResponse.Content.ReadAsStringAsync(cancellationToken);
if (string.IsNullOrWhiteSpace(responseJson))
{
return new ApiResponse
{
Command = request.Command,
Success = false,
ErrorMessage = $"Пустой ответ сервера (HTTP {(int)httpResponse.StatusCode}).",
};
}
try
{
return ApiResponseDeserializer.Deserialize(responseJson);
}
catch (JsonException)
{
return new ApiResponse
{
Command = request.Command,
Success = false,
ErrorMessage = $"Некорректный JSON в ответе (HTTP {(int)httpResponse.StatusCode}): {responseJson}",
};
}
}
private static GetMenuApiResponse ToGetMenuResponse(ApiResponse response) =>
response as GetMenuApiResponse ?? new GetMenuApiResponse
{
Command = Commands.GetMenu,
Success = false,
ErrorMessage = response.ErrorMessage,
};
private static SendOrderApiResponse ToSendOrderResponse(ApiResponse response) =>
response as SendOrderApiResponse ?? new SendOrderApiResponse
{
Command = Commands.SendOrder,
Success = false,
ErrorMessage = response.ErrorMessage,
};
}