AstroWay/api v2.204.2 · ja
すべてのシステムが正常です

X-Cache header: cache-status の可視化によるクライアント統合の最適化

各 response API は今では X-Cache: MISS | HIT | BYPASS を含み、クライアントはすぐにリクエストがゼロから計算されたか、キャッシュから取得されたかを確認できます。これにより、/dashboard/usage に cache hit % 列が表示され、guesswork なしでインテグレーションを最適化できるようになります。

サーバーサイドキャッシュは昔から機能していた - 同じ date/time/lat/lon の決定的なチャート計算は、再計算されずにキャッシュから返される。しかし クライアントはこれを見えていなかった。ダッシュボードの「cache hit %」列は – と表示されていた。なぜならバックエンドは cache-outcome を内部メトリクスに記録していたが、レスポンスには含めていなかったからだ。

今では各レスポンスに次の3つのヘッダーのうちいずれかが含まれる:

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

これは小さな変更 - ヘッダーと api_request_log の1つのカラムを追加しただけだが、これにより以前は盲点だった最適化の一クラスが開かれる。

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

同じリクエストボディで2回実行してみて:

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。キャッシュはせいぜい1分間しか正しくないため、そもそもキャッシュしないほうが簡単だ。
  • AI生成コンテンツ (/v1/horoscope/personal, /v1/interpret/*) - BYPASS。LLMの回答は同じプロンプトでも決定的ではないため、キャッシュするとランダム性を固定してしまう。
  • レンダーエンドポイント (/v1/render/*) - 一部は MISS/HIT、大きなペイロード(たとえば500点の eclipse-path)を受け取るものは BYPASS。

特定のエンドポイントのマーカーはレスポンスからすぐにわかる - ドキュメントを読まずともキャッシュされるかどうかがわかる。

Pricing impact: キャッシュされたリクエストも 同じく コストがかかる

Section titled “Pricing impact: キャッシュされたリクエストも 同じく コストがかかる”

これが理解する上で最も重要な点 - キャッシュされたリクエストも MISS と同じティアで credits を引き続き消費する。理由:

  1. 私たちの価格設定は CPU コストではなくエンドポイントのビジネス価値に基づいて校正されている。/v1/chart はチャートを再計算してもキャッシュから返しても同じコストで、クライアントは同じチャートを得る。
  2. 透明性。あるユーザーベースが MISS に対して支払い、別のユーザーベースが HIT に対して支払う状況(理論的には「キャッシュの運」による)は避けたい。価格は予測可能であるべきだ。
  3. キャッシュインフラは付加価値ではなくインフラであり、私たちはそれをティア内で補填している。

しかしこれは X-Cache が価格文脈で意味がないということではない - これはクライアントに対して アーキテクチャの可能性 を示している(次のセクション参照)。

4つの実践的なパターン:

1. MISS 用のクライアントサイドキャッシュレイヤー

Section titled “1. MISS 用のクライアントサイドキャッシュレイヤー”

X-Cache: MISS が表示されるリクエストで、シナリオによって繰り返される可能性がある(同じ人物のネイタルチャートなど)場合は、Redis/Memcached/IndexedDB にローカルでキャッシュせよ。サーバーサイドキャッシュは TTL と evict ポリシーを持っている - コントロール可能な TTL を持つクライアントサイドレイヤーなら、不要な 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. バックエンドでのバッチ+デデュプ

Section titled “2. バックエンドでのバッチ+デデュプ”

あなたのサービスが同じ birth-data に対する大量のリクエストを受け取る場合(オンボーディングキャンペーンで同僚が同じデモデータをテストしているなど)、プロミスベースのデデュプを使え:

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

これはクレジットを節約しない(各呼び出しは依然としてカウントされる)が、同時アクセスのスパイクによるボトルネックを解消する。

3. クリティカルパスのプリウォーム

Section titled “3. クリティカルパスのプリウォーム”

製品に rituel チャート(人気のデイリー占星術サインなど)がある場合は、スケジュールされた cron でプリウォームせよ。その日の最初の呼び出しは MISS、evict までのその後の呼び出しはすべて HIT。ユーザーはサブセカンドのレスポンスを得る。

4. ダッシュボードインサイト: どこで過剰支払いしているか

Section titled “4. ダッシュボードインサイト: どこで過剰支払いしているか”

/dashboard/usage のエンドポイントごとの新しい「cache hit %」列は次のように示す:

  • HIT% = 90+ - エンドポイントはよくキャッシュされており、おそらく同じチャートが複数回送信されている。クライアントサイドデデュプ(#2)を検討せよ。
  • HIT% = 0 かつ BYPASS: エンドポイントは設計上キャッシュされない(transits/now, AI など)。これは正常だ。
  • HIT% = 50% かつ MISS: リクエストの半分は一意のパラメータ、残り半分は繰り返し。クライアントサイドキャッシュは価値がある。
  • HIT% が低い + エンドポイントが決定的: 疑わしい。クライアントがペイロードにランダムなフィールド(タイムスタンプや request-id など)を追加してキャッシュキーを汚していないか確認せよ。

トラッキングは api_request_log.cache_status という1つのカラムを追加するだけ(enum: MISS|HIT|BYPASS、マイグレーション 030)。このカラムはキャッシュルックアップの決定を行う同じハンドラーから設定されるため、DB への追加クエリは行われない。

GET /v1/me/usage/endpoints は теперь、あなたの履歴の各エンドポイントに対して null ではなく実際の cache_hit_pct を返す。SDK メソッド client.me.usage.endpoints() はこのフィールドを自動的に取得する(型は次の codegen リリースで提供される)。

キャッシュインストルメンテーションは「no caching」と「full edge cache」の間の中間最適化レベルを開く。ロードマップの次の手順:

  • Cache-Control レスポンスヘッダーにキャッシュされたエンドポイントの実際の TTL を含める - クライアント側の CDN/proxy キャッシュを可能にする。
  • If-None-Match ETags: レスポンスにフルペイロードを含めずに MISS の再チェックを行う。
  • ダッシュボードでの per-user キャッシュ統計、無効化のオプション付き(例: birth-time の修正後に特定のチャートを強制的に再計算)。

ドキュメント - /ドキュメント/api/ → パフォーマンス & キャッシング。X-Cache の具体的なリファレンスは各エンドポイントのヘッダー セクションにある。

MakSeong · AstroWay

AstroWay API を作っている: Swiss Ephemeris を純粋な REST にラップし、実際に重要な退屈な詳細を書いています。

// この上に構築

Solar Fireと同じSwiss Ephemeris - 4行のコードで。

無料のキー(カード不要)。最初の支払いまでに月5,000回の呼び出し。

より多くのブログ →

Ephemeris 2026-07-19

精度をどう守っているか:swetest と NASA に対する CI

天文暦のリファクタリング一つで、占星術 API の精度は簡単に落ちます。その防ぎ方を解説します。アプリと API で共有する一つの Swiss Ephemeris コア、基準チャートに対する数百の固定スナップショット、そして各 PR を swetest CGI、Kerykeion、Prokerala、NASA の日食・月食カタログと照合する三角測量。

Engineering 2026-07-15

3つの公式SDK: TypeScript、Python、PHP - 生のcurlの代わりに

生のHTTPは動作しますが、型付けされたクライアントは時間を節約します: パスの自動補完、リクエストとレスポンスの型、408/409/429/5xx用の組み込みリトライ、Stainlessスタイルのエラーヒエラルキー。3つの公式SDK - @astroway/sdk (npm)、astroway (PyPI)、astroway/sdk (Packagist) - と、それらが1つの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.