API:Implementation Strategy/ja

From MediaWiki.org
Jump to navigation Jump to search
言語: English  • 日本語

This explains the implementation of the MediaWiki API machinery in core. If you want to provide an API in your code for clients to consume, read API:Extensions.

ファイル/モジュール構造[edit]

  • api.phpはエントリポイントで、mediawikiのrootに設置されています
  • includes/apiはapiに関連したすべてのファイルを含みますが、それらのうちどれもエントリポイントとしては許可されません
  • すべてのapiクラスは共通の抽象クラスであるApiBaseから派生します。パラメータの解析、プロファイリング、とエラーハンドリングといった基本クラスは共通の機能性を提供します。
  • ApiMain is the main class instantiated by api.php. It determines which module to execute based on the action=XXX parameter. ApiMain also creates an instance of the ApiResult class, which contains the output data array and related helper functions. Lastly, ApiMain instantiates the formatting class that will output the data from ApiResult in XML/JSON/PHP or other format to the client.
  • ApiBaseから派生したどのモジュールもインスタンスになっている間にApiMainのインスタンスへの参照を受け取るので、実行の間にモジュールは結果のオブジェクトといった共有リソースを取得することがあります。

クエリモジュール[edit]

  • ApiQueryはサブモジュールを実行するという点でAPiMainと同じ振る舞いをします。それぞれのサブモジュールはApiQueryBaseから派生します(トップレベルのモジュールであるApiQuery自身は除く。インスタンスになっている間、サブモジュールはApiQueryのインスタンスへの参照を受け取ります。
  • All extension query modules should use a 3 or more letter prefixes. The core modules use 2 letter prefixes.
  • ApiQueryの実行プラン:
    1. 必要なサブモジュールを決定するために共有クエリパラメータlist/prop/metaを取得する。
    2. ApiPageSetオブジェクトを作りtitles/pageids/revidsパラメータからそれを投入する。pagesetオブジェクトはクエリモジュールが連携するページもしくはリビジョンの一覧を含みます。モジュールの中には単独のページのみを含むpagesetを必要とするものがあることにご注意お願いします。
    3. 必要な場合、別のPageSetを作るためにgeneratorモジュールが実行されます - UNIXでストリームをパイプするのと似ています - 任意のページは取り組む他のすべてのモジュールに対してページの別の一式を生み出すgeneratorへの入力です。
  • Requirements for query continuation:
    • The SQL query must be totally ordered. In other words, the query must be using all columns of some unique key either as constants in the WHERE clause or in the ORDER BY clauses.
      • In MySQL this is an exclusive or, to the point where querying Foo and Bar must order by title but not namespace (namespace is constant 0), Foo and Talk:Foo must order by namespace but not title (title is constant "Foo"), and Foo and Talk:Bar must order by both namespace and title.
    • The SQL query must not filesort.
    • The value given to setContinueEnumParameter() must include all the columns in the ORDER BY clause.
    • When continuing, a single compound condition should be added to the WHERE clause. If the query has ORDER BY column_0, column_1, column_2, this condition should look something like this:
      (column_0 > value_0 OR (column_0 = value_0 AND
       (column_1 > value_1 OR (column_1 = value_1 AND
        (column_2 >= value_2)
       ))
      ))
      Of course, swap ">" for "<" if your ORDER BY columns are using DESC. Be sure to avoid SQL injection in the values.

内部のデータ構造[edit]

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

エラー/ステータスの報告[edit]

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

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

HTTPコードを使う
void header( string reason_phrase [, bool replace [, int http_response_code]] )

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

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

Cons: ...

適切なリスポンス内部のエラー情報を含める

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

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

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

Boilerplate code[edit]