V13-FE-011: finalize search list layout slice
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
|
||||
namespace Kbx.Shared.Providers;
|
||||
|
||||
public sealed class KrxOpenApiAdapter(HttpClient http, IKbxProviderSecretStore secrets) : IKbxExternalProviderAdapter
|
||||
{
|
||||
public string ProviderId => "provider.krx.openapi";
|
||||
|
||||
public async Task<KbxProviderResult<string>> InvokeApprovedServiceAsync(KrxApprovedServiceRequest request, CancellationToken ct)
|
||||
{
|
||||
if (!request.ServiceUri.IsAbsoluteUri || request.ServiceUri.Scheme != Uri.UriSchemeHttps || !request.ServiceUri.Host.EndsWith(".krx.co.kr", StringComparison.OrdinalIgnoreCase))
|
||||
return new(KbxProviderResultKind.PermanentFailure, Code:"KRX_SERVICE_URL_NOT_APPROVED", Message:"KRX 승인 서비스의 HTTPS URL만 사용할 수 있습니다.");
|
||||
if (request.Method != HttpMethod.Get && request.Method != HttpMethod.Post)
|
||||
return new(KbxProviderResultKind.PermanentFailure, Code:"KRX_METHOD_NOT_ALLOWED", Message:"조회성 GET/POST만 허용됩니다.");
|
||||
|
||||
var key = await secrets.GetRequiredAsync("ExternalProviders:Krx:AuthKey", ct);
|
||||
var uri = AppendQuery(request.ServiceUri, request.Query);
|
||||
using var message = new HttpRequestMessage(request.Method, uri);
|
||||
message.Headers.TryAddWithoutValidation("AUTH_KEY", key);
|
||||
if (request.Method == HttpMethod.Post && request.Body is not null)
|
||||
message.Content = new StringContent(request.Body, System.Text.Encoding.UTF8, "application/json");
|
||||
using var response = await http.SendAsync(message, HttpCompletionOption.ResponseHeadersRead, ct);
|
||||
var body = await response.Content.ReadAsStringAsync(ct);
|
||||
if (response.IsSuccessStatusCode) return new(KbxProviderResultKind.Success, body, HttpStatus:(int)response.StatusCode);
|
||||
var transient = response.StatusCode is HttpStatusCode.RequestTimeout or (HttpStatusCode)429 || (int)response.StatusCode >= 500;
|
||||
return new(transient ? KbxProviderResultKind.TransientFailure : KbxProviderResultKind.PermanentFailure, Code:$"HTTP_{(int)response.StatusCode}", Message:"KRX OPEN API 호출이 실패했습니다.", HttpStatus:(int)response.StatusCode);
|
||||
}
|
||||
|
||||
private static Uri AppendQuery(Uri uri, IReadOnlyDictionary<string,string?> query)
|
||||
{
|
||||
if (query.Count == 0) return uri;
|
||||
var parts = query.Where(x => x.Value is not null).Select(x => $"{Uri.EscapeDataString(x.Key)}={Uri.EscapeDataString(x.Value!)}");
|
||||
var builder = new UriBuilder(uri) { Query = string.Join("&", parts) };
|
||||
return builder.Uri;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user