more work on api

This commit is contained in:
2024-08-15 15:51:23 +02:00
parent c24b460a0d
commit f57aef5f4f
6 changed files with 112 additions and 47 deletions

View File

@@ -1,9 +1,41 @@
namespace Pilz.Networking.Api; namespace Pilz.Networking.Api;
public class ApiClient : IApiClient public class ApiClient(string apiUrl) : IApiClient
{ {
public void MakeRequest<T>(string url, T message) where T : ApiMessage protected readonly HttpClient httpClient = new();
public string ApiUrl { get; } = apiUrl;
public IMessageSerializer Serializer { get; set; } = new DefaultMessageSerializer();
public virtual async Task<ApiResponse> SendMessage<TResponse>(string url, ApiMessage message, IMessageSerializer? serializer)
{ {
// ... serializer ??= Serializer;
//message.AuthSecret = AuthSecret;
var res = await Send(url, message, serializer);
return new(res.StatusCode);
}
public virtual async Task<ApiResponse<TResponse>> SendRequest<TResponse>(string url, ApiMessage message, IMessageSerializer? serializer) where TResponse : ApiMessage
{
serializer ??= Serializer;
//message.AuthSecret = AuthSecret;
var res = await Send(url, 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<HttpResponseMessage> Send(string url, ApiMessage message, IMessageSerializer serializer)
{
var fullRequestUrl = ApiUrl + url;
var content = new StringContent(serializer.Serialize(message)!, null, "application/json");
return await httpClient.PostAsync(fullRequestUrl, content);
} }
} }

View File

@@ -0,0 +1,13 @@
using System.Net;
namespace Pilz.Networking.Api;
public record class ApiResponse(
HttpStatusCode StatusCode)
{
public void EnsureOk()
{
if (StatusCode != HttpStatusCode.OK)
throw new Exception("Api return is not ok!");
}
}

View File

@@ -0,0 +1,15 @@
using System.Net;
namespace Pilz.Networking.Api;
public record class ApiResponse<T>(
HttpStatusCode StatusCode,
T? Message)
where T : ApiMessage
{
public void EnsureOk()
{
if (StatusCode != HttpStatusCode.OK)
throw new Exception("Api return is not ok!");
}
}

View File

@@ -4,8 +4,7 @@ namespace Pilz.Networking.Api;
public record class ApiResult( public record class ApiResult(
HttpStatusCode StatusCode, HttpStatusCode StatusCode,
ApiMessage? Message = null, ApiMessage? Message = null)
string? StatusDescription = null)
{ {
public static ApiResult Ok() public static ApiResult Ok()
{ {

View File

@@ -50,17 +50,20 @@ public class ApiServer(string apiUrl) : ApiClient, IApiServer
protected virtual void Listen() protected virtual void Listen()
{ {
while (httpListener.IsListening) while (httpListener.IsListening)
CheckContext();
}
protected virtual void CheckContext()
{ {
var context = httpListener.GetContext(); var context = httpListener.GetContext();
void close() => context.Response.OutputStream.Close();
if (context.Request.HttpMethod != HttpMethod.Post.Method if (context.Request.HttpMethod != HttpMethod.Post.Method
|| context.Request.ContentType is not string contentType || context.Request.ContentType is not string contentType
|| contentType.Contains("application/json") || !contentType.Contains("application/json"))
|| context.Request.AcceptTypes is null
|| context.Request.AcceptTypes.Contains("application/json"))
{ {
close(); close();
continue; return;
} }
// Parse url // Parse url
@@ -68,7 +71,7 @@ public class ApiServer(string apiUrl) : ApiClient, IApiServer
if (string.IsNullOrWhiteSpace(path) || context.Request.ContentLength64 <= 0) if (string.IsNullOrWhiteSpace(path) || context.Request.ContentLength64 <= 0)
{ {
close(); close();
continue; return;
} }
// Read input content // Read input content
@@ -76,24 +79,26 @@ public class ApiServer(string apiUrl) : ApiClient, IApiServer
var contentJson = input.ReadToEnd(); var contentJson = input.ReadToEnd();
// Handle message // Handle message
if (HandleMessage(path, contentJson) is not string resultJson) if (HandleMessage(path, contentJson) is not PrivateApiResult result)
{ {
close(); close();
continue; return;
} }
// Set response parameters // Set response parameters
context.Response.StatusCode = (int)args.ResponseStatusCode; context.Response.StatusCode = (int)result.Original.StatusCode;
context.Response.StatusDescription = args.ResponseStatusDescription; if (result.Original.StatusDescription is not null)
context.Response.StatusDescription = result.Original.StatusDescription;
// Write response content // Write response content
context.Response.ContentType = ContentTypes.CONTENT_TYPE_JSON; if (result.ResultJson is not null)
{
context.Response.ContentType = "application/json";
using StreamWriter output = new(context.Response.OutputStream); using StreamWriter output = new(context.Response.OutputStream);
output.Write(resultJson); output.Write(result);
}
close(); close();
void close() => context.Response.OutputStream.Close();
}
} }
protected virtual PrivateApiResult? HandleMessage(string url, string json) protected virtual PrivateApiResult? HandleMessage(string url, string json)

View File

@@ -2,5 +2,6 @@
public interface IApiClient public interface IApiClient
{ {
void MakeRequest<T>(string url, T message) where T : ApiMessage; Task<ApiResponse> SendMessage<TResponse>(string url, ApiMessage message, IMessageSerializer? serializer = null);
Task<ApiResponse<TResponse>> SendRequest<TResponse>(string url, ApiMessage message, IMessageSerializer? serializer = null) where TResponse : ApiMessage;
} }