using Application.Abstractions.Messaging; using Application.Abstractions.Cache; using Application.Abstractions.Crypto; namespace Application.Features.Api.Crypto.Orderbook.Get; 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 cacheKey = CacheKeys.CryptoOrderbook(request.Market); // 캐시 확인 var cached = await cache.GetAsync(cacheKey, ct); if (cached is not null) { return cached; } // Upbit REST API 호출 var orderbooks = await upbit.GetOrderbookAsync([request.Market], ct); if (orderbooks.Count == 0) { return new Response(0, 0, [], 0, 0); } var o = orderbooks[0]; var response = new Response( o.TotalAskSize, o.TotalBidSize, [..o.OrderbookUnits.Select(u => new Response.Unit( u.AskPrice, u.BidPrice, u.AskSize, u.BidSize ))], o.Timestamp, o.Level ); // Redis 캐시 저장 (5초) await cache.SetAsync(cacheKey, response, _cacheExpiry, ct); return response; } }