Fessのv2 APIクライアントでJSON本文と応答型を確認する

Fessのv2 APIを自作クライアントから呼ぶとき、正しいJSONでも本文の最上位が配列やnullだと受け付けられません。JSON本文の検証修正と、実際の応答に合わせたOpenAPI・リファレンスの訂正をまとめて確認します。

JSON本文はUTF-8のオブジェクトにする

ログイン、クリック記録、パスワード変更、タグ、お気に入り、チャットなど、共通のJSON本文読み込みを使うAPIが対象です。Content-Type: application/jsonを指定し、文字コードを明示する場合もUTF-8を使います。

修正後は最上位のnull、配列、文字列、数値、真偽値をHTTP 400、invalid_requestとして拒否します。オブジェクト内のnull、たとえば{"a":null}はJSONの構造として読み取れますが、各APIの必須項目の検証は別に実行されます。

不正なUTF-8バイト列も400になります。以前のように代替文字へ置き換えてタグ名などを保存しません。先頭のUTF-8 BOMは読み取り時に除去します。0バイトの本文は空オブジェクト相当として読み取る仕様を維持し、空白だけの本文や未入力の必須フィールドまで成功とするものではありません。

この検証を有効にする設定は追加していません。各APIの認証、CSRF、本文サイズ制限は従来の条件に従い、サイズ上限は呼び出すAPIで決まります。400では本文を修正し、文字コードやContent-Typeによる415、サイズによる413とは区別して扱います。

生成クライアントの数値型を確認する

検索ヒットのcontent_lengthとboostは、クローラーが保存した文書では"9894"、"1.0"のような文字列です。OpenAPIで整数・数値とされていた定義を文字列へ訂正しました。管理用documents APIから登録した文書ではJSON数値を持つ場合もあるため、実データを確認し、必要ならクライアント側で両形式を扱います。

検索語がない場合のhighlight_paramsはnullになり得ます。更新された定義からクライアントを再生成し、検索語なしの応答もデシリアライズできるか確認してください。定義上の型が変わっても、サーバーがここで既存文書を変換するわけではありません。

UI設定と認証エラーにも対応する

/api/v2/ui/configのfeatures.login_linkは真偽値だけでなく、SSO利用時には相対URLの"sso/"になる場合があります。default_label_valuesやdefault_sortは画面の初期選択用で、/api/v2/searchが自動適用する値ではありません。

サジェストのnumの初期値は10で、page_sizeは実際に返された語数です。語数が要求より少なくても異常と決め付けないでください。各APIはログイン必須設定や無効なトークンなどの条件で401を返し、デコード不能なクエリ文字列では処理前に400になり得ます。

実環境に近い検索文書、検索語なし、認証失敗、SSO設定の組み合わせでクライアントを確認すると、正常系だけでは見つからない型の不一致を減らせます。

関連PR

Fessのデータクロールで最後の一括登録失敗を確認しやすくする

データクロールでは、取得できた文書が検索エンジンのマッピングに合わず、一括登録の最後のバッチだけが失敗することがあります。Fessで、文書単位の失敗理由をWARNへ出す変更と、最終コミットの失敗をクロールログ・障害URLへ記録する変更がマージされました。

文書単位の拒否理由

従来は一括登録で拒否された文書の情報がDEBUG中心で、通常運用のログでは対象や理由が分かりにくい状態でした。修正後は、拒否された各文書についてURL、ID、ステータス、エラー種別、理由をWARNに記録します。

理由の長さは500文字までに制限します。マッピングエラーが付加するフィールド値のプレビューはログから除きます。ただし、#3616と#3624だけでは、後続の例外メッセージや数値変換の理由にフィールド値が残る経路があります。#3643はこれらも除去する提案ですが、今回の取得時点では未マージです。ログと障害URLに文書内容が絶対に含まれないとは扱わず、共有前に内容を確認してください。設定項目を追加して有効化する方式ではなく、修正された処理のログ出力が変わります。WARNが出力されるログレベルで運用することが必要です。

送信文書数と応答件数が一致せずURLを対応付けられない場合、URLはnullとなります。文書IDなど他の情報で調べます。文書単位の問題としてWARNにしているため、この出力だけでERROR通知が発生するとは限りません。

最終コミット失敗も記録する

データストアの処理終了時には、まだバッファーに残った文書をコミットします。この処理で例外が発生すると、修正前はクロールスレッドの未捕捉例外となり、クロールログや障害URLへ記録されない場合がありました。

修正後は例外を捕捉し、ERRORログと障害URLに記録します。最終コミットが失敗した場合は、その後の古い文書削除を実行しません。登録に失敗した文書が置き換えるはずだった既存文書を、削除処理で消さないためです。

調査と再実行

取得件数と登録件数が合わない場合は、WARNの文書ID・エラー種別、最終コミットのERROR、該当データ設定の障害URLを確認します。たとえばmapper_parsing_exceptionなら、送信した値の型と検索インデックスのマッピングを比較します。型や変換処理を直してからクロールを再実行します。

文書単位のWARN処理自体が、各拒否文書をすべて障害URLとして登録するわけではありません。最終コミットの失敗記録はデータクロール設定の単位です。また、今回の変更は失敗の可視化であり、自動再試行やマッピングの修復を追加するものではありません。

関連PR

FessのS3・GCS一覧が空のとき、接続失敗と区別するための修正案

Fessのストレージ画面でファイルが見つからないとき、バケットが空なのか、認証や接続に失敗しているのかは区別したいところです。S3・GCSストレージプラグインでは、一覧取得中の例外を捕まえて空または途中までの一覧を返す経路がありました。そのため、取得失敗が正常な「0件」に見えることがあります。

この動作を改善するS3側のPR #4とGCS側のPR #6が提案されています。2026年10月17日の確認時点では両方とも未マージです。以下は修正案の説明であり、Fess 15.9.0や公開済みプラグインに反映済みという案内ではありません。

一覧取得の失敗を呼び出し元へ伝える

修正案では、listObjects内で発生した例外をStorageExceptionとして呼び出し元へ伝えます。メッセージには対象のバケットとprefixが入り、元の例外も原因として保持します。GCSでは一覧ページの取得だけでなく、結果を走査している途中の失敗も対象です。

Fess 15.9.0側の管理処理には、例外を受けてストレージアクセスエラーにする経路があります。プラグイン側で例外を握りつぶさなければ、管理画面・管理APIで正常な空一覧と区別できるようになります。

ただし、すべてのエラーが新しい動作になるわけではありません。S3のNoSuchBucketExceptionは従来どおりINFOログを記録し、空の一覧を返す扱いが残ります。GCSの修正案は、存在しないバケット等の取得例外もエラーとして伝えます。S3とGCSで「バケットがない」場合の動作は揃っていません。

空の一覧が返る場合に確認すること

この修正で新しい有効化設定は追加されません。利用には、対象のストレージ種類に合うプラグイン、バケット、認証情報、接続先の設定が必要です。修正を試す場合は、対応PRを含むプラグインを検証環境へ導入し、Fess本体との互換性も確認してください。未マージの修正が既存環境へ自動適用されることはありません。

既存環境で一覧が空なら、まず次を確認します。

  • ストレージ種類とプラグインが一致しているか。プラグインを導入・変更した場合はFessを再起動したか。
  • エンドポイント、バケット名、リージョンまたはプロジェクト、認証情報が対象環境に合っているか。
  • 実行環境から接続先へ到達でき、オブジェクト一覧を取得する権限があるか。
  • 指定したprefixが正しいか。サブディレクトリ相当のprefixを指定していれば、別の場所にあるオブジェクトは表示されない。

Fess側でプラグインが見つからない、認証情報が未設定といった初期化エラーを表示できても、その後のプラグイン内部の一覧取得失敗まで常に表示できるとは限りません。修正前の環境では「0件、成功」という応答だけで接続正常と判断しないようにします。

件数制限やダウンロードの問題とは分けて考える

正常に取得できた空バケットは、修正後も空の一覧です。また、Fess 15.9.0のstorage.max.items.in.pageの初期値は1000で、このPRは上限やページングを変更しません。画面に見える一覧だけでバケット内の全オブジェクト数を判断することはできません。

対象はオブジェクト一覧の失敗通知です。ダウンロード、アップロード、削除の動作や、接続可否を調べる別のメソッドを一括で変える修正ではありません。自動再試行や認証情報の修復も追加されません。

導入を検討する際は、正常な空バケット、オブジェクトのあるprefix、接続先へ到達できない状態をそれぞれ確認すると、0件と失敗を区別できるかを確かめやすくなります。S3の存在しないバケットの例外扱いも、運用監視の条件に含めてください。

関連PR