Server‑side cache u nás fungoval dlouho – determinovaný výpočet chartu pro stejné date/time/lat/lon se vrací z cache, místo aby se počítal znovu. Ale klient to neviděl. V dashboardu sloupec „cache hit %“ ukazoval –, protože backend logoval cache‑outcome do vnitřní metriky, ne do odpovědi.
Nyní každá response nese jeden ze tří hlaviček:
X-Cache: HIT # обслужено з кешуX-Cache: MISS # обчислено з нуля, результат збереженоX-Cache: BYPASS # не кешується за дизайномJe to malá změna – hlavička plus jeden sloupec v api_request_log – ale otevírá celou třídu optimalizací, které dříve byly slepým místem.
Jak to funguje: příklad
Sekce “Jak to funguje: příklad”curl -I -X POST https://api.astroway.info/v1/chart \ -H "X-Api-Key: aw_live_..." \ -H "Content-Type: application/json" \ -d '{ "date": "1990-05-15", "time": "14:30:00", "timezoneOffset": 3, "latitude": 50.45, "longitude": 30.52 }' | grep -i x-cache# X-Cache: MISSSpusťte podruhé se stejným tělem požadavku:
# X-Cache: HITPro endpointy typu /v1/transits/now (dynamický čas) – X-Cache: BYPASS, protože výsledek závisí na aktuálním Date.now() a nemá smysl cacheovat.
Které endpointy co vracejí
Sekce “Které endpointy co vracejí”Ne všechny endpointy jsou cachovány – a je to úmyslné. Rozdělení:
- Determinované výpočty chartu (
/v1/chart,/v1/houses,/v1/aspects,/v1/synastry,/v1/dasha/*,/v1/vargas/*) – jsou plně cachovány. Očekávaný pattern MISS → HIT. - Time-dependent (
/v1/transits/now,/v1/horoscope/today,/v1/moon/phase-now) –BYPASS. Cache by mohl být správný jen do konce minuty, takže je jednodušší vůbec necacheovat. - AI-generated content (
/v1/horoscope/personal,/v1/interpret/*):BYPASS. Odpovědi LLM nejsou deterministické ani na stejný prompt, cacheovat = zachytit náhodnost. - Render endpoints (
/v1/render/*):MISS/HITpro některé,BYPASSpro ty, které přijímají velké payloady (eclipse-path se 500 body).
Marker na konkrétní endpoint je vidět hned v response – nemusíš číst dokumentaci, abys pochopil, jestli se cacheuje nebo ne.
Pricing impact: cachované požadavky přesto stojí
Sekce “Pricing impact: cachované požadavky přesto stojí”To je nejdůležitější věc k pochopení – cachované požadavky stále odečítají kredity ze stejného tieru jako MISS. Proč:
- Pricing u nás je kalibrován na business value endpointu, ne na CPU‑cost.
/v1/chartstojí stejně, ať se chart počítal znovu, nebo přišel z cache – klient dostal stejný chart. - Transparentnost. Nechceme situaci, kdy jedna user‑base platí za MISS a druhá za HIT (teoreticky kvůli „štěstu s cache“). Pricing je předvídatelný.
- Cache infrastructure: je to infra, ne value‑add. Subvencujeme ji v tieru.
Ale to neznamená, že X-Cache je v pricing kontextu bezvýznamný – zjevně ukazuje architektonické možnosti pro klienta (viz následující sekce).
Co s tím dělat na klientské straně
Sekce “Co s tím dělat na klientské straně”Čtyři praktické patterny:
1. Client‑side cache layer pro MISS
Sekce “1. Client‑side cache layer pro MISS”Pokud vidíš X-Cache: MISS pro požadavek, který se může opakovat (nativní karta téže osoby), cacheuj lokálně v Redis/Memcached/IndexedDB. Server‑side cache u nás má TTL a evict policy – tvá klientská vrstva s kontrolovaným TTL se vyhne zbytečným credit‑deduct.
import { Astroway } from "@astroway/sdk";
const cache = new Redis();const client = new Astroway({ apiKey: process.env.ASTROWAY_KEY, // optional: hook on response headers onResponse(req, res) { const cacheStatus = res.headers["x-cache"]; metrics.increment(`astroway.cache.${cacheStatus.toLowerCase()}`); },});
async function getChart(input: ChartInput) { const cacheKey = `chart:${hashChart(input)}`; const cached = await cache.get(cacheKey); if (cached) return JSON.parse(cached);
const chart = await client.chart.create(input); await cache.set(cacheKey, JSON.stringify(chart), "EX", 86400); return chart;}2. Batch + dedupe na backendu
Sekce “2. Batch + dedupe na backendu”Pokud tvá služba přijímá hromadné požadavky na stejné birth‑data (onboarding kampaň, kde kolegové testují stejná demo‑data), použijte promise‑based dedupe:
const inFlight = new Map<string, Promise<Chart>>();
function getChart(input: ChartInput) { const key = hashChart(input); if (inFlight.has(key)) return inFlight.get(key)!;
const promise = client.chart.create(input); inFlight.set(key, promise); promise.finally(() => inFlight.delete(key)); return promise;}To neuloží kredity (každé volání se i tak počítá), ale odstraňuje zácpy při concurrency‑spikech.
3. Pre‑warm kritické cesty
Sekce “3. Pre‑warm kritické cesty”Pokud má produkt rituální charty (populární daily‑horoscope znamení), pre‑warm je pomocí naplánovaného cron‑u. První volání dne – MISS, všechny následující do evictu – HIT. Uživatel dostane subsecond response.
4. Dashboard insight: kde připlácíš
Sekce “4. Dashboard insight: kde připlácíš”Nový sloupec cache hit % v /dashboard/usage podle endpointu ukazuje:
- HIT% = 90+ – endpoint se dobře cachuje, pravděpodobně se stejný chart posílá několikrát. Zvaž client‑side dedupe (#2).
- HIT% = 0 a BYPASS: endpoint není cachován designem (transits/now, AI). To je v pořádku.
- HIT% = 50% a MISS: polovina požadavků má unikátní parametry, polovina jsou opakování. Stojí za client‑side cache.
- HIT% nízký + endpoint determinovaný: podezřelé. Zkontroluj, jestli tvůj klient nepřidává náhodná pole do payloadu (timestamps, request‑id), která zaplňují cache‑klíč.
Technická implementace: pro zvědavé
Sekce “Technická implementace: pro zvědavé”Tracking stojí jeden sloupec v api_request_log.cache_status (enum: MISS|HIT|BYPASS, migration 030). Sloupec je naplněn ze stejného handleru, který rozhoduje o cache‑lookup – další dotaz do DB se neprovádí.
GET /v1/me/usage/endpoints nyní vrací reálné cache_hit_pct místo null pro každý endpoint ve tvé historii. SDK‑metoda client.me.usage.endpoints() získá pole automaticky (typy v následujícím codegen‑release).
Co dál
Sekce “Co dál”Cache instrumentation otevírá mezistupeň optimalizací mezi „no caching“ a „full edge cache“. Další kroky v roadmapě:
Cache-Controlresponse hlavička s reálným TTL pro cachované endpointy – umožní CDN/proxy‑cache na straně klientaIf-None-MatchETags: opakované MISS‑kontroly bez plného payloadu v odpovědi- Per‑user cache statistiky v dashboardu s možností invalidate (např. vynutit přepočet určitého chartu po opravě birth‑time)
Dokumentace – /docs/api/ → Performance & Caching. Konkrétní X-Cache reference – v sekci headers každého endpointu.
Stejný Swiss Ephemeris jako v Solar Fire - ve 4 řádcích kódu.
Zdarma klíč bez karty. 5 000 volání za měsíc do první platby.