using Application.Abstractions.Messaging; using Application.Abstractions.Cache; using Application.Abstractions.Crypto; namespace Application.Features.Api.Crypto.Trade.GetRecent; public sealed class Handler(IUpbitClient upbit, ICacheService cache) : IQueryHandler { private static readonly TimeSpan _cacheExpiry = TimeSpan.FromSeconds(5); public async Task Handle(Query request, CancellationToken ct) { var count = Math.Clamp(request.Count, 1, 100); var cacheKey = CacheKeys.CryptoTrades(request.Market); // 캐시 확인 var cached = await cache.GetAsync>(cacheKey, ct); if (cached is { Count: > 0 }) { return new Response(cached); } // Upbit REST API 호출 var trades = await upbit.GetTradesAsync(request.Market, count, ct); var items = trades .Select(t => new Response.TradeItem( t.Timestamp, t.TradePrice, t.TradeVolume, t.PrevClosingPrice, t.ChangePrice, t.AskBid, t.SequentialId )) .ToList(); // Redis 캐시 저장 (5초) if (items.Count > 0) { await cache.SetAsync(cacheKey, items, _cacheExpiry, ct); } return new Response(items); } }