Files
Pilz/Pilz.Net/Api/ApiClient.cs
Pilzinsel64 ab6411fe39 improvements
2024-12-12 07:31:25 +01:00

113 lines
3.4 KiB
C#

using Castle.Core.Logging;
using System.Web;
namespace Pilz.Net.Api;
public class ApiClient(string apiUrl) : IApiClient
{
protected readonly HttpClient httpClient = new();
protected readonly List<object> clients = [];
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 T GetClient<T>() where T : IApiSubClient
{
foreach (var c in clients)
{
if (c is T t)
return t;
}
if (T.CreateClient<T>(this) is T client)
{
clients.Add(client);
return client;
}
throw new ApiException("Could not create an instance of this client.");
}
public virtual async Task<ApiResponse> SendRequest(string route, HttpMethod method, ApiMessage? message, ApiParameterCollection? @params, IApiMessageSerializer? serializer)
{
serializer ??= Serializer;
Log.InfoFormat("Send message to {0}", route);
var res = await Send(route, method, message, @params, serializer);
return new(res.StatusCode);
}
public virtual async Task<ApiResponse<TResponse>> SendRequest<TResponse>(string route, HttpMethod method, ApiMessage? message, ApiParameterCollection? @params, IApiMessageSerializer? serializer) where TResponse : ApiMessage
{
serializer ??= Serializer;
Log.InfoFormat("Send request to {0}", route);
var res = await Send(route, method, message, @params, 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<HttpResponseMessage> Send(string route, HttpMethod method, ApiMessage? message, ApiParameterCollection? @params, IApiMessageSerializer serializer)
{
var url = ApiUrl + route + BuildParameters(@params);
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");
var httpmsg = new HttpRequestMessage(method, url)
{
Content = content
};
return await httpClient.SendAsync(httpmsg);
}
protected virtual string BuildParameters(ApiParameterCollection? @params)
{
if (@params == null || @params.Count == 0)
return string.Empty;
return "?" + string.Join("&", @params.Select(kvp =>
{
var key = kvp.Key;
var value = HttpUtility.UrlEncode(ConvertParameter(kvp.Value));
return $"{key}={value}";
}));
}
protected virtual string? ConvertParameter(object? @param)
{
return (string?)Convert.ChangeType(@param, typeof(string));
}
protected virtual string? EncodeAuthKey()
{
return AuthKey;
}
}