RFC 7807 Problem Detailsと一貫したエラーレスポンス
Spring 6のProblemDetailを使い、RFC 7807に準拠した構造化エラーペイロードを返します。
「RFC 7807 Problem Detailsと一貫したエラーレスポンス」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
RFC 7807 とは
RFC 7807 の「Problem Details for HTTP APIs」は、エラーレスポンス用の標準 JSON 形式を定義しています。API ごとに独自のエラー形式を用意する必要がなくなり、クライアントは予測可能な構造を解析できます。
RFC 7807 のフィールド
標準フィールドは次のとおりです。type(問題を識別する URI)、title(人間が読める概要)、status(HTTP ステータスコード)、detail(具体的な説明)、instance(特定の発生事例を示す URI)。
{
"type": "https://api.example.com/errors/not-found",
"title": "Resource Not Found",
"status": 404,
"detail": "User with id 42 does not exist.",
"instance": "/api/users/42"
}Spring 6 の ProblemDetail
Spring 6 / Spring Boot 3 には、ProblemDetail のサポートが組み込まれています。例外ハンドラーから ProblemDetail を返すか、ErrorResponseException を使用します。
import org.springframework.http.ProblemDetail;
@ExceptionHandler(ResourceNotFoundException.class)
public ProblemDetail handleNotFound(ResourceNotFoundException ex, HttpServletRequest req) {
ProblemDetail pd = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage());
pd.setType(URI.create("https://api.example.com/errors/not-found"));
pd.setTitle("Resource Not Found");
pd.setInstance(URI.create(req.getRequestURI()));
return pd;
}カスタム拡張の追加
ProblemDetail では、setProperty(key, value) を使用して拡張プロパティを追加できます。エラーコードやフィールドエラーなど、ドメイン固有の詳細を追加する場合に便利です。
ProblemDetail pd = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
pd.setTitle("Validation Failed");
pd.setProperty("errors", fieldErrors); // custom extension
pd.setProperty("timestamp", Instant.now());Spring MVC で RFC 7807 を有効にする
application.properties で spring.mvc.problemdetails.enabled=true を設定すると、組み込みの Spring 例外に対して ProblemDetail を有効にできます。Spring は標準例外(404、405 など)を RFC 7807 形式で自動的にラップします。
# application.properties:
spring.mvc.problemdetails.enabled=trueErrorResponseException
サービスコードから ErrorResponseException をスローすると、ハンドラーメソッドを用意しなくても RFC 7807 レスポンスを生成できます。Spring MVC が例外を捕捉して形式を整えます。
throw new ErrorResponseException(HttpStatus.CONFLICT,
ProblemDetail.forStatusAndDetail(HttpStatus.CONFLICT,
"Email already exists: " + email), null);カスタム ProblemDetail サブクラス
ProblemDetail のドメイン固有のサブクラスを作成すると、型付きの拡張フィールドを追加でき、ハンドラーコードを簡潔に保てます。
public class ValidationProblemDetail extends ProblemDetail {
private final Map<String, String> fieldErrors;
public ValidationProblemDetail(Map<String, String> errors) {
super(HttpStatus.BAD_REQUEST.value());
this.fieldErrors = errors;
setTitle("Validation Failed");
setProperty("fieldErrors", errors);
}
}Content Type: application/problem+json
RFC 7807 のレスポンスでは、通常の JSON ペイロードと問題レスポンスをクライアントが区別できるように、コンテンツタイプ application/problem+json を使用します。
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.contentType(MediaType.APPLICATION_PROBLEM_JSON)
.body(pd);一貫したエラー構造のチェックリスト
適切なエラー API には、(1) 機械可読な type URI、(2) 人間が読める title、(3) 正確な HTTP ステータスコード、(4) 具体的な detail メッセージ、(5) リクエストの instance URI、(6) 任意の拡張フィールド(タイムスタンプ、traceId、フィールドエラー)が含まれます。
可観測性のためのトレース ID
リクエストのトレース ID(Micrometer Tracing または MDC から取得)を拡張プロパティとして追加すると、エラーログを、失敗した特定のリクエストと関連付けられます。
pd.setProperty("traceId", MDC.get("traceId"));
pd.setProperty("timestamp", Instant.now());Problem Details のテスト
@WebMvcTest のテストでは、レスポンスのコンテンツタイプが application/problem+json であることを検証し、status、title、detail などの JSON フィールドが期待値と一致することを確認します。
mockMvc.perform(get("/api/users/999"))
.andExpect(status().isNotFound())
.andExpect(content().contentType("application/problem+json"))
.andExpect(jsonPath("$.status").value(404))
.andExpect(jsonPath("$.title").value("Resource Not Found"));クイックチェック
組み込みの Spring MVC 例外に対して RFC 7807 を有効にする Spring Boot のプロパティはどれですか?
まとめ
RFC 7807 は、type、title、status、detail、instance フィールドによって JSON エラーレスポンスを標準化します。Spring 6 には ProblemDetail と ErrorResponseException が用意されています。spring.mvc.problemdetails.enabled=true で有効にします。可観測性を高めるため、traceId と timestamp を拡張フィールドとして追加します。
よくある質問
「RFC 7807 Problem Detailsと一貫したエラーレスポンス」レッスンは無料ですか?
はい。「RFC 7807 Problem Detailsと一貫したエラーレスポンス」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「RFC 7807 Problem Detailsと一貫したエラーレスポンス」で何を学びますか?
Spring 6のProblemDetailを使い、RFC 7807に準拠した構造化エラーペイロードを返します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「RFC 7807 Problem Detailsと一貫したエラーレスポンス」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Bean Validation:@NotNull、@Size、@Pattern
- カスタム制約アノテーション
- @ControllerAdviceによるグローバル例外処理
- RFC 7807 Problem Detailsと一貫したエラーレスポンス