Lompat ke konten
dokumentasi.id
Commit 493bd1c
v1
Star762

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

4

Format Response dan Wrapper `data`/`meta`

Semua endpoint di bawah base URL /v2 mengembalikan JSON dengan amplop yang sama: objek data berisi payload sebenarnya, objek meta berisi keterangan berkas. Bentuk ini tidak berbeda antar endpoint karena seluruh berkas JSON ditulis lewat satu fungsi pembungkus. README.md:55-74

type genMeta struct {
	UpdatedAt string `json:"updated_at"`
	Level     int    `json:"level"`
}

func genResponse(data any, level int) map[string]any {
	return map[string]any{
		"data": data,
		"meta": genMeta{UpdatedAt: time.Now().UTC().Format("2006-01-02"), Level: level},
	}
}

Fungsi genResponse mencetak meta.updated_at sebagai tanggal YYYY-MM-DD dari jam UTC saat berkas ditulis, dan meneruskan level sebagai argumen pemanggil. tools/generate_static_api.go:150-160

Nilai data bisa berupa objek tunggal (endpoint detail) atau array (endpoint daftar). Dua struct yang menentukan bentuknya adalah genPlace untuk objek dan genShortItem untuk item daftar; pada keduanya field has_path dideklarasikan tanpa omitempty, sehingga selalu muncul sebagai true atau false. tools/generate_static_api.go:100-123

Level payload dan transisinya

meta.level menandai kedalaman data pada berkas itu. Nilainya bukan turunan dari id di dalam data, melainkan angka yang dikirim pemanggil genResponse. Akibatnya satu berkas daftar bisa berlevel berbeda dari id yang dikandungnya: regencies/32.json berisi daftar kab/kota tetapi tetap berlevel 2. tools/generate_static_api.go:241-245

stateDiagram-v2
    [*] --> L0
    L0: level 0 stats.json dan missings.json
    L0 --> L1: provinces.json
    L1: level 1 provinces dan provinces/32.json
    L1 --> L2: regencies/32.json
    L2: level 2 regencies dan regencies/32.73.json
    L2 --> L3: districts/32.73.json
    L3: level 3 districts dan districts/32.73.01.json
    L3 --> L4: villages/32.73.01.json
    L4: level 4 villages dan postal-codes
    L4 --> [*]
    style L0 fill:#8b5cf6,color:#fff
    style L1 fill:#2d7d46,color:#fff
    style L2 fill:#2d7d46,color:#fff
    style L3 fill:#2d7d46,color:#fff
    style L4 fill:#2d7d46,color:#fff
%% fig: Transisi level payload antar berkas JSON
%% desc: Setiap turun satu tingkat hirarki, pemanggil genResponse menaikkan angka level dari 0 sampai 4; stats.json dan missings.json berada di level 0.
Fig. 1: Transisi level payload antar berkas JSONSetiap turun satu tingkat hirarki, pemanggil genResponse menaikkan angka level dari 0 sampai 4; stats.json dan missings.json berada di level 0.
meta.levelBerkas yang memakainyaPemanggil genResponse
0stats.jsongenResponse(stats, 0) tools/generate_static_api.go:417
0missings.jsonbukan lewat genResponse, objek meta ditulis manual tools/generate_missings.go:159-163
1provinces.json, provinces/{code}.jsongenResponse(provinces, 1) dan newGenPlace, termasuk regenerasi di phase B tools/generate_static_api.go:241-245
2regencies/{province}.json, regencies/{code}.jsonwriteList(...) dengan level 2 dan write("regencies", k, d, 2) tools/generate_static_api.go:241-245
3districts/{regency}.json, districts/{code}.jsonwriteList("districts", k, ..., 3) dan write("districts", k, d, 3) tools/generate_static_api.go:252-262
4villages/{district}.json, villages/{code}.json, postal-codes/{code}.jsonwriteList("villages", k, ..., 4) dan write("postal-codes", post, items, 4) tools/generate_static_api.go:273-288
1–4paths/{code}.jsongenLevelCount(kode)+1, jadi provinsi 1, kab/kota 2, kecamatan 3, desa 4 tools/generate_static_api.go:346-347

Contoh nyata untuk paths/32.json memperlihatkan meta.level bernilai 1 karena id 32 tidak memuat titik. web/src/components/api/apiSpec.ts:631-644

meta.updated_at dan meta.generated_at

Dokumentasi menyebut dua nama field: meta.updated_at pada contoh amplop dan meta.generated_at (RFC3339) pada keterangan field. README.md:55-74 SKILL.md:21-35

Di dalam kode Go, generated_at hanya pernah muncul sebagai argumen delete: setiap tahap patch menghapus field itu lalu menimpa updated_at dengan tanggal hari patch. tools/add_has_path.go:172-176 Tahap pembaruan koordinat melakukan hal yang sama pada berkas detail dan berkas daftar. tools/generate_boundaries.go:606-609 Tahap hitung ukuran berkas juga menimpa updated_at di stats.json. tools/update_stats.go:128-129

Konsekuensinya, berkas hasil pipeline membawa updated_at berupa tanggal, bukan timestamp RFC3339 penuh. meta.updated_at adalah tanggal pemrosesan terakhir, bukan tanggal data hulu: nilai itu bergeser walau isi wilayah tidak berubah, setiap kali salah satu tahap patch menyentuh berkas. tools/add_has_path.go:172-176

⚠️ Jangan memakai meta.updated_at sebagai penanda versi data. Field ini ditulis ulang oleh add-has-path, generate-boundaries, dan update-stats di setiap kali jalan, jadi tanggal berubah tanpa perubahan wilayah. tools/update_stats.go:128-129

has_path dan has_latlng

Kedua bendera menjawab pertanyaan berbeda. has_path menempel pada setiap objek wilayah di endpoint provinsi sampai desa, sedangkan has_latlng hanya ada di missings.json sebagai hasil evaluasi. tools/generate_missings.go:31-36

graph LR
    paths["api/paths/*.json"] --> set["buildHasPathSet"]
    set --> patch["patchFileHasPath"]
    patch --> item["genPlace.has_path"]
    latlng["lat + lng pada berkas wilayah"] --> eval["hasLatLngFromMap"]
    eval --> mjson["missings.json: has_latlng"]
    style paths fill:#336791,color:#fff
    style set fill:#f59e0b,color:#000
    style patch fill:#8b5cf6,color:#fff
    style item fill:#2d7d46,color:#fff
    style latlng fill:#336791,color:#fff
    style eval fill:#f59e0b,color:#000
    style mjson fill:#8b5cf6,color:#fff

%% fig: Asal nilai has_path dan has_latlng %% desc: has_path disalin dari daftar nama berkas di direktori paths, sedangkan has_latlng dihitung dari ada tidaknya lat dan lng di berkas wilayah.

buildHasPathSet membaca nama berkas di direktori paths, membuang sufiks .json dengan strings.TrimSuffix, dan menjadikan sisanya kunci himpunan. tools/add_has_path.go:110-126 patchFileHasPath lalu menulis m["has_path"] = hasPathSet[id] untuk setiap item array, atau v["has_path"] = hasPathSet[id] untuk objek tunggal. tools/add_has_path.go:144-170 Artinya has_path mencerminkan ada tidaknya berkas api/paths/{id}.json pada saat patch dijalankan, bukan hasil pembacaan geometri di dalam berkas itu.

⚠️ Menjalankan generate-boundaries dengan -limit memotong daftar target sebelum diproses, sehingga hanya sebagian api/paths/*.json yang tertulis dan sisanya mendapat has_path: false di tahap patch berikutnya. tools/generate_boundaries.go:197-200

has_latlng dihitung oleh hasLatLngFromMap: hasilnya false bila lat atau lng tidak ada atau bernilai null, dan juga false bila keduanya 0. tools/generate_missings.go:228-247 Entry hanya dimasukkan ke daftar bila has_path atau has_latlng bernilai false. tools/generate_missings.go:109-115 Rincian isi dan arti summary.by_level dibahas di Kelengkapan Data dan missings.json.

Pemakaian praktisnya: periksa has_path lebih dulu, baru fetch paths/{id}.json, supaya tidak menerima 404. SKILL.md:149-152

Bentuk yang menyimpang dari amplop standar

Dua berkas menambah kunci di luar data dan meta:

Contoh keluaran missings.json yang menampilkan summary di samping data dan meta dapat dilihat pada spesifikasi di website. web/src/components/api/apiSpec.ts:684-699 Bentuk objek stats.json mengikuti pola yang sama: seluruh total ada di dalam data, dengan meta.level 0. web/src/components/api/apiSpec.ts:57-77 Untuk daftar endpoint beserta payload masing-masing, lihat Referensi Endpoint.