Skip to content

davidgrldo/alkitab-api

Repository files navigation

alkitab-api

CI License: MIT

One engine, many sources. A Bible API in Go that treats copyright as an architecture problem — not an afterthought.

Most Bible translations, including the Indonesian Terjemahan Baru, are copyrighted. This project responds by design instead of by ignoring it: the engine ships only public-domain text, reads your own data at runtime, and keeps access to copyrighted translations strictly opt-in — a live proxy, never a redistribution.

One binary. No database. Zero copyrighted text in the repo.

HTTP ──▶ server ──▶ engine ──▶ Source
         net/http   cache ·    ├── local   default · embedded JSON + BYOD corpus
         REST       Chain      └── scrape  opt-in · runtime proxy, no redistribution

         transport ──▶ core ──▶ adapters — dependencies point inward
  • local — JSON via go:embed plus anything you drop in a data directory. Carries the in-memory corpus that powers search/daily/random.
  • scrape — a runtime proxy for alkitab.mobi (goquery, 10 s timeout, 4 MiB body cap, throttled + self-identifying). Serves tb, tl, bis, vmd, tsi, ayt, ende, jawa, sunda. No corpus: search/daily/random honestly return 501.
  • Chain — tries local first, falls through to scrape when a version isn't found. Capability is checked by type assertion, not by hoping.

Quick start

go run ./cmd/alkitab-api
# alkitab-api listening on :3000 (scrape=false)

curl localhost:3000/v1/kjv/3john/1/4
{
  "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
    }
  ]
}

Works out of the box: a small public-domain KJV sample (3 John, Philemon) is embedded. Full translations are yours to add — see BYOD.

Prefer a container?

docker run -p 3000:3000 ghcr.io/davidgrldo/alkitab-api:latest
# or build locally: docker build -t alkitab-api . && docker run -p 3000:3000 alkitab-api

GET /healthz answers ok for liveness probes; the server shuts down gracefully on SIGINT/SIGTERM.

Use as a library

The engine and adapters are importable — the HTTP server is just one consumer:

go get github.com/davidgrldo/alkitab-api
package main

import (
	"fmt"

	"github.com/davidgrldo/alkitab-api/bible"
	"github.com/davidgrldo/alkitab-api/local"
)

func main() {
	src, err := local.New("") // "" = embedded public-domain sample; or your ALKITAB_DATA_DIR
	if err != nil {
		panic(err)
	}
	eng := bible.New(src)

	ch, _ := eng.Chapter("kjv", "3john", 1)
	fmt.Println(ch.Verses[3].Content) // I have no greater joy…
}

Compose sources with bible.NewChain(local, scrape) — the engine checks the bible.Corpus capability by type assertion, so search/daily/random work exactly when the active source can support them.

Endpoints

Method Path Description
GET /v1/translations List available translations
GET /v1/{version}/books Books, chapter counts, OT/NT category
GET /v1/{version}/{book}/{chapter} Whole chapter, section headings included
GET /v1/{version}/{book}/{chapter}/{verse} Single verse
GET /v1/search?q=&version=&limit= Case-insensitive substring search (local corpus); default limit 50, total reports the full count
GET /v1/daily?version= Deterministic per date & version (UTC)
GET /v1/random?version= Random verse, seeded by math/rand/v2

{book} accepts an id (gen), an English name (Genesis), or an Indonesian name (Kejadian) — case-insensitive. Typed errors map to honest status codes: 404 unknown, 400 malformed, 501 unsupported capability. Internal messages never leak.

Bring Your Own Data (BYOD)

Want a full Bible right away? A complete public-domain KJV (66 books, 31,100 verses) in BYOD format ships with every release — download kjv.json, drop it in a directory, done:

mkdir -p data && curl -L -o data/kjv.json \
  https://github.com/davidgrldo/alkitab-api/releases/latest/download/kjv.json
ALKITAB_DATA_DIR=./data go run ./cmd/alkitab-api

Have another public-domain dump? cmd/alkitab-convert turns the common array-of-books JSON shape (e.g. thiagobodruk/bible) into BYOD:

go run ./cmd/alkitab-convert -id kjv -name "King James Version" -lang en en_kjv.json > kjv.json

Or write the format by hand — one JSON file per translation in ALKITAB_DATA_DIR:

{
  "translation": { "id": "kjv", "name": "King James Version", "language": "en" },
  "books": [
    {
      "id": "3john", "name": "3 John", "abbr": "3John",
      "testament": "NT", "chapters": 1,
      "chapter_data": [
        { "number": 1, "verses": [
          { "verse": 1, "type": "content", "content": "..." }
        ] }
      ]
    }
  ]
}

A runtime file with the same id overrides the embedded sample. Safe public-domain candidates: KJV, BBE, and 19th-century Indonesian works such as Klinkert (1863/1879) and Melayu Baba (1913).

Configuration

Var Default Purpose
ALKITAB_PORT 3000 Listen port
ALKITAB_DATA_DIR (none) Extra translations directory
ALKITAB_SCRAPE 0 1 enables the scrape adapter
ALKITAB_BASE_URL https://alkitab.mobi Scrape base URL

Copyright

This repository distributes no copyrighted text. The embedded sample is public domain (KJV: 3 John, Philemon). Translations like Terjemahan Baru (TB) © LAI 1974 are not included; access them at runtime by enabling ALKITAB_SCRAPE=1 (a proxy that keeps only an in-memory cache) or by supplying your own data file, for which you are responsible.

Microsite

A single-file, framework-free microsite that tells the whole story visually is live at davidgrldo.github.io/alkitab-api (source: site/index.html). Run the server locally and its demo button fetches a verse for real.

About

One engine, many sources — Go Bible API that treats copyright as an architecture problem. Embedded public-domain text, BYOD at runtime, opt-in scrape. One binary, no database.

Topics

Resources

License

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors