AstroWay/api v2.204.2 · ko
모든 시스템 정상 작동 중

X-Cache header: 가시적인 cache-status를 통한 클라이언트 통합 최적화

각 API 응답은 이제 X-Cache: MISS | HIT | BYPASS 를 포함합니다 - 클라이언트는 요청이 처음부터 계산되었는지, 캐시에서 가져왔는지 즉시 확인할 수 있습니다. 이는 /dashboard/usage 의 cache hit % 열을 열어주며 guesswork 없이 통합을 최적화할 수 있게 합니다.

Server-side 캐시는 오래전부터 작동했어 - 같은 date/time/lat/lon에 대한 결정론적 차트 계산이 캐시에서 반환되고, 다시 계산하지 않아. 하지만 클라이언트는 이를 보지 못했어. 대시보드의 “cache hit %” 열은 – 를 표시했는데, 백엔드가 cache-outcome을 응답이 아니라 내부 메트릭에 기록했기 때문이야.

이제 모든 response는 세 가지 헤더 중 하나를 포함해:

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

작은 변화야 - 헤더 하나와 api_request_log에 한 컬럼이 추가됐지만, 이전에 눈에 보이지 않던 다양한 최적화 가능성을 열어줘.

Terminal window
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

같은 요청 본문으로 두 번째 호출을 수행해:

Terminal window
# X-Cache: HIT

/v1/transits/now 같은 엔드포인트(동적 시간)의 경우 - X-Cache: BYPASS야, 결과가 현재 Date.now()에 의존하니 캐시할 의미가 없어.

어떤 엔드포인트가 무엇을 반환하는지

섹션 제목: “어떤 엔드포인트가 무엇을 반환하는지”

모든 엔드포인트가 캐시되는 건 아니야 - 의도된 설계야. 구분:

  • 결정론적 차트 계산 (/v1/chart, /v1/houses, /v1/aspects, /v1/synastry, /v1/dasha/*, /v1/vargas/*) - 완전히 캐시돼. 일반적인 MISS → HIT 패턴이야.
  • 시간 의존 (/v1/transits/now, /v1/horoscope/today, /v1/moon/phase-now) - BYPASS. 캐시는 분이 끝날 때까지만 정확할 수 있어서, 아예 캐시하지 않는 게 더 쉬워.
  • AI 생성 콘텐츠 (/v1/horoscope/personal, /v1/interpret/*): BYPASS. 같은 프롬프트라도 LLM 응답은 결정론적이지 않으니, 캐시 = 무작위성을 고정하는 것과 같아.
  • 렌더 엔드포인트 (/v1/render/*): 일부는 MISS/HIT, 큰 payload(예: 500 포인트의 eclipse-path)를 받는 경우는 BYPASS.

특정 엔드포인트에 대한 마커는 response에서 바로 볼 수 있어 - 문서를 읽지 않아도 캐시되는지 알 수 있지.

가격 영향: 캐시된 요청도 여전히 비용이 들어

섹션 제목: “가격 영향: 캐시된 요청도 여전히 비용이 들어”

이게 가장 중요한 포인트야 - 캐시된 요청도 같은 tier에서 credits를 차감해, MISS와 동일하게. 이유는:

  1. 우리 가격은 엔드포인트의 비즈니스 가치에 맞춰 조정돼, CPU 비용이 아니라. /v1/chart는 차트를 다시 계산하든 캐시에서 가져오든 같은 비용이야 - 클라이언트는 같은 차트를 받으니까.
  2. 투명성. 한 user-base는 MISS에, 다른 쪽은 HIT에 비용을 내는 상황을 원하지 않아 (이론적으로 “캐시가 운이 좋았다”는 이유). 가격이 예측 가능해야 해.
  3. 캐시 인프라: 이것은 부가가치가 아니라 인프라야. 우리는 tier에 포함해서 보조금처럼 제공하고 있어.

하지만 이게 X-Cache가 가격 컨텍스트에서 무의미하다는 뜻은 아니야 - 클라이언트에게 아키텍처적 가능성을 보여주는 역할을 해 (다음 섹션 참고).

클라이언트 측에서 어떻게 할까

섹션 제목: “클라이언트 측에서 어떻게 할까”

네 가지 실용적인 패턴:

1. MISS에 대한 클라이언트 측 캐시 레이어

섹션 제목: “1. MISS에 대한 클라이언트 측 캐시 레이어”

요청에 X-Cache: MISS가 표시되고, 같은 시나리오(예: 같은 사람의 출생 차트)에서 반복될 수 있다면 Redis/Memcached/IndexedDB에 로컬로 캐시해. 서버 측 캐시는 TTL과 evict 정책이 있어서, 제어된 TTL을 가진 클라이언트 레이어가 불필요한 credit 차감을 피할 수 있어.

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

서비스가 동일한 birth-data에 대한 대량 요청을 받는 경우(예: 동료들이 같은 데모 데이터를 테스트하는 온보딩 캠페인), 프라미스 기반 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;
}

이렇게 하면 credits를 절감하진 못해(각 호출마다 여전히 차감됨), 하지만 동시성 급증 시 병목을 줄여줘.

제품에 의식 차트(예: 인기 있는 daily-horoscope 별자리)가 있다면, 스케줄된 cron으로 미리 워밍해. 첫 호출은 MISS, evict 되기 전까지는 모두 HIT. 사용자는 서브초 응답을 받게 돼.

4. 대시보드 인사이트: 어디서 과다 지불하고 있나요

섹션 제목: “4. 대시보드 인사이트: 어디서 과다 지불하고 있나요”

새로운 cache hit % 컬럼이 /dashboard/usage에서 엔드포인트별로 보여줘:

  • HIT% = 90+ - 엔드포인트가 잘 캐시돼, 같은 차트가 여러 번 전송될 가능성이 높아. 클라이언트 측 dedupe(#2)를 고려해.
  • HIT% = 0 그리고 BYPASS: 엔드포인트가 설계상 캐시되지 않아 (transits/now, AI). 정상적인 거야.
  • HIT% = 50% 그리고 MISS: 절반은 고유 파라미터, 절반은 반복 호출. 클라이언트 측 캐시를 적용할 가치가 있어.
  • HIT% 낮고 엔드포인트가 결정론적: 의심스러워. 클라이언트가 payload에 무작위 필드(timestamp, request-id 등)를 추가해 캐시 키를 깨뜨리지 않는지 확인해.

기술 구현: 궁금한 사람들을 위해

섹션 제목: “기술 구현: 궁금한 사람들을 위해”

Tracking은 api_request_log.cache_status에 한 컬럼을 추가해(enum: MISS|HIT|BYPASS, migration 030). 이 컬럼은 캐시 조회 결정을 내리는 동일한 핸들러에서 채워지니, DB에 추가 쿼리를 하지 않아.

GET /v1/me/usage/endpoints는 이제 각 엔드포인트에 대해 null 대신 실제 cache_hit_pct를 반환해. SDK 메서드 client.me.usage.endpoints()도 자동으로 해당 필드를 받게 되고(다음 codegen 릴리즈에 타입 포함).

Cache instrumentation은 “no caching”과 “full edge cache” 사이의 중간 최적화 레벨을 열어줘. 로드맵에 다음과 같은 개선이 예정돼:

  • 캐시된 엔드포인트에 실제 TTL을 담은 Cache-Control 응답 헤더 - 클라이언트 측 CDN/프록시 캐시를 가능하게 해.
  • If-None-Match ETags: 전체 payload 없이 반복적인 MISS 검증.
  • 대시보드에 사용자별 캐시 통계와 invalidate 기능 제공(예: birth-time 수정 후 특정 차트를 강제로 재계산).

문서 - /docs/api/ → Performance & Caching. 구체적인 X-Cache 레퍼런스는 각 엔드포인트의 headers 섹션에 있어.

MakSeong · AstroWay

AstroWay API를 만들고 있어: Swiss Ephemeris를 순수 REST로 감싸고, 실제로 중요한 지루한 세부사항을 기록합니다.

// 이걸로 빌드해

Solar Fire에 사용된 것과 동일한 Swiss Ephemeris - 단 4줄의 코드로.

카드 없이 무료 키. 첫 결제 전까지 월 5,000 API 호출.

더 많은 블로그 글 모든 글 보기 →

Ephemeris 2026-07-19

우리가 정확성을 제어하는 방법: CI vs swetest 및 NASA

아스트로-API의 정확성은 하나의 에프메르에디드 리팩토링으로 쉽게 저하됩니다. CI의 보호를 분석합니다: 앱과 API를 위한 하나의 스위스 에프메르에디스 핵심, 수백의 스냅샷이 동결된 표준 맵에, swetest CGI, Kerykeion, Prokerala 및 NASA의 어두움 카탈로그에 대한 각 PR의 삼각화.

Engineering 2026-07-15

세 개의 공식 SDK: TypeScript, Python, PHP, 원시 curl 대신

원시 HTTP는 작동하지만, 타이핑된 클라이언트는 시간을 절약합니다: 경로 자동 완성, 요청 및 응답 유형, 408/409/429/5xx에 대한 내장된 재시도 및 스테인리스 스타일 오류 계층 구조. 세 개의 공식 SDK - @astroway/sdk (npm), astroway (PyPI), astroway/sdk (Packagist) - 및 하나의 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.