API:Implementation Strategy/ja

これは MediaWiki コアの API の機構の実行方法を説明します. API をコードを書いてクライアントに使用してもらうにはAPI:Extensionsをご参照ください.

ファイル/モジュール構造

 * api.phpはエントリポイントで、mediawikiのrootに設置されています
 * includes/apiはapiに関連したすべてのファイルを含みますが、それらのうちどれもエントリポイントとしては許可されません
 * すべてのapiクラスは共通の抽象クラスであるApiBaseから派生します. パラメータの解析、プロファイリング、とエラーハンドリングといった基本クラスは共通の機能性を提供します.
 * ApiMain はapi.php によって例示されるメインクラスです. action=XXX パラメータに基づき実施するモジュールを決定します. ApiMain により出力データの配列と関連のヘルパー機能を内蔵する ApiResult クラスをインスタンス化します. 最後に ApiMain は形式設定クラスをインスタンス化、ApiResult から XML/JSON/PHP その他の形式でデータをクライアントに出力します.
 * ApiBaseから派生したどのモジュールもインスタンス化する間にApiMainのインスタンスへの参照を受け取るので、実行の間にモジュールは結果のオブジェクトといった共有リソースを取得することがあります.

クエリモジュール

 * ApiQueryはサブモジュールを実行するという点でAPiMainと同じ振る舞いをします. それぞれのサブモジュールはApiQueryBaseから派生します(トップレベルのモジュールであるApiQuery自身は除く. インスタンス化する間、サブモジュールはApiQueryのインスタンスへの参照を受け取ります.
 * 拡張クエリモジュールは全て、必ず3文字以上の接頭辞を付けます. コアモジュール接頭辞は2文字です.
 * ApiQueryの実行プラン:
 * 必要なサブモジュールを決定するために共有クエリパラメータlist/prop/metaを取得する.
 * ApiPageSetオブジェクトを作りtitles/pageids/revidsパラメータからそれを投入する. pagesetオブジェクトはクエリモジュールが連携するページもしくはリビジョンの一覧を含みます. モジュールの中には単独のページのみを含むpagesetを必要とするものがあることにご注意お願いします.
 * 必要な場合、別のPageSetを作るためにgeneratorモジュールが実行されます - UNIXでストリームをパイプするのと似ています - 任意のページは取り組む他のすべてのモジュールに対してページの別の一式を生み出すgeneratorへの入力です.
 * クエリ継続の必要条件：
 * SQL クエリは完全に順序付けする必要があります. 言い換えるなら、クエリは全ての列を使い、特定の固有のキーをWHERE節もしくはORDER BY節にある定数として提供します.
 * MySQL ではこれはexclusive orであり、クエリの Foo と Bar のどちらも名前空間順ではなくページ名順に並べ (名前空間は定数 0)、Foo と Talk:Foo はページ名順ではなく名前空間順に並べ (ページ名は定数 "Foo")、Foo と Talk:Bar は名前空間じゅんとページ名順の両方にしたがって並べる必要があります.
 * SQL クエリは filesort (クイックソート) してはいけません.
 * に与える値は ORDER BY 節の全列を含みます.
 * 継続するには WHERE 節に単一の複合条件を追加します. クエリに が含まれると、この条件は次のような形になります. (column_0 > value_0 OR (column_0 = value_0 AND&#xa; (column_1 > value_1 OR (column_1 = value_1 AND&#xa; (column_2 >= value_2)&#xa; ))&#xa;)) もちろん、ORDER BY 列が DESC を使用する場合は「>」を「<」に置換します. 値に SQL を導入しないよう注意します.

内部のデータ構造

 * クエリのAPIは1つのたらい回しにされるグローバルな入れ子のarray構造のとても連続した構造を持ちます. 様々なモジュールはデータのピースを多くの異なる配列のポイントに追加し、最後には、それはプリンター (出力モジュール) の1つによるクライアントに対してレンダリングされます. APIのために、筆者はこの配列を個別のleafノードを追加するヘルパー関数を持つクラスとしてラップすることを提案します.

エラー/ステータスの報告
これまで開発者達はエラー情報を通常の結果として同じ構造化された出力に含めることを決定しました(オプション #2).

結果に関して、標準的なHTTPエラーコードを使うもしくは適切にフォーマットされたデータを返すかのどちらかを行うことになります:

void header( string reason_phrase [, bool replace [, int http_response_code]] ) The headerはオペレーションの返り値ステータスを設定するために使うことができます. reason_phraseの可能なすべての値を定義できるので、失敗したログインに関してはcode=403とphrase="BadPassword"を返す一方で、成功した場合ヘッダを変えることなく単にリスポンスを返します.
 * HTTPコードを使う

長所：これは標準です. クライアントは常にhttpエラーを取り扱わなければなりませんので、結果に対するhttpコードを使うことで実行する個別のクライアントエラーハンドリングを除去します. クライアントは複数のフォーマットのデータをリクエストするので、無効なフォーマットパラメータは、別のhttpエラーコードになるので、まだ適切に処理されます.

短所： ...

このメソッドは適切にフォーマットされたリスポンスオブジェクトを常に返しますが、エラーステータス/説明はそのオブジェクト内のみの値になります. これはクエリAPIがステータスコードを返す方法と似ています.
 * 適切なリスポンス内部のエラー情報を含める

長所：HTTPエラーコードはデータ(論理エラー)ではなくネットワーキング問題のためのみに使われます. 既存のHTTPコードに頼りません.

短所：data formatパラメータが適切に設定されていない場合、出力データのフォーマットは何になりますが？エラーを知るためにオブジェクトを解析しなければなりません(perf?). エラーチェックのコードは接続とデータ解析レベルの両方に存在しなければなりません.