using Castle.Core.Logging; namespace Pilz.Net.Api; public class ApiClient(string apiUrl) : IApiClient { protected readonly HttpClient httpClient = new(); public virtual string ApiUrl { get; } = apiUrl; public string? AuthKey { get; set; } public virtual IApiMessageSerializer Serializer { get; set; } = new DefaultApiMessageSerializer(); public ILogger Log { get; set; } = NullLogger.Instance; public virtual Task SendRequest(string route) { return SendRequest(route, null); } public virtual Task SendRequest(string route, ApiMessage? message) { return SendRequest(route, message, null); } public virtual async Task SendRequest(string route, ApiMessage? message, IApiMessageSerializer? serializer) { serializer ??= Serializer; Log.InfoFormat("Send message to {0}", route); var res = await Send(route, message, serializer); return new(res.StatusCode); } public virtual Task> SendRequest(string route) where TResponse : ApiMessage { return SendRequest(route, null); } public virtual Task> SendRequest(string route, ApiMessage? message) where TResponse : ApiMessage { return SendRequest(route, message, null); } public virtual async Task> SendRequest(string route, ApiMessage? message, IApiMessageSerializer? serializer) where TResponse : ApiMessage { serializer ??= Serializer; Log.InfoFormat("Send request to {0}", route); var res = await Send(route, message, serializer); TResponse? result = null; if (res.IsSuccessStatusCode) result = serializer.Deserialize(await res.Content.ReadAsStringAsync(), typeof(TResponse)) as TResponse; return new(res.StatusCode, result); } protected virtual async Task Send(string route, ApiMessage? message, IApiMessageSerializer serializer) { var url = ApiUrl + route; HttpContent content; Log.DebugFormat("Api endpoint url is {0}", url); Log.Debug("Create content"); if (message is not null) content = new StringContent(serializer.Serialize(message)!, null, "application/json"); else content = new StringContent(string.Empty, null, "application/json"); Log.Debug("Build headers"); content.Headers.Add("API-AUTH-KEY", EncodeAuthKey()); Log.Debug("Sending request"); return await httpClient.PostAsync(url, content); } protected virtual string? EncodeAuthKey() { return AuthKey; } }