Bible API · Go · Open Source

Satu mesin,
banyak sumber.

API Alkitab berbasis Go dengan arsitektur adapter — local JSON sebagai default, scrape alkitab.mobi sebagai opsi. Satu binari, tanpa database, tanpa teks berhak cipta di repositori ini.

~/alkitab-api
# jalankan dalam satu baris
$ go run ./cmd/alkitab-api
  → listening on :3000 (scrape=false)

# satu ayat, atau rentang: …/1/4-6
$ curl localhost:3000/v1/kjv/3john/1/4
{
  "version": "kjv",
  "verses": [
    { "verse": 4,
      "content": "I have no greater joy…" }
  ]
}
Filosofi

Hak cipta adalah masalah arsitektur.

Sebagian besar terjemahan Alkitab — termasuk Terjemahan Baru — berstatus berhak cipta. Proyek ini menanggapinya bukan dengan mengabaikan, melainkan dengan merancang ulang: teks bawaan adalah domain-publik, akses ke terjemahan berhak cipta bersifat opt-in dan hanya terjadi saat runtime.

i.

Bring Your Own Data

Mesin tidak membawa teks berhak cipta. Cukup letakkan berkas JSON di ALKITAB_DATA_DIR dan ia langsung terbaca di samping contoh domain-publik yang sudah tertanam.

ii.

Scrape adalah opt-in

Akses ke Terjemahan Baru tetap mungkin lewat adapter scrape yang diaktifkan dengan ALKITAB_SCRAPE=1 — sekadar proxy saat runtime, tanpa redistribusi.

iii.

Tiga lapis, satu arah

Transport, mesin, adapter. Dependensi hanya mengalir ke dalam. Itu yang membuat BYOD dan opt-in scrape bekerja tanpa menulis ulang inti.

Design tokens
Paper
#F5EFE1
Paper-2
#EFE7D4
Ink
#1C1813
Rubric
#9A3B2D
Olive
#64703F
Gold
#9A7B2E
Display · FrauncesTeks suci
Body · Frauncesayat yang berbicara
Code · JetBrains/v1/kjv/3john/1
EyebrowBible API
Arsitektur

Tiga lapisan, dependensi mengalir ke dalam.

REST menyentuh mesin; mesin membungkus sebuah Source; adapter mengimplementasikan kontrak itu. Arahkan kursor atau ketuk tiap lapis untuk menonjolkannya.

Lapisan · Transport
server
REST di atas stdlib net/http. Routing pola Go 1.22, tanpa dependensi. Mapping error terpusat di sini.
Handlernet/http

7 rute: translations, books, chapter, verse, search, daily, random.

mapErr → 404/501/400/500ResolveBookIDsort deterministik
HTTP
Lapisan · Inti
engine
Pure domain. Cache pasal in-memory, dan tiga operasi yang ditopang kapabilitas Corpus.
Enginecache

Membungkus satu Source. Menyimpan pasal agar tidak di-fetch ulang.

Chapter()Search()DailyVerse()RandomVerse()
Chaincomposite

Menggabungkan source secara berurutan: local dulu, scrape saat tidak ada.

fallback ErrNotFound / ErrUnsupportedVersionmerge Translations
Source / Corpus
Lapisan · Adapter
sources
Dua implementasi Source. Hanya yang punya korpus in-memory yang menopang search/daily/random.
localdefault

JSON + go:embed, di-scan di memori. Contoh KJV domain-publik tertanam.

Corpus ✓scan O(n)ALKITAB_DATA_DIR
scrapeopt-in

Mengikis alkitab.mobi via goquery. Timeout 10s, body dibatasi 4 MiB, error tidak bocor.

Corpus ✗ → 5019 terjemahan · id/jv/su

Kapabilitas Corpus diperiksa lewat type assertion — search/daily/random jujur mengembalikan 501 saat sumber aktif tidak punya korpus.

Siklus permintaan

Bagaimana satu GET menjadi ayat.

Dari path hingga JSON, setiap langkah melalui satu titik: Engine.

i

Menerima GET /v1/kjv/3john/1

Router Go 1.22 menangkap path values. {chapter} divalidasi numerik; bukan → 400.

ii

Resolve book → id

ResolveBookID menerima id, nama Inggris, atau nama Indonesia (case-insensitive) dan menormalisasinya ke "3john".

iii

Engine mengecek cache

Cache in-memory version:book:chapter dijamin RWMutex. Kena → langsung kembali. Luput → lanjut ke source.

iv

Source menjawab (local, atau Chain → scrape)

local.Chapter membaca JSON tertanam. Jika versi tak ada dan scrape aktif, Chain meneruskan ke adapter scrape.

v

JSON keluar

Hasil di-cache, diserialisasi. Error bertipe memetakan ke kode status yang tepat (404, 400, 501, 502 scrape) — tak ada pesan internal yang bocor.

Endpoint

Delapan rute, kontrak yang sama.

JSON masuk, JSON keluar. {book} menerima id, nama, atau singkatan — Inggris maupun Indonesia. GET /v1 mendaftar rute; terjemahan scrape tidak punya corpus.

GET
/v1/translations
Daftar terjemahan

Source aktif, plus origin (local atau proxy) dan capabilities.

GET
/v1/{version}/books
Struktur kitab

Kitab, jumlah pasal, PL/PB. ?locale=id untuk nama Indonesia.

GET
/v1/{version}/{book}/{chapter}
Satu pasal

Seluruh ayat, termasuk judul. prev/next, ETag, ?also=tb.

GET
…/{chapter}/{verse}
Ayat atau rentang

4, 16-18, atau 16,17. Pointer ayat tetangga, ?also= sama.

GET
/v1/passage?version=&q=
Referensi manusia

3john 1:4-6, Yohanes 3:16,17, Matt 5:1-7:29.

GET
/v1/search?q={q}
Pencarian teks

Korpus lokal. Hit membawa snippet dengan **match**. Filter book, testament, whole=1. Limit max 200. Judul dilewati.

GET
/v1/daily?version={v}
Ayat hari ini

Hanya ayat isi. date=YYYY-MM-DD, tz, kitab atau perjanjian opsional.

GET
/v1/random?version={v}
Ayat acak

Sama: hanya isi, filter kitab/perjanjian. seed= untuk hasil yang bisa diulang.

Demo

Ambil ayat, langsung.

Coba ambil 3 Yohanes 1:4 dari server lokal, atau lihat contoh jika server belum berjalan.

butuh go run ./cmd/alkitab-api di port 3000
response · kjv · 3john 1:4
// contoh respons (server belum dihubungi)
{
  "version": "kjv",
  "book": "3john",
  "chapter": 1,
  "verses": [
    {
      "verse": 4,
      "content": "I have no greater joy than to hear that my children walk in truth.",
      "type": "content",
      "order": 0
    }
  ]
}

Bring Your Own Data

“Tidak ada teks berhak cipta di repositori ini — dan sengaja demikian.”

Contoh tertanam adalah domain-publik — KJV, hanya 3 Yohanes & Filemon. Butuh Alkitab utuh? KJV lengkap tersedia sebagai aset rilis, dan alkitab-convert mengubah dump JSON, USFM, OSIS, atau CSV domain-publik ke format ini (catatan kaki menjadi type=note). File runtime dengan id yang sama menimpa contoh tertanam. Terjemahan berhak cipta seperti TB © LAI hanya bisa diakses saat runtime lewat proxy scrape — tanggung jawab operator, bukan proyek.

ALKITAB_PORTport listen · default 3000
ALKITAB_LISTENalamat penuh · mis. 127.0.0.1:3000
ALKITAB_DATA_DIRdirektori terjemahan tambahan
ALKITAB_SCRAPE1 → aktifkan adapter scrape
ALKITAB_BASE_URLbasis scrape · default alkitab.mobi
alkitab-data/tb.json
// format BYOD — satu file per terjemahan
{
  "translation": {
    "id": "tb",
    "name": "Terjemahan Baru",
    "language": "id"
  },
  "books": [
    { "id": "john",
      "name": "Yohanes",
      "abbr": "Yoh",
      "testament": "NT",
      "chapters": 21,
      "chapter_data": [
        { "number": 1,
          "verses": [
            { "verse": 1,
              "type": "content",
              "content": "…" }
          ] }
      ] }
  ]
}