0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Java 21】APIレスポンスライブラリを自作した話

0
Last updated at Posted at 2026-02-16

はじめに

私はフルスタックエンジニアとしてインターンに従事しています。
実務でAPI開発に携わる中で、フロントエンドとバックエンドの連携を円滑にする「共通レスポンス形式」の重要性を痛感しました。

そこで、単なるデータ返却だけでなく、「開発時の利便性」と「本番環境での情報漏洩防止」をライブラリレベルで解決することを目指し、SasatoResLib を開発しました。

開発の背景

開発を経験する中で、以下の課題を感じました。

  1. エラー情報の露出: 本番環境でスタックトレースがそのまま返ってしまうことによる、内部構造の露呈リスク。
  2. 機密情報の混入: ログやエラー詳細に、パスワードやトークンが意図せず含まれてしまうリスク。

これらを「実装時の注意」に頼るのではなく、「ライブラリの仕組み」として解決したいと考えました。

技術スタック

  • Language: Java 21 (LTS)
  • Build Tool: Gradle 8.5
  • Test Framework: JUnit 5
  • CI/CD: GitHub Releases

こだわったポイント

1. デバッグモードによる自動隠蔽ロジック

環境変数や設定一つで詳細情報の露出をコントロールできるようにしました。

// デフォルト(debugMode=false)ではスタックトレースを自動隠蔽
public String getStackTrace() {
    return isDebugMode ? stackTrace : "Access Denied: Set debug mode to true to see details.";
}

2. 正規表現による自動サニタイズ

リクエスト詳細に含まれる password や token などの機密情報を、正規表現を用いて自動的にマスクします。

private static final Pattern SENSITIVE_PATTERN =
        Pattern.compile("(?i)(password|token|secret|apiKey|auth|credential|card_no)=[^&\\s,]*");

private String sanitize(String details) {
    if (details == null) return null;
    return SENSITIVE_PATTERN.matcher(details).replaceAll("$1=********");
}

3. 一貫したメタ情報の付与

すべてのレスポンスにUUIDベースの requestId と、ナノ秒単位で計算された processingTimeMs を付与。これにより、トラブルシューティングとパフォーマンス計測を容易にしました。

苦労した点:フロントエンドの知識不足

フロントエンドとバックエンドの連携を円滑にすると意気込んだものの、私は今までバックエンドをメインで開発していたので、ぶっちゃけますと

フロントエンドが使いやすい形式がわかりません!!!!

そんな中どうこの最大の難点を解決したかというと、AIで解決しました。
今回、AIにペルソナ(人物像)を与え、大手企業のCTOでフロントエンドエンジニアという設定を与え、新入社員である私が書いたコードを採用するにはどこを修正すべきか。
私が書いたコードをレビューしてもらう擬似的なコードレビューを繰り返しました。

AIとの対話で改善した「フロントエンド視点」の工夫

「新入社員の私が書いたこのライブラリを、現場で採用するには何が足りないか?」と問いかけ、以下のフィードバックを得て実装に反映しました。

成功・失敗の判定を1行で:
フロントエンドが毎回HTTPステータスコードを細かく判定しなくても、statusCode という共通のフィールドを見るだけで処理を分岐できるように設計。

メタ情報の標準化:
デバッグ時に「どのリクエストでエラーが起きたか」を即座に特定できるよう、UUIDを用いた requestId をレスポンスに含める重要性を学びました。

ページネーションの共通化:
フロントエンドのUIコンポーネントがそのまま受け取れる totalCount, limit, offset を構造化して返す形式を採用。

実装とテストによる裏付け

バックエンド側のロジックが正しいことは、JUnit 5を用いた単体テストで徹底的に検証しました。
「フロントエンドが求める仕様」をAIから引き出し、それを「堅牢なコード」としてJava 21で実装する。このサイクルを回すことで、知識不足を補うだけでなく、実務でも通用するレベルの設計思想を身につけることができました。

まとめ

今回の開発を通して一番の収穫だったのは、「自分に足りない視点をAIで補い、それを確かな技術で形にする」 というプロセスを経験できたことです。

バックエンド専攻の私にとって、フロントエンドの使い勝手は未知の領域でした。
しかし、AIにペルソナを与えて対話を繰り返すことで、「実務で求められる仕様」の解像度を爆速で上げることができました。

もちろん、AIが提示した設計が本当に正しいか、そして安全かを判断し、テストを書くのは、人間の仕事です。

これからAIがコードを書く時代。
どうAIを使いこなすのか、AIを扱う人材をどう教育するのか、未来が楽しみですね


リポジトリ

GitHub: SasatoResLib

ライブラリの解説記事

Qiita:APIレスポンスの「標準化」と「多層防御」を1行で実現するライブラリ


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?