🕓 Ghi chú từ 2026-04-14, cập nhật 2026-05-09. TS / Python / PHP SDK giờ đã có trên public registries -
@astroway/sdk(npm),astroway(PyPI),astroway/sdk(Packagist). Chi tiết trong changelog.
Bạn muốn tạo một ứng dụng chiêm tinh. Bắt đầu từ đâu? Trong hướng dẫn này - giải pháp và mã: từ chọn API đến triển khai sản phẩm hoạt động.
Vấn đề kiến trúc
Phần tiêu đề “Vấn đề kiến trúc”Trước khi viết code, hãy xác định: tính toán trên client hay trên server?
Client (ví dụ, Swiss Ephemeris WASM trong trình duyệt):
- Ưu điểm: không tốn phí cho mỗi request, hoạt động offline, kiểm soát hoàn toàn
- Nhược điểm: ~2MB WASM cho mỗi người dùng, giấy phép phức tạp (sử dụng thương mại Swiss Ephemeris có hạn chế), bạn tự quản lý code tính toán
Server API (AstroWay, Prokerala, v.v.):
- Ưu điểm: không phụ thuộc client, bundle ứng dụng nhỏ, nhanh trên mobile, không đau đầu về giấy phép
- Nhược điểm: tính phí theo credit cho mỗi request, độ trễ trên “cold” requests
Đối với hầu hết các ứng dụng, server API sẽ thắng. Người dùng mobile sẽ không chờ đợi 2MB WASM; không nên phải xử lý các vấn đề giấy phép phức tạp; và các API hiện đại miễn phí cache các request giống nhau (AstroWay có cache 5 phút với header X-Cache: HIT).
Chọn API
Phần tiêu đề “Chọn API”Điều quan trọng:
- Độ chính xác: tìm kiếm Swiss Ephemeris “bên dưới” (±1 giây cung). Nếu API không nói rõ - hãy hỏi.
- Phạm vi: birth chart + synastry + transits: tối thiểu. Progressions và returns - cấp độ tiếp theo. Các kỹ thuật hiếm (rectification, Human Design) - là yếu tố khác biệt.
- Chất lượng SDK: TypeScript và Python SDK được type-safe tiết kiệm hàng giờ.
- Mô hình giá: credit-based mở rộng tốt hơn per-request trên tải hỗn hợp.
Trong hướng dẫn này, chúng ta sẽ sử dụng AstroWay API, vì nó có cả bốn (777 endpoints, Swiss Ephemeris, typed SDK, credit-based).
Bước 1: Thiết lập backend
Phần tiêu đề “Bước 1: Thiết lập backend”Không bao giờ gọi API chiêm tinh trực tiếp từ trình duyệt - API key của bạn sẽ bị rò rỉ. Luôn đi qua backend của bạn.
mkdir my-astrology-appcd my-astrology-appnpm init -ynpm install express @astroway/sdk zodnpm install -D typescript @types/express @types/node tsxTạo src/server.ts:
import express from 'express';import { Astroway } from '@astroway/sdk';import { z } from 'zod';
const app = express();app.use(express.json());
const client = new Astroway({ apiKey: process.env.ASTROWAY_API_KEY!,});
const BirthInput = z.object({ date: z.string(), time: z.string(), timezoneOffset: z.number(), latitude: z.number(), longitude: z.number(),});
app.post('/api/chart', async (req, res) => { const parsed = BirthInput.safeParse(req.body); if (!parsed.success) return res.status(400).json({ error: parsed.error });
try { const chart = await client.chart.compute({ ...parsed.data, houseSystem: 'P', }); res.json(chart); } catch (err) { res.status(500).json({ error: String(err) }); }});
app.listen(3000, () => console.log('http://localhost:3000'));Chạy:
ASTROWAY_API_KEY=aw_test_... npx tsx src/server.tsKiểm tra với curl:
curl -X POST http://localhost:3000/api/chart \ -H "Content-Type: application/json" \ -d '{"date":"1990-07-14","time":"14:30:00","timezoneOffset":3,"latitude":50.4501,"longitude":30.5234}'Bạn nhận được một birth chart JSON đầy đủ.
Bước 2: Frontend
Phần tiêu đề “Bước 2: Frontend”Bất kỳ framework nào cũng được. Ví dụ - React với một form đơn giản:
import { useState } from 'react';
type Chart = { planets: { name: string; longitude: number; isRetrograde: boolean }[]; aspects: { planet1: string; planet2: string; type: { name: string }; orb: number }[];};
// Planets come with ecliptic longitude, not a sign: the sign is that longitude// divided by 30. Work it out on your side, it is cheaper than another call.const SIGNS = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo', 'Libra', 'Scorpio', 'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces'];const signOf = (longitude: number) => SIGNS[Math.floor(longitude / 30) % 12];
export function NatalForm() { const [chart, setChart] = useState<Chart | null>(null);
async function handleSubmit(formData: FormData) { const body = Object.fromEntries(formData.entries()); const res = await fetch('/api/chart', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ date: body.date, time: body.time + ':00', timezoneOffset: Number(body.tz), latitude: Number(body.lat), longitude: Number(body.lng), }), }); setChart(await res.json()); }
return ( <div> <form action={handleSubmit}> <input name="date" type="date" required /> <input name="time" type="time" required /> <input name="tz" type="number" placeholder="Timezone offset (e.g. 3)" required /> <input name="lat" type="number" step="0.0001" placeholder="Latitude" required /> <input name="lng" type="number" step="0.0001" placeholder="Longitude" required /> <button>Build chart</button> </form>
{chart && ( <div> <h2>Planets</h2> <ul> {chart.planets.map(p => ( <li key={p.name}>{p.name}: {signOf(p.longitude)} {(p.longitude % 30).toFixed(2)}°{p.isRetrograde ? ' R' : ''}</li> ))} </ul> <h2>Aspects</h2> <ul> {chart.aspects.map((a, i) => ( <li key={i}>{a.planet1} {a.type.name} {a.planet2} (orb {a.orb.toFixed(2)}°)</li> ))} </ul> </div> )} </div> );}Bước 3: Synastry
Phần tiêu đề “Bước 3: Synastry”Tương thích - tính năng tiếp theo rõ ràng. Thêm vào src/server.ts:
const SynastryInput = z.object({ chart1: BirthInput, chart2: BirthInput,});
app.post('/api/synastry', async (req, res) => { const parsed = SynastryInput.safeParse(req.body); if (!parsed.success) return res.status(400).json({ error: parsed.error });
const result = await client.synastry.compute(parsed.data); res.json({ score: result.compatibility.score, label: result.compatibility.label, aspects: result.crossAspects, });});Xong. Một endpoint, 50 credit cho mỗi lần gọi, trả về score 0-100 và cross-aspects.
Bước 4: Tử vi hàng ngày
Phần tiêu đề “Bước 4: Tử vi hàng ngày”Để tăng engagement nội dung, tử vi hàng ngày - must have. AstroWay tạo chúng từ dữ liệu transits thực tế:
// The daily horoscope is keyed by sign and date, not by the birth chart.const DailyInput = z.object({ sign: z.enum(['aries', 'taurus', 'gemini', 'cancer', 'leo', 'virgo', 'libra', 'scorpio', 'sagittarius', 'capricorn', 'aquarius', 'pisces']), date: z.string(),});
app.post('/api/horoscope/daily', async (req, res) => { const parsed = DailyInput.safeParse(req.body); if (!parsed.success) return res.status(400).json({ error: parsed.error });
const horoscope = await client.horoscope.daily({ ...parsed.data, language: 'uk' }); res.json({ text: horoscope.horoscope, disclaimer: horoscope.disclaimer, // must be shown in the UI! });});Quan trọng: nội dung do AI tạo có chứa disclaimer, bạn bắt buộc phải hiển thị cho người dùng (theo Terms of Service). Đừng xóa nó.
Bước 5: Cache
Phần tiêu đề “Bước 5: Cache”Tử vi hàng ngày giống nhau cho tất cả người dùng cùng ngày sinh và birth chart tương tự. Cache một cách quyết liệt:
import { LRUCache } from 'lru-cache';
const cache = new LRUCache<string, any>({ max: 1000, ttl: 86400 * 1000 });
app.post('/api/horoscope/daily', async (req, res) => { const key = JSON.stringify(req.body); const cached = cache.get(key); if (cached) return res.json(cached);
const horoscope = await client.horoscope.daily(req.body); cache.set(key, horoscope); res.json(horoscope);});AstroWay cũng có server-side cache 5 phút tích hợp (X-Cache: HIT), nhưng cho nội dung lâu dài, bạn cần cache riêng.
Bước 6: Triển khai
Phần tiêu đề “Bước 6: Triển khai”Bất kỳ nền tảng nào cũng được. Để bắt đầu nhanh - Vercel hoặc Railway:
# vercel.json{ "functions": { "src/server.ts": { "runtime": "@vercel/node" } } }Trong bảng điều khiển nền tảng, đặt env ASTROWAY_API_KEY.
Lập kế hoạch ngân sách
Phần tiêu đề “Lập kế hoạch ngân sách”Nếu bạn đã đến đây - hãy đánh giá mức tiêu thụ credit hàng tháng trước khi khởi chạy:
credits/month = DAU × (avg_charts_per_user × 20 + avg_synastries × 50 + avg_horoscopes × 20) × 30Với 100 DAU với 1 birth chart + 1 horoscope + 0.3 synastry cho mỗi người dùng mỗi ngày:
100 × (20 + 20 + 0.3 × 50) × 30 = 165,000 credits/monthĐây là gói Starter với $19/tháng (200K credits).
Tiếp theo
Phần tiêu đề “Tiếp theo”Các tính năng nâng cao nên thêm khi phát triển:
- Transit overlay:
/v1/transitscho thấy vị trí hiện tại của các hành tinh trên birth chart - Progressions:
/v1/progressionscho các cung tâm lý phát triển - Solar return:
/v1/solar-returncho “dự báo năm từ ngày sinh” - Human Design: Human Design API mở ra một lĩnh vực chức năng hoàn toàn mới
- Astrocartography:
/v1/acgánh xạ nơi người dùng nên sống
Mỗi tính năng khó thực hiện từ đầu, nhưng - chỉ một API call với AstroWay.
Bắt đầu
Phần tiêu đề “Bắt đầu”- Nhận API key miễn phí: 10,000 credits / tháng
- Toàn bộ API reference: tất cả 777 endpoints
- Birth Chart API: tài liệu chi tiết về endpoint birth chart
Chính Swiss Ephemeris giống như trong Solar Fire - chỉ trong 4 dòng code.
Khóa API miễn phí không cần thẻ. 5.000 lượt gọi/tháng trước lần thanh toán đầu tiên.