6
Kontrak Response dan Penanganan Error
Setiap response sukses di repository ini dikirim sebagai satu objek JSON dengan empat field: code, status, message, dan data. Field code menyalin ulang nilai status HTTP yang dikirim bersama body, sehingga informasi yang sama muncul dua kali di jalur kabel. api/handlers/surah.js:5-161
Pola itu tidak berlaku di semua endpoint. Endpoint akar / mengirim body yang sama sekali berbeda, tanpa code, status, message, maupun data, melainkan sebuah peta URL contoh beserta maintaner dan source. api/routes.js:14-322
Field envelope
| Field | Tipe nilai | Sumber nilai |
|---|---|---|
code | number | Selalu sama dengan status HTTP yang dipakai di res.status(...) |
status | string | 'OK.' untuk 200 dan 'Not Found.' untuk 404, selalu diakhiri titik |
message | string | Kalimat yang menyebut entitas dan nilai parameternya |
data | object atau array | Payload hasil bacaan; berupa {} pada 404 dari handler |
Nilai code dan status ditulis manual di setiap handler, bukan dihitung dari satu fungsi pembantu. Karena itu tidak ada satu modul yang menjadi rujukan tunggal envelope ini: bentuknya tersebar di SurahHandler dan JuzHandler. api/handlers/juz.js:4-223
Perpindahan status response
Satu request hanya bisa berakhir di tiga bentuk: sukses 200 dari handler, gagal 404 dari handler, atau gagal 404 dari fallback router. Tidak ada bentuk keempat.
stateDiagram-v2
[*] --> Router
Router --> SurahHandler: router.get cocok
Router --> JuzHandler: router.get cocok
Router --> Fallback: router.all
SurahHandler --> Sukses200: data ada
SurahHandler --> Gagal404: data falsy
JuzHandler --> Sukses200: juzData mengembalikan objek
JuzHandler --> Gagal404: juzData mengembalikan null
Sukses200 --> [*]: code 200 dengan data terisi
Gagal404 --> [*]: code 404 dengan data kosong
Fallback --> [*]: code 404 tanpa field data
style Router fill:#f59e0b,color:#000
style Sukses200 fill:#2d7d46,color:#fff
style Gagal404 fill:#dc2626,color:#fff
style Fallback fill:#dc2626,color:#fff
%% fig: Perpindahan status response
%% desc: Router memilih satu handler atau fallback, lalu request berakhir sebagai 200 dengan data terisi, 404 dari handler dengan data kosong, atau 404 dari fallback tanpa field data.Fallback didaftarkan sebagai router.all('*') setelah semua router.get, sehingga ia menangkap path yang tidak dikenal sekaligus metode HTTP lain terhadap path yang dikenal, misalnya POST /surah. api/routes.js:41-454
Response tiap endpoint
| Route | Kondisi | Status HTTP | code | status | message | data |
|---|---|---|---|---|---|---|
/ | selalu | 200 | tidak ada | tidak ada | tidak ada | tidak ada |
/surah | selalu | 200 | 200 | 'OK.' | 'Success fetching all surah.' | array surah tanpa verses dan preBismillah |
/surah/:surah | quran[surah - 1] ada | 200 | 200 | 'OK.' | 'Success fetching surah.' | objek surah utuh |
/surah/:surah | indeks kosong | 404 | 404 | 'Not Found.' | Surah "<surah>" is not found. | {} |
/surah/:surah/:ayah | surah dan ayah ada | 200 | 200 | 'OK.' | 'Success fetching ayah' | objek ayah plus surah |
/surah/:surah/:ayah | surah tidak ada | 404 | 404 | 'Not Found.' | Surah "<surah>" is not found. | {} |
/surah/:surah/:ayah | verses[ayah - 1] kosong | 404 | 404 | 'Not Found.' | Ayah "<ayah>" in surah "<surah>" is not found. | {} |
/juz/:juz | juzData mengembalikan objek | 200 | 200 | 'OK.' | 'Success fetching juz.' | objek rentang juz |
/juz/:juz | juzData mengembalikan null | 404 | 404 | 'Not Found.' | Juz "<juz>" is not found. | {} |
| path atau metode lain | selalu | 404 | 404 | 'Not Found.' | Resource "<req.url>" is not found. | tidak ada |
Tiga hal kecil di tabel itu mudah terlewat. Pertama, message pada sukses ayah ditulis 'Success fetching ayah' tanpa titik penutup, berbeda dari empat pesan sukses lain yang memakai titik. api/handlers/surah.js:59-675 Kedua, pesan ayah menyebut dua nilai sekaligus, ayah dan surah, sedangkan pesan 404 surah hanya menyebut surah. api/handlers/surah.js:41-576 Ketiga, pada getSurah pemeriksaan keberhasilan memakai nilai objek surah itu sendiri sebagai kondisi, bukan panjang array. api/handlers/surah.js:19-367
data: {} pada 404, dan fallback yang melewatkannya
Handler selalu mengirim data: {} ketika mengembalikan 404, sehingga klien dapat membaca response.data.surah tanpa memeriksa undefined lebih dulu. Fallback router tidak mengikuti aturan itu: body-nya hanya memuat code, status, dan message. api/routes.js:41-454
⚠️ Klien yang memperlakukan
datasebagai field wajib akan gagal pada response fallback, karena objek yang dikirim tidak memiliki kuncidatasama sekali. Periksacodelebih dulu, baru aksesdata.
Tidak ada jalur 500 di repository ini
Rantai middleware di api/server.js hanya memasang cors(), express.json(), dan routes. Tidak ada handler error empat argumen dan tidak ada try/catch di dalam handler, sehingga tidak ada satu pun cabang yang mengirim code: 500. api/server.js:11-148 Bila sebuah handler melempar exception, Express memakai penangan error bawaan dan body-nya tidak lagi mengikuti envelope di halaman ini.
Satu catatan yang menyentuh kontrak ini tetapi dibahas di Alur Request dan Middleware caching: pada cache hit, caching memanggil res.status(200).send(cache[key]) dan menyimpan body apa adanya. Karena body 404 ikut tersimpan, pemutaran ulang bisa mengirim body ber-code 404 dengan status HTTP 200; pada kondisi itu field code di body menjadi satu-satunya penanda kegagalan. api/middlewares.js:6-89