AstroWay/api v2.204.2 · pt
todos os sistemas normais

X-Cache header: cache-status visível para otimização de integrações do cliente

Cada resposta da API agora carrega X-Cache: MISS | HIT | BYPASS - o cliente vê imediatamente se o pedido foi calculado do zero ou recuperado da cache. Isto abre uma coluna de % de cache hit em /dashboard/usage e permite otimizar a integração sem adivinhações.

O cache do lado do servidor já funcionava há muito tempo - o cálculo determinístico de um mapa astral para a mesma date/time/lat/lon era devolvido do cache, em vez de ser recalculado. Mas o cliente não via isso. No dashboard, a coluna “cache hit %” mostrava – porque o backend registava o resultado do cache numa métrica interna, e não na resposta.

Agora, cada response inclui um dos três cabeçalhos:

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

Esta é uma pequena alteração - um cabeçalho mais uma coluna em api_request_log - mas abre toda uma classe de otimizações que antes eram um ponto cego.

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

Executa uma segunda vez com o mesmo corpo de pedido:

Terminal window
# X-Cache: HIT

Para endpoints como /v1/transits/now (tempo dinâmico) - X-Cache: BYPASS, porque o resultado depende do Date.now() atual e não faz sentido armazenar em cache.

Nem todos os endpoints são armazenados em cache - e isso é intencional. Distribuição:

  • Cálculos determinísticos de mapa astral (/v1/chart, /v1/houses, /v1/aspects, /v1/synastry, /v1/dasha/*, /v1/vargas/*) - são totalmente armazenados em cache. Padrão esperado: MISS → HIT.
  • Dependentes do tempo (/v1/transits/now, /v1/horoscope/today, /v1/moon/phase-now) - BYPASS. O cache só seria válido até ao final do minuto, por isso é mais simples não armazenar em cache de todo.
  • Conteúdo gerado por IA (/v1/horoscope/personal, /v1/interpret/*): BYPASS. As respostas do LLM não são determinísticas mesmo para o mesmo prompt, armazenar em cache = fixar a aleatoriedade.
  • Endpoints de renderização (/v1/render/*): MISS/HIT para alguns, BYPASS para aqueles que aceitam payloads grandes (caminho de eclipse com 500 pontos).

O marcador para um endpoint específico é visível diretamente na response - não precisas de ler a documentação para entender se é armazenado em cache ou não.

Esta é a coisa mais importante a entender - pedidos em cache continuam a deduzir créditos no mesmo tier que um MISS. Porquê:

  1. O nosso pricing é calibrado para o valor de negócio do endpoint, não para o custo de CPU. O /v1/chart custa o mesmo, quer o mapa tenha sido recalculado, quer tenha vindo do cache - o cliente recebeu o mesmo mapa astral.
  2. Transparência. Não queremos uma situação em que uma base de utilizadores paga por um MISS e outra por um HIT (teoricamente por “sorte com o cache”). Pricing previsível.
  3. Infraestrutura de cache: é infraestrutura, não um valor acrescentado. Nós subsidiamos isso no tier.

Mas isso não significa que o X-Cache seja sem sentido no contexto do pricing - ele mostra visivelmente as oportunidades arquitetónicas para o cliente (vê a próxima secção).

Quatro padrões práticos:

Se vires X-Cache: MISS para um pedido que pode ser repetido no cenário (mapa astral da mesma pessoa), armazena-o localmente em Redis/Memcached/IndexedDB. O nosso cache do lado do servidor tem um TTL e uma política de evict - a tua camada de cliente com um TTL controlado evitará deduções de crédito desnecessárias.

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

Se o teu serviço aceita pedidos em massa para os mesmos birth-data (campanha de onboarding onde os colegas testam com os mesmos dados de demonstração), usa um dedupe baseado em 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;
}

Isto não poupará créditos (cada chamada ainda conta), mas elimina congestionamentos durante picos de concurrency.

Se o produto tem mapas astrais rituais (signos populares de horóscopo diário), faz um pre-warm deles com um cron agendado. A primeira chamada do dia é um MISS, todas as seguintes até ao evict são HIT. O utilizador recebe uma response em subsegundos.

A nova coluna “cache hit %” em /dashboard/usage por endpoint mostra:

  • HIT% = 90+ - o endpoint é bem armazenado em cache, provavelmente o mesmo mapa astral é enviado várias vezes. Considera o client-side dedupe (#2).
  • HIT% = 0 e BYPASS: o endpoint não é armazenado em cache por design (transits/now, AI). Isso é normal.
  • HIT% = 50% e MISS: metade dos pedidos tem parâmetros únicos, metade são repetições. Client-side cache que vale a pena.
  • HIT% baixo + endpoint determinístico: suspeito. Verifica se o teu cliente não está a adicionar fields aleatórios ao payload (timestamps, request-id), que entopem a chave do cache.

O tracking custa uma coluna em api_request_log.cache_status (enum: MISS|HIT|BYPASS, migration 030). A coluna é preenchida a partir do mesmo handler que toma a decisão de cache-lookup - não é feita uma consulta adicional à DB.

O GET /v1/me/usage/endpoints agora devolve o cache_hit_pct real em vez de null para cada endpoint no teu histórico. O método client.me.usage.endpoints() do SDK receberá o campo automaticamente (tipos na próxima versão do codegen).

A instrumentação do cache abre um nível intermédio de otimizações entre “no caching” e “full edge cache”. Os próximos passos no roadmap:

  • Cabeçalho de response Cache-Control com TTL real para endpoints em cache - permitirá CDN/proxy-cache do lado do cliente
  • If-None-Match ETags: verificações MISS repetidas sem o payload completo na response
  • Estatísticas de cache por utilizador no dashboard com a possibilidade de invalidate (por exemplo, recalcular forçadamente um certain chart após a correção da birth-time)

Documentação - /docs/api/ → Performance & Caching. Referência específica do X-Cache - na secção de headers de cada endpoint.

MakSeong · AstroWay

Crio a API AstroWay: envolvo o Swiss Ephemeris em REST puro e escrevo sobre os detalhes aborrecidos que realmente importam.

// construa sobre isso

O mesmo Swiss Ephemeris que no Solar Fire - em 4 linhas de código.

Chave gratuita sem cartão. 5 000 chamadas por mês até o primeiro pagamento.

Mais do blog todas as postagens →

Ephemeris 2026-07-19

Como mantemos a precisão sob controle: CI versus swetest e NASA

A precisão da API astronômica pode degradar-se facilmente após uma refatorização dos ephémérides. Desvendamos a defesa: um núcleo Swiss Ephemeris para o app e a API, centenas de snapshots congelados em cartas de referência e triângulos de cada PR contra swetest CGI, Kerykeion, Prokerala e o catálogo de eclipses da NASA.

Engineering 2026-07-15

Três SDKs oficiais: TypeScript, Python, PHP em vez de curl bruto

HTTP bruto funciona, mas um cliente tipificado economiza horas: autocompletamento de caminhos, tipos de pedido e resposta, retry incorporado para 408/409/429/5xx e hierarquia de erros no estilo Stainless. Vamos analisar os três SDKs oficiais - @astroway/sdk (npm), astroway (PyPI), astroway/sdk (Packagist) - e como são gerados a partir do mesmo contrato 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.