0Pricing
Java Academy · レッスン

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=true

ErrorResponseException

サービスコードから 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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Bean Validation:@NotNull、@Size、@Pattern
  2. カスタム制約アノテーション
  3. @ControllerAdviceによるグローバル例外処理
  4. RFC 7807 Problem Detailsと一貫したエラーレスポンス
← Java Academyに戻る