Sulitnya Menangani Error HTTP API dan RFC7807
(gosuda.org)Saat mengembangkan HTTP API, penanganan error sering kali menjadi bagian yang merepotkan. Semakin banyak jumlah API dan semakin kompleks logika internalnya, tantangan muncul dari tiga sisi berikut.
- Mengembalikan kode error yang tepat: Bagi developer yang belum banyak berpengalaman, sulit untuk menggunakan kode status HTTP secara konsisten di dalam logika yang kompleks.
- Menulis banyak log hasil: Mencatat log di semua titik akhir yang diperkirakan saat error terjadi menambah jumlah kode dan membuat pengelolaannya lebih rumit.
- Mengirim pesan error yang jelas: Hanya menyampaikan pesan error ke klien saja tidak cukup untuk membantu mereka memahami dan menangani error dengan jelas.
Memperbaiki pengembalian kode error yang tepat
Untuk mengatasi masalah konsistensi dalam penggunaan kode error, diusulkan metode dengan mengimplementasikan interface atau struct HttpError yang mencakup StatusCode dan Message.
- Solusi:
- Mendefinisikan tipe
HttpError: membungkus kode status HTTP dan pesan. - Menyediakan helper function: menggunakan helper function yang mengembalikan kode error tertentu, seperti
httperror.BadRequest("wrong format"), agar objek error mudah dibuat.
- Mendefinisikan tipe
- Keuntungan:
- Memanfaatkan fitur auto-complete IDE untuk memasukkan kode error dan pesan dengan nyaman dan aman.
- Mengurangi kemungkinan kesalahan dibandingkan memasukkan kode angka secara manual.
- Mengurangi kerepotan harus memeriksa dokumen desain yang sudah disiapkan satu per satu.
Sentralisasi penulisan log
Untuk mengurangi penulisan log yang berulang dan mengelola logika penanganan error di satu tempat, diajukan metode membungkus HTTP handler.
- Solusi:
- Mengimplementasikan router kustom (
chiwrap.Router): menyertakan router yang sudah ada sepertichi.Routerdi dalamnya dan menambahkan logika penanganan error. - Membungkus handler: method seperti
Getpada router kustom menerimaHandlerFunc, mengeksekusinya secara internal, lalu saat error terjadi meneruskannya ke logika penanganan terpusat. - Fungsi callback error: saat membuat
NewRouter, terima fungsierrCallbacksehingga ketika error terjadi callback tersebut dipanggil untuk mencatat log secara terpusat atau melakukan pemrosesan tambahan.
- Mengimplementasikan router kustom (
- Keuntungan:
- Saat error terjadi di logika API, kode error dan pesan yang tepat otomatis dikembalikan sebagai respons.
- Pengelolaan log menjadi mudah dengan mendaftarkan fungsi callback agar log yang sesuai dapat dicatat untuk tiap layanan.
- Mengurangi duplikasi kode dan meningkatkan kemudahan pemeliharaan.
Mengirim pesan error yang jelas (memanfaatkan RFC7807)
Agar klien dapat memahami dan menangani error dengan lebih jelas, diusulkan cara mengirim pesan error terstruktur dengan memanfaatkan standar RFC7807.
- Elemen utama RFC7807:
type: URI yang mengidentifikasi jenis error (contoh:https://example.com/errors/validation).title: deskripsi singkat satu baris tentang error.status: sama dengan kode status HTTP.detail: penjelasan error terperinci yang dapat dibaca manusia.instance: URI spesifik tempat error terjadi (contoh:/api/users/abc).extensions: objek JSON yang memuat informasi tambahan (contoh:invalid_field,expected_format).
- Implementasi:
-
Membuat struct
RFC7807Errordan memasukkan elemen-elemen utamanya. -
Dengan pola method chaining (
WithType(),WithInstance(),WithExtension()), objek error terstruktur dapat dibuat dengan mudah. -
Melalui method
ToHttpError(),RFC7807Errordapat diubah menjadiHttpErrorsehingga bisa dihubungkan dengan router terpusat. -
Klien dapat mengetahui dengan jelas jenis error, penyebabnya, lokasi terjadinya, dan sebagainya.
-
Meningkatkan konsistensi dan kegunaan respons API sehingga efisiensi pengembangan klien ikut naik.
-
5 komentar
Terima kasih untuk artikelnya yang bagus.
Terima kasih untuk tulisannya yang bagus!
Sebagai referensi, di Spring ada implementasinya pada library
spring-web>org.springframework.http.ProblemDetail!Terima kasih untuk pengantarnya yang bagus!
Setelah saya cek, ternyata sudah digantikan oleh RFC 9457.
https://datatracker.ietf.org/doc/html/rfc9457
(Dokumen 7807 sebelumnya: https://datatracker.ietf.org/doc/html/rfc7807)
Perbedaan utama antara RFC 7807 dan RFC 9457
errorsdi dalam satu jenis masalahpointerUntuk proyek baru setelah Juli 2023, disarankan menerapkan RFC 9457
Field
typetampaknya disarankan untuk diatur sebagai URI yang dapat didereferensikan.Untuk layanan internal, sepertinya tidak masalah jika diganti dengan tautan dokumentasi Swagger-ui.