using Application.Abstractions.Messaging; using Application.Abstractions.Cache; using Application.Abstractions.Crypto; namespace Application.Features.Api.Crypto.Ticker.GetDetail; public sealed class Handler(IUpbitClient upbit, ICacheService cache) : IQueryHandler { private static readonly TimeSpan _cacheExpiry = TimeSpan.FromSeconds(10); public async Task Handle(Query request, CancellationToken ct) { var cacheKey = CacheKeys.CryptoTickerDetail(request.Market); // 캐시 확인 var cached = await cache.GetAsync(cacheKey, ct); if (cached is not null) { return cached; } // Upbit REST API 호출 var tickers = await upbit.GetTickersAsync([request.Market], ct); if (tickers.Count == 0) { return new Response(request.Market, "", "", "", "", 0, 0, 0, 0, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, "", 0); } var t = tickers[0]; var response = new Response( t.Market, t.TradeDate, t.TradeTime, t.TradeDateKst, t.TradeTimeKst, t.TradeTimestamp, t.OpeningPrice, t.HighPrice, t.LowPrice, t.TradePrice, t.PrevClosingPrice, t.Change, t.ChangePrice, t.ChangeRate, t.SignedChangePrice, t.SignedChangeRate, t.TradeVolume, t.AccTradePrice, t.AccTradePrice24h, t.AccTradeVolume, t.AccTradeVolume24h, t.Highest52WeekPrice, t.Highest52WeekDate, t.Lowest52WeekPrice, t.Lowest52WeekDate, t.Timestamp ); // Redis 캐시 저장 (10초) await cache.SetAsync(cacheKey, response, _cacheExpiry, ct); return response; } }