Lompat ke konten
18 menit bacamateri 13 dari 96

Tentukan spesifikasi API

Tulis kontrak API yang bisa dites: resource, error, validasi, versioning, dan perubahan apa yang aman tanpa mematahkan klien lama.

Ditinjau 26 Oktober 2026

Pertanyaan

Apa yang dijanjikan API-mu ke klien, dan perubahan apa yang boleh kamu lakukan tanpa mematahkan klien yang sudah jalan?

Selesai baca ini, kamu bisa menulis spesifikasi satu endpoint lengkap dengan bentuk error, aturan validasi, dan aturan kompatibilitas, lalu menilai apakah sebuah perubahan itu aman.

Prasyarat dan contoh

Kamu paham request dan respons HTTP (method, status code, header) dari M02, dan sudah pernah bikin endpoint JSON.

Contoh: tim pembayaran punya endpoint POST /v1/orders yang dipanggil aplikasi mobile, web, dan dua layanan internal. Suatu hari backend mengganti field total dari angka rupiah (125000) jadi objek { "amount": 125000, "currency": "IDR" }. Server baru lolos semua tes. Aplikasi mobile versi lama, yang masih dipakai 30% pengguna, crash karena mengharapkan angka.

Implementasinya benar, kontraknya yang rusak. Kontrak API itu janji yang ditulis, dan klien bergantung ke janji itu, termasuk bagian yang kamu nggak sadar sudah kamu janjikan.

Mekanisme

Spesifikasi yang baik menjawab lima hal untuk tiap endpoint.

1. Resource dan operasinya. Namai benda, bukan aksi: /orders, /orders/{id}. Tiap method punya arti tetap. GET nggak mengubah apa pun. PUT dan DELETE idempoten secara semantik (diulang hasilnya sama). POST nggak punya jaminan itu, dan itu jadi bahan lesson M03.05.

2. Bentuk respons sukses. Tulis tiap field, tipe, satuan, dan apakah boleh null. "total" tanpa satuan adalah bug yang menunggu. Tulis juga status code yang berbeda untuk keadaan berbeda: 201 untuk dibuat, 200 untuk dibaca, 204 untuk sukses tanpa isi.

3. Bentuk error. Satu format untuk semua error, supaya klien bisa menanganinya tanpa menebak:

{
  "error": {
    "code": "insufficient_stock",
    "message": "Stok tidak cukup untuk SKU A-100",
    "retryable": false
  }
}

Klien mengambil keputusan dari code dan status HTTP, bukan dari message (teks boleh berubah). Bedakan tiga kelas: 4xx salah di klien (jangan diulang tanpa mengubah request), 429 terlalu cepat (tunggu dulu), 5xx salah di server (mungkin aman diulang, lihat M03.04).

4. Validasi. Tulis batasnya: quantity bilangan bulat 1 sampai 100, note maksimal 500 karakter, body maksimal 64 KB. Pilih sikap untuk field yang nggak dikenal (ditolak atau diabaikan) dan tulis. Tolak dengan 422 atau 400 plus daftar field yang salah, bukan satu pesan umum.

5. Versioning dan kompatibilitas. Bedakan perubahan yang aman dan yang mematahkan:

| Perubahan | Aman untuk klien lama? | | --- | --- | | Menambah field opsional di respons | Ya, kalau klien mengabaikan field asing | | Menambah endpoint baru | Ya | | Menambah nilai baru pada enum respons | Berisiko: klien dengan switch ketat bisa gagal | | Menghapus atau mengganti nama field | Tidak | | Mengubah tipe atau satuan field | Tidak | | Membuat field request opsional jadi wajib | Tidak |

Aturan praktis: respons boleh bertambah, nggak boleh berubah arti. Kalau perubahan yang mematahkan memang perlu, keluarkan versi baru (/v2/orders atau header versi), jalankan keduanya sambil memantau berapa klien yang masih memakai versi lama, lalu tetapkan tanggal pensiun.

Saat rancangan ini gagal

  • Kontrak implisit. Urutan elemen array, field yang kebetulan selalu ada, atau pesan error yang diparse klien dengan regex. Semuanya dianggap janji oleh klien walaupun nggak pernah kamu tulis. Cara menahannya: tes kontrak yang membandingkan respons nyata dengan skema.
  • Error yang nggak bisa dibedakan. Semua kegagalan jadi 500 dengan pesan teks. Klien nggak tahu mana yang aman diulang, jadi memilih salah satu ekstrem: nggak pernah retry, atau selalu retry termasuk untuk request yang memang salah.
  • Versi yang nggak pernah pensiun. Kamu mendukung v1, v2, v3 selamanya, dan tiap perbaikan bug harus dikerjakan tiga kali. Tanpa tanggal pensiun dan data pemakaian per versi, biaya ini nggak terlihat sampai terlambat.
  • Validasi hanya di klien. Klien mobile membatasi quantity sampai 100, tapi API nggak. Klien lain mengirim quantity: 1000000 dan menghabiskan stok.

Latihan

Kamu mengelola GET /v1/products/{id} yang mengembalikan:

{ "id": "p1", "name": "Kopi", "price": 25000, "status": "active" }

Nilai tiap perubahan berikut: aman, berisiko, atau mematahkan. Sebutkan alasannya.

  1. Menambah field weight_grams.
  2. Mengganti price dari rupiah ke sen (2500000).
  3. Menambah nilai status baru: "discontinued".
  4. Mengganti nama name jadi title.
  5. Mengembalikan 404 untuk produk yang dihapus, yang tadinya 200 dengan status: "deleted".
Lihat pembahasan
  1. Aman. Field baru di respons, asalkan kontrak awal menyatakan klien mengabaikan field asing.
  2. Mematahkan. Tipe sama, arti berubah. Klien menampilkan harga 100 kali lebih besar tanpa error apa pun, yang lebih berbahaya daripada crash. Solusinya field baru (price_minor) di samping price.
  3. Berisiko. Klien yang menangani active dan deleted saja mungkin jatuh ke cabang default. Kontrak sebaiknya dari awal menulis "klien harus menangani nilai status yang belum dikenal". Kalau belum, umumkan dulu sebelum mengirim nilai baru.
  4. Mematahkan. Nama field berubah. Tambahkan title, pertahankan name.
  5. Mematahkan. Status code adalah bagian kontrak. Klien yang membaca status: "deleted" sekarang menerima error. Perubahan semacam ini harus lewat versi baru.

Polanya: tanya "klien lama yang nggak diubah sama sekali, apa yang terjadi?" Kalau jawabannya "salah diam-diam" (nomor 2), itu lebih buruk daripada "gagal keras".

Terkait

  • Lanjut ke M03.02 Rancang pagination, satu bagian kontrak yang sering salah untuk koleksi besar.
  • Bentuk error dan flag retryable dipakai lagi di M03.04.
  • Lab L03 dan proyek B01 belum tersedia.

Catatan

  • Asumsi: API JSON di atas HTTP, dengan klien yang nggak bisa kamu paksa upgrade (mobile, integrasi pihak ketiga).
  • Yang nggak dibahas: GraphQL, gRPC, dan tooling skema seperti OpenAPI, walaupun idenya sama.
  • Tabel kompatibilitas itu panduan umum. Klien tertentu bisa lebih rapuh dari yang diasumsikan.
  • Terakhir ditinjau: 26 Oktober 2026.

Isi · System Design