Itu adalah posting yang sangat lama tetapi saya menghadapi masalah yang sama dan saya ingin berbagi pengalaman saya dengan kalian.
Saya sedang membangun arsitektur microservice dengan API lainnya. Saya punya beberapa layanan GET istirahat, mereka mengumpulkan data dari sistem back-end berdasarkan parameter permintaan.
Saya mengikuti dokumen desain API lainnya dan saya mengirim kembali HTTP 404 dengan pesan kesalahan JSON yang sempurna ke klien ketika tidak ada data yang selaras dengan kondisi kueri (misalnya, nol catatan dipilih).
Ketika tidak ada data untuk dikirim kembali ke klien saya menyiapkan pesan JSON sempurna dengan kode kesalahan internal, dll. Untuk menginformasikan klien tentang alasan "Tidak Ditemukan" dan itu dikirim kembali ke klien dengan HTTP 404. Itu bekerja dengan baik.
Kemudian saya telah membuat kelas klien API sisanya yang merupakan bantuan mudah untuk menyembunyikan kode terkait komunikasi HTTP dan saya menggunakan bantuan ini setiap saat ketika saya memanggil API sisanya dari kode saya.
TETAPI saya perlu menulis kode tambahan yang membingungkan hanya karena HTTP 404 memiliki dua fungsi berbeda:
- HTTP 404 asli ketika API sisanya tidak tersedia di url yang diberikan, itu dilemparkan oleh server aplikasi atau server web tempat aplikasi API lainnya berjalan
- klien mendapatkan kembali HTTP 404 juga ketika tidak ada data dalam database berdasarkan kondisi permintaan di mana.
Penting: Penangan kesalahan API istirahat saya menangkap semua pengecualian yang muncul di layanan back-end yang berarti jika terjadi kesalahan, API sisanya selalu kembali dengan pesan JSON sempurna dengan detail pesan.
Ini adalah versi pertama dari metode pembantu klien saya yang menangani dua respons HTTP 404 yang berbeda:
public static String getSomething(final String uuid) {
String serviceUrl = getServiceUrl();
String path = "user/" + , uuid);
String requestUrl = serviceUrl + path;
String httpMethod = "GET";
Response response = client
.target(serviceUrl)
.path(path)
.request(ExtendedMediaType.APPLICATION_UTF8)
.get();
if (response.getStatus() == Response.Status.OK.getStatusCode()) {
// HTTP 200
return response.readEntity(String.class);
} else {
// confusing code comes here just because
// I need to decide the type of HTTP 404...
// trying to parse response body
try {
String responseBody = response.readEntity(String.class);
ObjectMapper mapper = new ObjectMapper();
ErrorInfo errorInfo = mapper.readValue(responseBody, ErrorInfo.class);
// re-throw the original exception
throw new MyException(errorInfo);
} catch (IOException e) {
// this is a real HTTP 404
throw new ServiceUnavailableError(response, requestUrl, httpMethod);
}
// this exception will never be thrown
throw new Exception("UNEXPECTED ERRORS, BETTER IF YOU DO NOT SEE IT IN THE LOG");
}
TAPI , karena klien Java atau JavaScript saya dapat menerima dua jenis HTTP 404, entah bagaimana, saya perlu memeriksa isi respons jika ada HTTP 404. Jika saya dapat menguraikan respons, maka saya yakin saya mendapatkan kembali respons di mana ada tidak ada data untuk dikirim kembali ke klien.
Jika saya tidak dapat menguraikan respons itu berarti saya mendapatkan kembali HTTP 404 nyata dari server web (bukan dari aplikasi API lainnya).
Sangat membingungkan dan aplikasi klien selalu perlu melakukan parsing ekstra untuk memeriksa alasan sebenarnya dari HTTP 404.
Jujur saya tidak suka solusi ini. Ini membingungkan, perlu menambahkan kode omong kosong tambahan ke klien sepanjang waktu.
Jadi alih-alih menggunakan HTTP 404 dalam dua skenario berbeda ini, saya memutuskan untuk melakukan hal berikut:
- Saya tidak menggunakan HTTP 404 sebagai respons kode HTTP dalam aplikasi lain saya.
- Saya akan menggunakan HTTP 204 (Tidak Ada Konten) alih-alih HTTP 404.
Dalam hal ini kode klien bisa lebih elegan:
public static String getString(final String processId, final String key) {
String serviceUrl = getServiceUrl();
String path = String.format("key/%s", key);
String requestUrl = serviceUrl + path;
String httpMethod = "GET";
log(requestUrl);
Response response = client
.target(serviceUrl)
.path(path)
.request(ExtendedMediaType.APPLICATION_JSON_UTF8)
.header(CustomHttpHeader.PROCESS_ID, processId)
.get();
if (response.getStatus() == Response.Status.OK.getStatusCode()) {
return response.readEntity(String.class);
} else {
String body = response.readEntity(String.class);
ObjectMapper mapper = new ObjectMapper();
ErrorInfo errorInfo = mapper.readValue(body, ErrorInfo.class);
throw new MyException(errorInfo);
}
throw new AnyServerError(response, requestUrl, httpMethod);
}
Saya pikir ini menangani masalah itu dengan lebih baik.
Jika Anda memiliki solusi yang lebih baik, silakan bagikan dengan kami.