それは非常に古い投稿ですが、私は同様の問題に直面しました。私の経験を皆さんと共有したいと思います。
REST APIを使用してマイクロサービスアーキテクチャを構築しています。残りのGETサービスがいくつかあります。これらのサービスは、リクエストパラメータに基づいてバックエンドシステムからデータを収集します。
残りのAPI設計ドキュメントに従い、クエリ条件に一致するデータがなかった(たとえば、ゼロのレコードが選択された)場合、完全なJSONエラーメッセージを含むHTTP 404をクライアントに送り返しました。
クライアントに送り返すデータがない場合、「Not Found」の理由をクライアントに通知するために、内部エラーコードなどを含む完全なJSONメッセージを準備し、HTTP 404でクライアントに送り返しました。正常に動作します。
後で、HTTP通信関連のコードを非表示にする簡単なヘルパーであるREST APIクライアントクラスを作成しました。コードからREST APIを呼び出すときは常にこのヘルパーを使用しました。
しかし、HTTP 404に2つの異なる機能があるため、混乱を招く追加コードを記述する必要がありました。
- 残りのAPIが指定されたURLで使用できない場合の実際のHTTP404。これは、残りのAPIアプリケーションが実行されるアプリケーションサーバーまたはWebサーバーによってスローされます。
- クエリのwhere条件に基づいてデータベースにデータがない場合も、クライアントはHTTP 404を返します。
重要:残りのAPIエラーハンドラーがすべての例外をキャッチし、バックエンドサービスに表示されます。つまり、エラーが発生した場合、残りのAPIは常にメッセージの詳細を含む完全なJSONメッセージを返します。
これは、2つの異なるHTTP 404応答を処理するクライアントヘルパーメソッドの最初のバージョンです。
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");
}
しかし、私のJavaまたはJavaScriptクライアントは2種類のHTTP 404を何らかの方法で受信できるため、HTTP 404の場合は応答の本文を確認する必要があります。応答の本文を解析できれば、確実に応答が返されますクライアントに送り返すデータはありません。
応答を解析できない場合は、Webサーバーから(残りのAPIアプリケーションからではなく)実際のHTTP 404が返されたことを意味します。
これは非常にわかりにくく、クライアントアプリケーションは常にHTTP 404の実際の理由をチェックするために追加の解析を行う必要があります。
正直なところ、私はこのソリューションが好きではありません。混乱を招き、常にクライアントにでたらめなコードを追加する必要があります。
したがって、この2つの異なるシナリオでHTTP 404を使用する代わりに、以下を実行することにしました。
- 残りのアプリケーションでHTTP 404を応答HTTPコードとして使用しなくなりました。
- HTTP 404の代わりにHTTP 204(コンテンツなし)を使用します。
その場合、クライアントコードはよりエレガントになります。
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);
}
これはその問題をよりよく処理すると思います。
より良い解決策があれば、私たちと共有してください。