ApiClient

This commit is contained in:
2026-06-01 00:41:06 +03:00
parent 51a047602e
commit 9c5763ba38
7 changed files with 198 additions and 6 deletions

View File

@@ -1,6 +0,0 @@
namespace ApiClient;
public class Class1
{
}

View File

@@ -0,0 +1,71 @@
using Contracts;
using Contracts.Menu;
using Contracts.Responses;
using Domain.Entities;
using Google.Protobuf.WellKnownTypes;
using Grpc.Net.Client;
using Sms.Test;
namespace ApiClient.Grpc;
public sealed class GrpcSmsClient : ISmsClient, IDisposable
{
private readonly GrpcChannel _channel;
private readonly SmsTestService.SmsTestServiceClient _client;
public GrpcSmsClient(GrpcSmsClientOptions options)
{
_channel = GrpcChannel.ForAddress(options.Address);
_client = new SmsTestService.SmsTestServiceClient(_channel);
}
public async Task<GetMenuApiResponse> GetMenuAsync(bool withPrice = true, CancellationToken cancellationToken = default)
{
var response = await _client.GetMenuAsync(new BoolValue { Value = withPrice }, cancellationToken: cancellationToken);
return new GetMenuApiResponse
{
Command = Commands.GetMenu,
Success = response.Success,
ErrorMessage = response.ErrorMessage,
Data = response.Success
? new GetMenuData { MenuItems = response.MenuItems.Select(ToDish).ToList() }
: null,
};
}
public async Task<SendOrderApiResponse> SendOrderAsync(Domain.Entities.Order order, CancellationToken cancellationToken = default)
{
var grpcOrder = new Sms.Test.Order { Id = order.Id.ToString() };
grpcOrder.OrderItems.AddRange(order.Items.Select(item => new Sms.Test.OrderItem
{
Id = item.Id,
Quantity = (double)item.Quantity,
}));
var response = await _client.SendOrderAsync(grpcOrder, cancellationToken: cancellationToken);
return new SendOrderApiResponse
{
Command = Commands.SendOrder,
Success = response.Success,
ErrorMessage = response.ErrorMessage,
};
}
public void Dispose()
{
_channel.Dispose();
}
private static Dish ToDish(MenuItem item) => new()
{
Id = item.Id,
Article = item.Article,
Name = item.Name,
Price = (decimal)item.Price,
IsWeighted = item.IsWeighted,
FullPath = item.FullPath,
Barcodes = item.Barcodes.ToList(),
};
}

View File

@@ -0,0 +1,6 @@
namespace ApiClient.Grpc;
public sealed class GrpcSmsClientOptions
{
public string Address { get; set; } = "http://localhost:5053";
}

View File

@@ -0,0 +1,89 @@
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 = 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, 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);
return ApiResponseDeserializer.Deserialize(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,
};
}

View File

@@ -0,0 +1,10 @@
namespace ApiClient.Http;
public sealed class HttpSmsClientOptions
{
public string BaseUrl { get; set; } = "http://localhost:5053";
public string Username { get; set; } = "user";
public string Password { get; set; } = "password";
}

View File

@@ -0,0 +1,11 @@
using Contracts.Responses;
using Domain.Entities;
namespace ApiClient;
public interface ISmsClient
{
Task<GetMenuApiResponse> GetMenuAsync(bool withPrice = true, CancellationToken cancellationToken = default);
Task<SendOrderApiResponse> SendOrderAsync(Order order, CancellationToken cancellationToken = default);
}

View File

@@ -0,0 +1,11 @@
using ApiClient.Grpc;
using ApiClient.Http;
namespace ApiClient;
public static class SmsClientFactory
{
public static HttpSmsClient CreateHttp(HttpSmsClientOptions options) => new(options);
public static GrpcSmsClient CreateGrpc(GrpcSmsClientOptions options) => new(options);
}