88 lines
3.6 KiB
C#
88 lines
3.6 KiB
C#
using Microsoft.Extensions.Logging;
|
|
using System.IO;
|
|
using System.Net.Http.Headers;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
|
|
namespace JSMR.Infrastructure.Http;
|
|
|
|
public abstract class ApiClient(IHttpService http, ILogger logger, JsonSerializerOptions? json = null)
|
|
{
|
|
protected async Task<T> GetJsonAsync<T>(string url, CancellationToken cancellationToken = default)
|
|
{
|
|
string response = await http.GetStringAsync(url, cancellationToken);
|
|
|
|
return JsonSerializer.Deserialize<T>(response, json)
|
|
?? throw new InvalidOperationException($"Failed to deserialize JSON to {typeof(T).Name} from {url}.");
|
|
}
|
|
|
|
//protected async Task<T> GetJsonAsync<T>(
|
|
// string url,
|
|
// Action<HttpRequestHeaders>? configureHeaders = null,
|
|
// CancellationToken ct = default
|
|
// )
|
|
//{
|
|
// using var req = new HttpRequestMessage(HttpMethod.Get, url);
|
|
// configureHeaders?.Invoke(req.Headers);
|
|
|
|
// LogRequest(req);
|
|
|
|
// using var res = await http.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, ct).ConfigureAwait(false);
|
|
// await EnsureSuccess(res).ConfigureAwait(false);
|
|
|
|
// var stream = await res.Content.ReadAsStreamAsync(ct).ConfigureAwait(false);
|
|
|
|
// var model = await JsonSerializer.DeserializeAsync<T>(stream, json, ct).ConfigureAwait(false)
|
|
// ?? throw new InvalidOperationException($"Failed to deserialize JSON to {typeof(T).Name} from {url}.");
|
|
|
|
// return model;
|
|
//}
|
|
|
|
//protected async Task<TResponse> PostJsonAsync<TRequest, TResponse>(
|
|
// string url,
|
|
// TRequest payload,
|
|
// Action<HttpRequestHeaders>? configureHeaders = null,
|
|
// CancellationToken ct = default)
|
|
//{
|
|
// var content = new StringContent(JsonSerializer.Serialize(payload, json), Encoding.UTF8, "application/json");
|
|
// using var req = new HttpRequestMessage(HttpMethod.Post, url) { Content = content };
|
|
// configureHeaders?.Invoke(req.Headers);
|
|
|
|
// LogRequest(req);
|
|
|
|
// using var res = await http.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, ct).ConfigureAwait(false);
|
|
// await EnsureSuccess(res).ConfigureAwait(false);
|
|
|
|
// var stream = await res.Content.ReadAsStreamAsync(ct).ConfigureAwait(false);
|
|
|
|
// var model = await JsonSerializer.DeserializeAsync<TResponse>(stream, json, ct).ConfigureAwait(false)
|
|
// ?? throw new InvalidOperationException($"Failed to deserialize JSON to {typeof(TResponse).Name} from {url}.");
|
|
|
|
// return model;
|
|
//}
|
|
|
|
//protected virtual void LogRequest(HttpRequestMessage req)
|
|
// => logger.LogDebug("HTTP {Method} {Uri}", req.Method, req.RequestUri);
|
|
|
|
//protected virtual void LogFailure(HttpResponseMessage res, string body)
|
|
// => logger.LogWarning("HTTP {Status} for {Uri}. Body: {Body}", (int)res.StatusCode, res.RequestMessage?.RequestUri, Truncate(body, 500));
|
|
|
|
//protected static string Truncate(string s, int max) => s.Length <= max ? s : s[..max] + "…";
|
|
|
|
//protected async Task EnsureSuccess(HttpResponseMessage res)
|
|
//{
|
|
// if (res.IsSuccessStatusCode) return;
|
|
|
|
// string body;
|
|
// try { body = await res.Content.ReadAsStringAsync().ConfigureAwait(false); }
|
|
// catch { body = "<unable to read body>"; }
|
|
|
|
// LogFailure(res, body);
|
|
|
|
// Throw a richer exception(you can customize per API)
|
|
// throw new HttpRequestException(
|
|
// $"Request to {res.RequestMessage?.RequestUri} failed: {(int)res.StatusCode} {res.ReasonPhrase}. Body: {Truncate(body, 1000)}",
|
|
// null,
|
|
// res.StatusCode);
|
|
//}
|
|
} |