KrxCoKrHttp.cs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. using System.Net.Http.Headers;
  2. using Microsoft.Extensions.Logging;
  3. namespace Infrastructure.StockData;
  4. /// <summary>KRX OpenAPI(data-dbg.krx.co.kr) 호출 공통 — AUTH_KEY 헤더 인증 + 간단 3회 재시도 (2s/4s 백오프)</summary>
  5. internal static class KrxCoKrHttp
  6. {
  7. public const string ClientName = "KRXCoKr";
  8. /// <summary>KRX OpenAPI 인증 헤더명 (라이브 검증: 헤더 있으면 "Unauthorized API Call", 없으면 "Unauthorized Key")</summary>
  9. public const string AuthHeader = "AUTH_KEY";
  10. private const int MaxAttempts = 3;
  11. public static async Task<string> GetStringWithRetryAsync(HttpClient client, string url, string apiKey, ILogger logger, CancellationToken ct)
  12. {
  13. for (var attempt = 1; ; attempt++)
  14. {
  15. try
  16. {
  17. using var request = new HttpRequestMessage(HttpMethod.Get, url);
  18. request.Headers.TryAddWithoutValidation(AuthHeader, apiKey);
  19. request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
  20. using var response = await client.SendAsync(request, ct);
  21. response.EnsureSuccessStatusCode();
  22. return await response.Content.ReadAsStringAsync(ct);
  23. }
  24. catch (Exception ex) when (ex is not OperationCanceledException && attempt < MaxAttempts)
  25. {
  26. logger.LogWarning(ex, "[KRXCoKr] HTTP 실패 — 재시도 {Attempt}/{Max}", attempt, MaxAttempts);
  27. await Task.Delay(TimeSpan.FromSeconds(2 * attempt), ct);
  28. }
  29. }
  30. }
  31. }