カテゴリ: Spring 更新日: 2026/01/09

Spring Bootの共通エラーレスポンス設計:Problem+JSON風フォーマットを作る

Spring Bootの共通エラーレスポンス設計:Problem+JSON風フォーマットを作る
Spring Bootの共通エラーレスポンス設計:Problem+JSON風フォーマットを作る

教材紹介 Spring Boot 学習のおすすめ教材

Spring Bootを使ったWebアプリケーション開発を、 環境構築から実践まで一通り学びたい方には、 定評のある入門書が参考になります。

Spring Boot 3 プログラミング入門をAmazonで見る

※ Amazon広告リンク

先生と生徒の会話形式で理解しよう

生徒

「Spring Bootでエラーメッセージを統一した形で返す方法ってありますか?」

先生

「良い視点ですね。REST APIの開発では、共通のエラーレスポンスを設計しておくことで、利用者がとても理解しやすくなります。」

生徒

「なるほど!具体的にはどんなフォーマットが使われてるんですか?」

先生

「最近では、Problem+JSON形式という標準に沿ったフォーマットを参考にした設計がよく使われています。それでは、実装のポイントを一緒に見ていきましょう。」

1. Spring Bootで共通エラーレスポンスを作る理由とは?

1. Spring Bootで共通エラーレスポンスを作る理由とは?
1. Spring Bootで共通エラーレスポンスを作る理由とは?

Spring BootのREST APIでは、バリデーションエラーや認可エラー、内部サーバーエラーなど様々なエラーが発生します。これらをすべてバラバラの形式で返してしまうと、フロントエンド側やクライアント側が扱いにくくなります。

そこで登場するのが「共通エラーレスポンス設計」です。これにより、すべてのエラーが統一された形式で返され、API利用者はエラーをパースしやすくなります。

その中でも注目されているのが「Problem+JSON」風のフォーマットです。RFC7807という仕様に基づいており、エラー情報をtypetitlestatusdetailinstanceといった項目で表現します。

2. Problem+JSON風フォーマットの基本構造

2. Problem+JSON風フォーマットの基本構造
2. Problem+JSON風フォーマットの基本構造

Problem+JSON形式は、次のようなJSON構造でエラー情報を返すことを前提としています:


{
    "type": "https://example.com/errors/not-found",
    "title": "Resource Not Found",
    "status": 404,
    "detail": "指定されたユーザーが見つかりません。",
    "instance": "/api/users/123"
}

この構造のメリットは、API利用者がstatusコードだけでなく、typetitleなどでエラーの種類や発生場所を把握しやすくなる点にあります。

3. Spring Bootで共通エラーのレスポンスクラスを作成

3. Spring Bootで共通エラーのレスポンスクラスを作成
3. Spring Bootで共通エラーのレスポンスクラスを作成

まずは、共通のレスポンスとして使うクラスを作成します。Javaで@Builder@Getterを使えば、簡単に定義できます。


public class ApiError {
    private String type;
    private String title;
    private int status;
    private String detail;
    private String instance;

    // コンストラクタやgetter/setterはLombokでもOK
}

Spring FrameworkやThymeleafを使った Webアプリ開発の全体像をやさしく理解したい人には、 この入門書が定番です。

Spring Framework超入門をAmazonで見る

※ Amazon広告リンク

4. @ControllerAdviceを使って例外をグローバルにハンドリング

4. @ControllerAdviceを使って例外をグローバルにハンドリング
4. @ControllerAdviceを使って例外をグローバルにハンドリング

Spring Bootで例外を一元的に扱うには、@ControllerAdviceを使います。これを使うことで、全コントローラに対する例外処理を共通化できます。


@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ApiError> handleNotFound(ResourceNotFoundException ex, HttpServletRequest request) {
        ApiError error = new ApiError();
        error.setType("https://example.com/errors/not-found");
        error.setTitle("リソースが見つかりません");
        error.setStatus(HttpStatus.NOT_FOUND.value());
        error.setDetail(ex.getMessage());
        error.setInstance(request.getRequestURI());

        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
    }

    // 他の例外も同様に追加可能
}

5. 実際のレスポンス例

5. 実際のレスポンス例
5. 実際のレスポンス例

たとえば、存在しないユーザーIDを指定してリクエストした場合、次のようなエラーが返されます。


{
"type": "https://example.com/errors/not-found",
"title": "リソースが見つかりません",
"status": 404,
"detail": "ユーザーIDが存在しません。",
"instance": "/api/users/999"
}

これにより、フロントエンド側はレスポンスのstatustypeを見て、適切な処理(アラート表示や遷移)を実装できます。

6. Problem+JSON形式に合わせたContent-Typeの指定

6. Problem+JSON形式に合わせたContent-Typeの指定
6. Problem+JSON形式に合わせたContent-Typeの指定

RFC7807に準拠するなら、Content-Typeヘッダーにapplication/problem+jsonを指定します。

Spring BootでContent-Typeを返すには、レスポンスエンティティに設定を加えます。


return ResponseEntity
    .status(HttpStatus.NOT_FOUND)
    .contentType(MediaType.valueOf("application/problem+json"))
    .body(error);

7. 独自のバリデーションエラーや認可エラーにも対応

7. 独自のバリデーションエラーや認可エラーにも対応
7. 独自のバリデーションエラーや認可エラーにも対応

MethodArgumentNotValidExceptionなどのバリデーションエラーも、Problem+JSON形式で返すことで、クライアントはdetailの内容を元にフィールドごとのエラーメッセージを表示できます。

また、AccessDeniedExceptionAuthenticationExceptionに対しても、適切なstatustitleを返すように設計しておくと、セキュリティ面での制御がしやすくなります。

8. Spring BootでAPIエラーを美しく扱うコツ

8. Spring BootでAPIエラーを美しく扱うコツ
8. Spring BootでAPIエラーを美しく扱うコツ

Spring Bootでの共通エラーレスポンス設計は、API開発において非常に重要な要素です。Problem+JSON風の統一フォーマットを用いることで、APIの使いやすさや保守性が飛躍的に向上します。

実装はシンプルですが、利用者にとっては大きなメリットとなるため、ぜひ導入を検討してみてください。

まとめ

まとめ
まとめ

Spring Bootにおける共通エラーレスポンス設計の重要性

この記事では、Spring BootでREST APIを開発する際に欠かせない「共通エラーレスポンス設計」について、 Problem+JSON風フォーマットを例に詳しく解説してきました。 API開発では正常系のレスポンスだけでなく、エラー発生時にどのような情報を返すかが非常に重要になります。 エラーレスポンスの形式がバラバラだと、フロントエンドや外部クライアントは実装のたびに個別対応が必要になり、 開発効率や保守性が大きく低下してしまいます。

その点、Problem+JSONを参考にした共通フォーマットを採用することで、 エラーの種類、HTTPステータス、詳細メッセージ、発生箇所といった情報を 一貫した構造で返せるようになります。 Spring BootとSpring MVCの仕組みを活かし、 @ControllerAdviceを使って例外処理を集約することで、 API全体のエラーハンドリングを整理された形で実装できるのが大きな特徴です。

Problem+JSON風フォーマットがもたらすメリット

Problem+JSON風のエラーレスポンスでは、 typetitlestatusdetailinstance といった項目を持たせることで、 人間にもプログラムにも理解しやすいエラー情報を表現できます。 特にstatustypeを組み合わせることで、 クライアント側はエラー内容を機械的に判定しやすくなります。

また、エラーメッセージをdetailに集約しておくことで、 フロントエンド側ではユーザー向けの表示を柔軟に制御できます。 さらに、instanceにリクエストURIを含めることで、 ログ解析や障害調査の際にも役立つ情報を残すことができます。 こうした設計は、規模の大きなAPIや複数人で開発するプロジェクトほど効果を発揮します。

Spring Bootでの実装ポイントを振り返る

実装面では、まず共通で利用するエラーレスポンス用のクラスを定義し、 それを@ControllerAdvice内で組み立てて返却する流れが基本となります。 例外ごとにHTTPステータスやtypeを切り替えることで、 リソース未存在エラー、バリデーションエラー、認可エラーなどを明確に区別できます。

さらに、Content-Typeにapplication/problem+jsonを指定することで、 Problem+JSON形式に近いレスポンスとして扱えるようになります。 このように、Spring Bootの標準機能を活用するだけで、 APIとして完成度の高いエラーハンドリングを実現できる点は大きな魅力です。

まとめとしてのサンプルプログラム

最後に、この記事の内容を振り返るため、 共通エラーレスポンスを返す基本的な構成のサンプルコードを確認してみましょう。 記事内で使用してきたクラス構成や書き方と同じ形式になっています。


@ControllerAdvice
public class SummaryExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ApiError> handleException(Exception ex, HttpServletRequest request) {
        ApiError error = new ApiError();
        error.setType("https://example.com/errors/internal");
        error.setTitle("内部サーバーエラー");
        error.setStatus(500);
        error.setDetail(ex.getMessage());
        error.setInstance(request.getRequestURI());

        return ResponseEntity
                .status(500)
                .contentType(MediaType.valueOf("application/problem+json"))
                .body(error);
    }
}

このような構成を用意しておけば、 どのような例外が発生しても一定のフォーマットでエラー情報を返せるようになります。 API利用者にとっても理解しやすく、 開発者にとっても拡張しやすい設計となるため、 Spring BootでREST APIを開発する際にはぜひ取り入れておきたい考え方です。

先生と生徒の振り返り会話

生徒

「エラーレスポンスって、今まであまり意識していませんでしたが、 共通化するとこんなにメリットがあるんですね。」

先生

「そうですね。APIは使われてこそ価値があります。 エラーがわかりやすいAPIは、それだけで使いやすいと言えます。」

生徒

「Problem+JSON風の形式なら、 ステータスやエラー内容を一目で判断できそうです。」

先生

「その理解で正しいです。 Spring BootとControllerAdviceを組み合わせれば、 きれいな共通エラーレスポンスを無理なく実装できますよ。」

生徒

「これからAPIを作るときは、 最初にエラーレスポンス設計も考えるようにしてみます。」

カテゴリの一覧へ
新着記事
JavaのIndexOutOfBoundsExceptionを完全ガイド!初心者でも理解できる例外処理と回避方法
スッキリわかるJava入門 第4版|独学でもレッスンでも学べる完全ガイド
JavaのCookieクラスのgetCommentメソッドを解説!Servlet開発でクッキーの説明文を取得する方法
JavaのBufferedOutputStreamクラスのwriteメソッドを徹底解説!初心者でもわかるファイルへのバイナリ書き込み
人気記事
No.1
Java&Spring記事人気No1
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.2
Java&Spring記事人気No2
Springの@Serviceアノテーションの使い方を徹底解説!初心者でもわかるSpring フレームワーク入門
No.3
Java&Spring記事人気No3
Thymeleafのth:classappend属性の使い方を完全ガイド!初心者でもわかる動的クラス追加
No.4
Java&Spring記事人気No4
Spring Data JPA入門!findAll()やfindBy**()の使い方などデータベース操作の基礎を学ぶ
No.5
Java&Spring記事人気No5
Spring BootのJakarta移行ガイド!初心者向けjavax→jakarta変更ポイント徹底解説
No.6
Java&Spring記事人気No6
Thymeleaf(タイムリーフ)入門!初心者でもわかるSpring Bootとテンプレートエンジンの使い方
No.7
Java&Spring記事人気No7
Springの@Repositoryアノテーションの使い方を徹底解説!初心者でもわかるSpringフレームワークのデータアクセス
No.8
Java&Spring記事人気No8
SpringのPageableとSortでページング一覧APIを最短実装!初心者向け完全ガイド

💻 作業効率アップに

長時間のコーディングでも疲れにくい♪ 静音ワイヤレスマウス

Logicool Signature M750 を見る

※ Amazon広告リンク