AstroWay/api v2.204.2 · pl
wszystkie systemy w normie

X-Cache header: widoczny cache-status do optymalizacji integracji klientów

Każda odpowiedź API teraz zawiera nagłówek X-Cache: MISS | HIT | BYPASS - klient od razu widzi, czy żądanie zostało obliczone od zera, czy pobrane z pamięci podręcznej. To otwiera kolumnę cache hit % w /dashboard/usage i pozwala zoptymalizować integrację bez zgadywania.

Cache po stronie serwera działał u nas od dawna – zdeterminowane obliczenie wykresu dla tej samej daty/czasu/szerokości/długości geograficznej jest zwracane z cache’u, a nie obliczane od nowa. Ale klient tego nie widział. W panelu kontrolnym kolumna „cache hit %” pokazywała –, ponieważ backend logował wynik cache’owania do wewnętrznej metryki, a nie do odpowiedzi.

Teraz każda odpowiedź zawiera jeden z trzech nagłówków:

X-Cache: HIT # обслужено з кешу
X-Cache: MISS # обчислено з нуля, результат збережено
X-Cache: BYPASS # не кешується за дизайном

To mała zmiana – nagłówek plus jedna kolumna w api_request_log – ale otwiera całą klasę optymalizacji, które wcześniej były martwym punktem.

Okno terminala
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: MISS

Wykonaj drugi raz z tym samym ciałem zapytania:

Okno terminala
# X-Cache: HIT

Dla endpointów typu /v1/transits/now (czas dynamiczny) – X-Cache: BYPASS, ponieważ wynik zależy od bieżącego Date.now() i cache’owanie nie ma sensu.

Nie wszystkie endpointy są cache’owane – i to celowo. Podział:

  • Zdeterminowane obliczenia wykresów (/v1/chart, /v1/houses, /v1/aspects, /v1/synastry, /v1/dasha/*, /v1/vargas/*) – są w pełni cache’owane. Oczekiwany wzorzec MISS → HIT.
  • Time-dependent (/v1/transits/now, /v1/horoscope/today, /v1/moon/phase-now) – BYPASS. Cache mógłby być poprawny tylko do końca minuty, dlatego prościej jest w ogóle nie cache’ować.
  • AI-generated content (/v1/horoscope/personal, /v1/interpret/*): BYPASS. Odpowiedzi LLM nie są zdeterminowane nawet dla tego samego promptu, cache’owanie = utrwalanie losowości.
  • Render endpoints (/v1/render/*): MISS/HIT dla niektórych, BYPASS dla tych, które przyjmują duże payloady (ścieżka zaćmienia z 500 punktami).

Wskaźnik dla konkretnego endpointu jest widoczny od razu w odpowiedzi – nie musisz czytać dokumentacji, aby zrozumieć, czy jest cache’owany, czy nie.

Wpływ na ceny: cache’owane zapytania nadal kosztują

Dział zatytułowany „Wpływ na ceny: cache’owane zapytania nadal kosztują”

To najważniejsza rzecz do zrozumienia – cache’owane zapytania nadal odejmują kredyty na tym samym poziomie (tier), co MISS. Dlaczego:

  1. Nasze ceny są skalibrowane na wartość biznesową endpointu, a nie na koszt CPU. /v1/chart kosztuje tyle samo, niezależnie od tego, czy wykres został obliczony od nowa, czy pochodzi z cache’u – klient otrzymał ten sam wykres.
  2. Przejrzystość. Nie chcemy sytuacji, w której jedna baza użytkowników płaci za MISS, a inna za HIT (teoretycznie z powodu „szczęścia z cache’em”). Ceny są przewidywalne.
  3. Infrastruktura cache’u: to infrastruktura, a nie wartość dodana. Subwencjonujemy ją w ramach tieru.

Ale to nie znaczy, że X-Cache jest bez znaczenia w kontekście cen – widocznie pokazuje możliwości architektoniczne dla klienta (patrz następna sekcja).

Cztery praktyczne wzorce:

Jeśli widzisz X-Cache: MISS dla zapytania, które w scenariuszu może się powtórzyć (np. mapa urodzeniowa tej samej osoby), cache’uj lokalnie w Redis/Memcached/IndexedDB. Cache po stronie serwera ma u nas TTL i politykę usuwania (evict policy) – Twoja warstwa kliencka z kontrolowanym TTL pozwoli uniknąć zbędnych odjęć kredytów.

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;
}

Jeśli Twój serwis przyjmuje masowe zapytania o te same dane urodzeniowe (kampania onboardingowa, gdzie koledzy testują tymi samymi danymi demo), użyj deduplikacji opartej na Promise:

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 nie zaoszczędzi kredytów (każde wywołanie i tak jest naliczane), ale eliminuje zatory podczas skoków współbieżności.

Jeśli w produkcie są rytualne wykresy (popularne znaki horoskopu dziennego), wstępnie je rozgrzej za pomocą zaplanowanego crona. Pierwsze wywołanie dnia – MISS, wszystkie kolejne do momentu usunięcia z cache’u – HIT. Użytkownik otrzymuje odpowiedź w czasie poniżej sekundy.

Nowa kolumna „cache hit %” w /dashboard/usage dla każdego endpointu pokazuje:

  • HIT% = 90+ – endpoint jest dobrze cache’owany, prawdopodobnie ten sam wykres jest przesyłany kilka razy. Rozważ deduplikację po stronie klienta (#2).
  • HIT% = 0 i BYPASS: endpoint nie jest cache’owany z założenia (transits/now, AI). To normalne.
  • HIT% = 50% i MISS: połowa zapytań zawiera unikalne parametry, połowa: powtórzenia. Warto rozważyć cache po stronie klienta.
  • Niski HIT% + zdeterminowany endpoint: podejrzane. Sprawdź, czy Twój klient nie dodaje losowych pól do payloadu (timestamps, request-id), które zaśmiecają klucz cache’u.

Śledzenie kosztuje jedną kolumnę w api_request_log.cache_status (enum: MISS|HIT|BYPASS, migracja 030). Kolumna jest wypełniana z tego samego handlera, który podejmuje decyzję o wyszukiwaniu w cache’u – dodatkowe zapytanie do bazy danych nie jest wykonywane.

GET /v1/me/usage/endpoints teraz zwraca rzeczywiste cache_hit_pct zamiast null dla każdego endpointu w Twojej historii. Metoda SDK client.me.usage.endpoints() automatycznie otrzyma to pole (typy w następnym wydaniu codegen).

Instrumentacja cache’u otwiera pośredni poziom optymalizacji między „brakiem cache’owania” a „pełnym cache’em brzegowym”. Następne punkty w roadmapie:

  • Nagłówek odpowiedzi Cache-Control z rzeczywistym TTL dla cache’owanych endpointów – umożliwi cache CDN/proxy po stronie klienta
  • If-None-Match ETags: ponowne sprawdzenia MISS bez pełnego payloadu w odpowiedzi
  • Statystyki cache’u dla poszczególnych użytkowników w panelu kontrolnym z możliwością unieważnienia (na przykład, wymuszone ponowne obliczenie określonego wykresu po poprawieniu czasu urodzenia)

Dokumentacja – /docs/api/ → Performance & Caching. Konkretne odniesienie do X-Cache – w sekcji nagłówków każdego endpointu.

MakSeong · AstroWay

Robię AstroWay API: pakuję Swiss Ephemeris w czysty REST i piszę o nudnych detalach, które naprawdę są ważne.

// zbuduj na tym

Ten sam Swiss Ephemeris, co w Solar Fire - w 4 liniach kodu.

Darmowy klucz bez karty. 5 000 wywołań miesięcznie do pierwszej płatności.

Więcej z bloga wszystkie posty →

Ephemeris 2026-07-19

Jak utrzymujemy dokładność pod kontrolą: CI przeciw swetest i NASA

Dokładność w astro-API łatwo degraduje od jednego refactoringu ephemerid. Rozmawiamy o ochronie: jedno jądro Swiss Ephemeris dla aplikacji i API, setki zamrożonych snapshotów na etalonicznych mapach i triangulacja każdego PR przeciw swetest CGI, Kerykeion, Prokerala oraz katalogu zaciemnień NASA.

Engineering 2026-07-15

Trzy oficjalne SDK: TypeScript, Python, PHP zamiast surowego curl

Surowy HTTP działa, ale typizowany klient oszczędza godziny: autouzupełnianie ścieżek, typy zapytań i odpowiedzi, wbudowany retry dla 408/409/429/5xx i hierarchia błędów w stylu Stainless. Przeanalizowaliśmy trzy oficjalne SDK - @astroway/sdk (npm), astroway (PyPI), astroway/sdk (Packagist) - i czym są generowane z jednego kontraktu OpenAPI.

Industry 2026-06-05

Free Astrology API: Which One Has the Best Free Tier in 2026?

A side-by-side of free tiers across the major astrology APIs - credits, request caps, card requirements - and how much you can actually build for free.