概要
REST APIは、WordPressインストール内のさまざまなリソースにURIをマッチさせる方法を提供します。デフォルトでは、きれいなパーマリンクが有効になっている場合、WordPress REST APIは/wp-json/
に「存在」します。私たちのWordPressサイトhttps://ourawesomesite.com`, we can access the REST API's index by making a
GETrequest to
https://ourawesomesite.com/wp-json/`で利用可能です。インデックスは、その特定のWordPressインストールで利用可能なルート、サポートされているHTTPメソッド、および登録されたエンドポイントに関する情報を提供します。
ルートとエンドポイント
エンドポイントは、APIを通じて利用可能な関数です。これには、APIインデックスの取得、投稿の更新、コメントの削除などが含まれます。エンドポイントは特定の機能を実行し、いくつかのパラメータを受け取り、クライアントにデータを返します。
ルートは、エンドポイントにアクセスするために使用する「名前」であり、URLで使用されます。ルートには複数のエンドポイントが関連付けられることがあり、どれが使用されるかはHTTP動詞によって異なります。
たとえば、URL http://example.com/wp-json/wp/v2/posts/123
の場合:
- 「ルート」は
wp/v2/posts/123
です – ルートにはwp-json
は含まれません。wp-json
はAPI自体のベースパスだからです。 このルートには3つのエンドポイントがあります:
GET
はget_item
メソッドをトリガーし、投稿データをクライアントに返します。PUT
はupdate_item
メソッドをトリガーし、更新するデータを受け取り、更新された投稿データを返します。DELETE
はdelete_item
メソッドをトリガーし、現在削除された投稿データをクライアントに返します。
きれいなパーマリンクがないサイトでは、ルートは
rest_route
パラメータとしてURLに追加されます。上記の例では、完全なURLはhttp://example.com/?rest_route=/wp/v2/posts/123
になります。
エンドポイントの作成
GETリクエストを受け取ったときに「Hello World, this is the WordPress REST API」というフレーズを返すエンドポイントを作成したい場合、まずそのエンドポイントのルートを登録する必要があります。ルートを登録するには、register_rest_route()
関数を使用する必要があります。これはrest_api_init
アクションフックで呼び出す必要があります。register_rest_route()
は、ルートをエンドポイントにマッピングするすべての処理を行います。「Hello World, this is the WordPress REST API」ルートを作成してみましょう。
/**
* This is our callback function that embeds our phrase in a WP_REST_Response
*/
function prefix_get_endpoint_phrase() {
// rest_ensure_response() wraps the data we want to return into a WP_REST_Response, and ensures it will be properly returned.
return rest_ensure_response( 'Hello World, this is the WordPress REST API' );
}
/**
* This function is where we register our routes for our example endpoint.
*/
function prefix_register_example_routes() {
// register_rest_route() handles more arguments but we are going to stick to the basics for now.
register_rest_route( 'hello-world/v1', '/phrase', array(
// By using this constant we ensure that when the WP_REST_Server changes our readable endpoints will work as intended.
'methods' => WP_REST_Server::READABLE,
// Here we register our callback. The callback is fired when this endpoint is matched by the WP_REST_Server class.
'callback' => 'prefix_get_endpoint_phrase',
) );
}
add_action( 'rest_api_init', 'prefix_register_example_routes' );
register_rest_route()
に渡される最初の引数は名前空間であり、ルートをグループ化する方法を提供します。渡される2番目の引数はリソースパス、またはリソースベースです。私たちの例では、取得しているリソースは「Hello World, this is the WordPress REST API」というフレーズです。3番目の引数はオプションの配列です。エンドポイントが使用できるメソッドと、エンドポイントが一致したときに発生するコールバックを指定します(他にも多くのことができますが、これが基本です)。
3番目の引数は、エンドポイントへのアクセスを特定のユーザーのみに制限できる権限コールバックを提供することも可能です。また、3番目の引数は、リクエストがエンドポイントの応答を変更できるように、エンドポイントの引数を登録する方法も提供します。これらの概念については、このガイドのエンドポイントセクションで詳しく説明します。
https://ourawesomesite.com/wp-json/hello-world/v1/phrase
にアクセスすると、私たちのREST APIが親切に挨拶してくれるのが見えます。ルートについてもう少し深く見てみましょう。
ルート
REST APIのルートはURIで表されます。ルート自体は、https://ourawesomesite.com/wp-json`. The index route for the API is
/which is why
https://ourawesomesite.com/wp-json/`の末尾に追加されます。これにより、APIの利用可能なすべての情報が返されます。すべてのルートはこのルートに基づいて構築されるべきであり、`````wp-json`````部分は変更できますが、一般的には同じに保つことが推奨されます。
私たちは、ルートがユニークであることを確認したいです。たとえば、次のような本のルートを持つことができます:/books
。私たちの本のルートはhttps://ourawesomesite.com/wp-json/books`. However, this is not a good practice as we would end up polluting potential routes for the API. What if another plugin we wanted to register a books route as well? We would be in big trouble in that case, as the two routes would conflict with each other and only one could be used. The fourth parameter to
に存在することになります。 register_rest_route() `は、ルートが既存のルートを上書きするかどうかのブール値です。
オーバーライドパラメータは、両方のルートがオーバーライドされる可能性があるため、私たちの問題を本当に解決するわけではありません。また、異なる目的のために両方のルートを使用したい場合もあります。これが、ルートに名前空間を使用する理由です。
名前空間
ルートに名前空間を追加することは非常に重要です。「コア」エンドポイントはwp/v2
名前空間を使用します。
コアに統合する意図でエンドポイントを作成している場合を除き、wp
名前空間に何も配置しないでください。
コアエンドポイント名前空間にはいくつかの重要な点があります。名前空間の最初の部分はwp
で、ベンダー名を表します。WordPressです。プラグインの場合、名前空間のベンダー部分に対してユニークな名前を考える必要があります。上記の例ではhello-world
を使用しました。
ベンダー部分の後には、名前空間のバージョン部分があります。「コア」エンドポイントは、WordPress REST APIのバージョン2を表すためにv2
を利用します。プラグインを書く場合、単に新しいエンドポイントを作成し、提供するバージョン番号を上げることで、REST APIエンドポイントの後方互換性を維持できます。この方法で、元のv1
とv2
エンドポイントの両方にアクセスできます。
リソースパス
リソースパスは、エンドポイントが関連付けられているリソースを示す必要があります。上記の例では、phrase
という単語を使用して、私たちが対話しているリソースがフレーズであることを示しました。衝突を避けるために、登録する各リソースパスは名前空間内でユニークである必要があります。リソースパスは、特定の名前空間内で異なるリソースルートを定義するために使用されるべきです。
たとえば、基本的なeコマース機能を処理するプラグインがあるとします。私たちは、注文と製品という2つの主要なリソースタイプを持ちます。注文は製品のリクエストですが、製品そのものではありません。同じ概念が製品にも当てはまります。これらのリソースは関連していますが、同じものではなく、それぞれが別々のリソースパスに存在する必要があります。私たちのルートは、eコマースプラグインのために次のようになります:/my-shop/v1/orders
と/my-shop/v1/products
。
このようなルートを使用すると、各ルートが注文または製品のコレクションを返すことを望みます。特定の製品をIDで取得したい場合、ルートにパス変数を使用する必要があります。
パス変数
パス変数を使用すると、動的ルートを追加できます。eコマースルートを拡張するために、個々の製品を取得するためのルートを登録できます。
/**
* This is our callback function to return our products.
*
* @param WP_REST_Request $request This function accepts a rest request to process data.
*/
function prefix_get_products( $request ) {
// In practice this function would fetch the desired data. Here we are just making stuff up.
$products = array(
'1' => 'I am product 1',
'2' => 'I am product 2',
'3' => 'I am product 3',
);
return rest_ensure_response( $products );
}
/**
* This is our callback function to return a single product.
*
* @param WP_REST_Request $request This function accepts a rest request to process data.
*/
function prefix_get_product( $request ) {
// In practice this function would fetch the desired data. Here we are just making stuff up.
$products = array(
'1' => 'I am product 1',
'2' => 'I am product 2',
'3' => 'I am product 3',
);
// Here we are grabbing the 'id' path variable from the $request object. WP_REST_Request implements ArrayAccess, which allows us to grab properties as though it is an array.
$id = (string) $request['id'];
if ( isset( $products[ $id ] ) ) {
// Grab the product.
$product = $products[ $id ];
// Return the product as a response.
return rest_ensure_response( $product );
} else {
// Return a WP_Error because the request product was not found. In this case we return a 404 because the main resource was not found.
return new WP_Error( 'rest_product_invalid', esc_html__( 'The product does not exist.', 'my-text-domain' ), array( 'status' => 404 ) );
}
// If the code somehow executes to here something bad happened return a 500.
return new WP_Error( 'rest_api_sad', esc_html__( 'Something went horribly wrong.', 'my-text-domain' ), array( 'status' => 500 ) );
}
/**
* This function is where we register our routes for our example endpoint.
*/
function prefix_register_product_routes() {
// Here we are registering our route for a collection of products.
register_rest_route( 'my-shop/v1', '/products', array(
// By using this constant we ensure that when the WP_REST_Server changes our readable endpoints will work as intended.
'methods' => WP_REST_Server::READABLE,
// Here we register our callback. The callback is fired when this endpoint is matched by the WP_REST_Server class.
'callback' => 'prefix_get_products',
) );
// Here we are registering our route for single products. The (?P<id>[\d]+) is our path variable for the ID, which, in this example, can only be some form of positive number.
register_rest_route( 'my-shop/v1', '/products/(?P<id>[\d]+)', array(
// By using this constant we ensure that when the WP_REST_Server changes our readable endpoints will work as intended.
'methods' => WP_REST_Server::READABLE,
// Here we register our callback. The callback is fired when this endpoint is matched by the WP_REST_Server class.
'callback' => 'prefix_get_product',
) );
}
add_action( 'rest_api_init', 'prefix_register_product_routes' );
上記の例は多くのことをカバーしています。重要な点は、登録する2番目のルートで、リソースパス/products
にパス変数/(?P<id>[\d]+)
を追加することです。パス変数は正規表現です。この場合、[\d]+
を使用して、少なくとも1回は数値文字である必要があることを示します。リソースに数値IDを使用している場合、これはパス変数の使用方法の良い例です。パス変数を使用する場合、ユーザー入力として何が一致するかに注意する必要があります。
幸いなことに、正規表現は数値以外のものをフィルタリングします。しかし、要求されたIDの製品が存在しない場合はどうなりますか。エラーハンドリングを行う必要があります。上記のコード例で、エラーを処理する基本的な方法を見ることができます。エンドポイントコールバックでWP_Error
を返すと、APIサーバーは自動的にエラーをクライアントに提供します。
このセクションはルートについてですが、エンドポイントについてもかなりのことをカバーしました。エンドポイントとルートは相互に関連していますが、明確な違いがあります。
エンドポイント
エンドポイントは、ルートがマッピングする必要がある宛先です。特定のルートに対して、登録されたさまざまなエンドポイントがある可能性があります。架空のeコマースプラグインを拡張して、ルートとエンドポイントの違いをよりよく示します。/wp-json/my-shop/v1/products/
ルートに存在する2つのエンドポイントを作成します。1つのエンドポイントはHTTP動詞GET
を使用して製品を取得し、もう1つのエンドポイントはHTTP動詞POST
を使用して新しい製品を作成します。
/**
* This is our callback function to return our products.
*
* @param WP_REST_Request $request This function accepts a rest request to process data.
*/
function prefix_get_products( $request ) {
// In practice this function would fetch the desired data. Here we are just making stuff up.
$products = array(
'1' => 'I am product 1',
'2' => 'I am product 2',
'3' => 'I am product 3',
);
return rest_ensure_response( $products );
}
/**
* This is our callback function to return a single product.
*
* @param WP_REST_Request $request This function accepts a rest request to process data.
*/
function prefix_create_product( $request ) {
// In practice this function would create a product. Here we are just making stuff up.
return rest_ensure_response( 'Product has been created' );
}
/**
* This function is where we register our routes for our example endpoint.
*/
function prefix_register_product_routes() {
// Here we are registering our route for a collection of products and creation of products.
register_rest_route( 'my-shop/v1', '/products', array(
array(
// By using this constant we ensure that when the WP_REST_Server changes, our readable endpoints will work as intended.
'methods' => WP_REST_Server::READABLE,
// Here we register our callback. The callback is fired when this endpoint is matched by the WP_REST_Server class.
'callback' => 'prefix_get_products',
),
array(
// By using this constant we ensure that when the WP_REST_Server changes, our create endpoints will work as intended.
'methods' => WP_REST_Server::CREATABLE,
// Here we register our callback. The callback is fired when this endpoint is matched by the WP_REST_Server class.
'callback' => 'prefix_create_product',
),
) );
}
add_action( 'rest_api_init', 'prefix_register_product_routes' );
ルート/wp-json/my-shop/v1/products
に使用するHTTPメソッドによって、異なるエンドポイントにマッチし、異なるコールバックが発火します。POST
を使用すると、prefix_create_product()
コールバックがトリガーされ、GET
を使用すると、prefix_get_products()
コールバックがトリガーされます。
さまざまなHTTPメソッドがあり、REST APIはそれらのいずれかを利用できます。
HTTPメソッド
HTTPメソッドは、時々HTTP動詞と呼ばれます。これは、HTTPを介して通信するための異なる方法です。WordPress REST APIで使用される主なものは次のとおりです:
GET
はAPIからデータを取得するために使用されるべきです。POST
は新しいリソース(ユーザー、投稿、分類など)を作成するために使用されるべきです。PUT
はリソースを更新するために使用されるべきです。DELETE
はリソースを削除するために使用されるべきです。OPTIONS
はリソースに関するコンテキストを提供するために使用されるべきです。
これらのメソッドはすべてのクライアントによってサポートされているわけではないことに注意することが重要です。これはHTTP 1.1で導入されたためです。幸いなことに、APIはこれらの不幸なケースに対する回避策を提供します。リソースを削除したいがDELETE
リクエストを送信できない場合、_method
パラメータまたはX-HTTP-Method-Override
ヘッダーをリクエストに使用できます。これがどのように機能するかというと、https://ourawesomesite.com/wp-json/my-shop/v1/products/1?_method=DELETE
にPOST
リクエストを送信します。これで、クライアントがリクエストで適切なHTTPメソッドを送信できなかった場合でも、またはDELETEリクエストをブロックするファイアウォールが存在する場合でも、製品番号1が削除されます。
HTTPメソッドは、ルートとコールバックと組み合わせて、エンドポイントのコアを構成します。
コールバック
現在、REST APIでサポートされているエンドポイントのコールバックは2種類のみです。callback
とpermission_callback
です。メインコールバックはリソースとのインタラクションを処理する必要があります。権限コールバックは、どのユーザーがエンドポイントにアクセスできるかを処理する必要があります。エンドポイントを登録する際に追加情報を追加することで、追加のコールバックを追加できます。その後、rest_pre_dispatch
、rest_dispatch_request
、またはrest_post_dispatch
フックにフックして、新しいカスタムコールバックを発火させることができます。
エンドポイントコールバック
削除エンドポイントのメインコールバックは、リソースを削除し、応答にそのコピーを返す必要があります。作成エンドポイントのメインコールバックは、リソースを作成し、新しく作成されたデータに一致する応答を返す必要があります。更新コールバックは、実際に存在するリソースのみを変更する必要があります。読み取りコールバックは、既に存在するデータのみを取得する必要があります。冪等性の概念を考慮することが重要です。
REST APIの文脈における冪等性とは、エンドポイントに同じリクエストを行った場合、サーバーがリクエストを同じ方法で処理することを意味します。読み取りエンドポイントが冪等でない場合を想像してみてください。それにリクエストを行うたびに、サーバーの状態がリクエストによって変更されることになります。これは、データを取得しようとしているだけなのに、壊滅的な結果をもたらす可能性があります。誰かがサーバーからデータを取得するたびに、内部で何かが変更されることになります。読み取り、更新、削除エンドポイントが悪影響を及ぼさず、意図されたことだけを行うことを確認することが重要です。
REST APIでは、冪等性の概念はエンドポイントコールバックではなくHTTPメソッドに関連しています。GET
、HEAD
、TRACE
、OPTIONS
、PUT
、またはDELETE
を使用するコールバックは、いかなる副作用も生じるべきではありません。POST
リクエストは冪等ではなく、通常はリソースを作成するために使用されます。冪等な作成メソッドを作成した場合、同じリクエストを行ってもサーバーに副作用がないため、リソースは1つだけ作成されます。作成の場合、同じリクエストを何度も行うと、サーバーは毎回新しいリソースを生成する必要があります。
エンドポイントの使用を制限するには、権限コールバックを登録する必要があります。
権限コールバック
権限コールバックは、WordPress REST APIのセキュリティにとって非常に重要です。公開されるべきでないプライベートデータがある場合、エンドポイントに対して権限コールバックを登録する必要があります。以下は、権限コールバックを登録する方法の例です。
/**
* This is our callback function that embeds our resource in a WP_REST_Response
*/
function prefix_get_private_data() {
// rest_ensure_response() wraps the data we want to return into a WP_REST_Response, and ensures it will be properly returned.
return rest_ensure_response( 'This is private data.' );
}
/**
* This is our callback function that embeds our resource in a WP_REST_Response
*/
function prefix_get_private_data_permissions_check() {
// Restrict endpoint to only users who have the edit_posts capability.
if ( ! current_user_can( 'edit_posts' ) ) {
return new WP_Error( 'rest_forbidden', esc_html__( 'OMG you can not view private data.', 'my-text-domain' ), array( 'status' => 401 ) );
}
// This is a black-listing approach. You could alternatively do this via white-listing, by returning false here and changing the permissions check.
return true;
}
/**
* This function is where we register our routes for our example endpoint.
*/
function prefix_register_example_routes() {
// register_rest_route() handles more arguments but we are going to stick to the basics for now.
register_rest_route( 'my-plugin/v1', '/private-data', array(
// By using this constant we ensure that when the WP_REST_Server changes our readable endpoints will work as intended.
'methods' => WP_REST_Server::READABLE,
// Here we register our callback. The callback is fired when this endpoint is matched by the WP_REST_Server class.
'callback' => 'prefix_get_private_data',
// Here we register our permissions callback. The callback is fired before the main callback to check if the current user can access the endpoint.
'permission_callback' => 'prefix_get_private_data_permissions_check',
) );
}
add_action( 'rest_api_init', 'prefix_register_example_routes' );
認証が有効でない状態でこのエンドポイントを試すと、エラー応答が返され、データを見ることができなくなります。認証は大きなトピックであり、最終的にはこの章の一部が作成されて、独自の認証プロセスを作成する方法を示します。
引数
エンドポイントにリクエストを行う際、応答を変更するために追加のパラメータを指定する必要がある場合があります。これらの追加パラメータは、エンドポイントを登録する際に追加できます。引数をエンドポイントで使用する方法の例を見てみましょう。
/**
* This is our callback function that embeds our resource in a WP_REST_Response
*/
function prefix_get_colors( $request ) {
// In practice this function would fetch the desired data. Here we are just making stuff up.
$colors = array(
'blue',
'blue',
'red',
'red',
'green',
'green',
);
if ( isset( $request['filter'] ) ) {
$filtered_colors = array();
foreach ( $colors as $color ) {
if ( $request['filter'] === $color ) {
$filtered_colors[] = $color;
}
}
return rest_ensure_response( $filtered_colors );
}
return rest_ensure_response( $colors );
}
/**
* We can use this function to contain our arguments for the example product endpoint.
*/
function prefix_get_color_arguments() {
$args = array();
// Here we are registering the schema for the filter argument.
$args['filter'] = array(
// description should be a human readable description of the argument.
'description' => esc_html__( 'The filter parameter is used to filter the collection of colors', 'my-text-domain' ),
// type specifies the type of data that the argument should be.
'type' => 'string',
// enum specified what values filter can take on.
'enum' => array( 'red', 'green', 'blue' ),
);
return $args;
}
/**
* This function is where we register our routes for our example endpoint.
*/
function prefix_register_example_routes() {
// register_rest_route() handles more arguments but we are going to stick to the basics for now.
register_rest_route( 'my-colors/v1', '/colors', array(
// By using this constant we ensure that when the WP_REST_Server changes our readable endpoints will work as intended.
'methods' => WP_REST_Server::READABLE,
// Here we register our callback. The callback is fired when this endpoint is matched by the WP_REST_Server class.
'callback' => 'prefix_get_colors',
// Here we register our permissions callback. The callback is fired before the main callback to check if the current user can access the endpoint.
'args' => prefix_get_color_arguments(),
) );
}
add_action( 'rest_api_init', 'prefix_register_example_routes' );
この例では、filter
引数を指定しました。エンドポイントをリクエストする際に、クエリパラメータとして引数を指定できます。https://ourawesomesitem.com/my-colors/v1/colors?filter=blue
にGET
リクエストを行うと、コレクション内の青い色のみが返されます。クエリ文字列の代わりにリクエストボディ内のボディパラメータとしてこれらを渡すこともできます。クエリパラメータとボディパラメータの違いを理解するには、HTTP仕様について読む必要があります。クエリパラメータはURLに追加されるクエリ文字列に存在し、ボディパラメータはHTTPリクエストのボディに直接埋め込まれます。
エンドポイントの引数を作成しましたが、引数が文字列であることを確認し、赤、緑、または青の値と一致するかどうかを判断するにはどうすればよいでしょうか。これを行うには、引数の検証コールバックを指定する必要があります。
検証
検証とサニタイズは、APIのセキュリティにとって非常に重要です。検証コールバック(WP 4.6+)は、サニタイズコールバックの前に発火します。引数が受け取っている入力が有効かどうかを確認するためにvalidate_callback
を使用する必要があります。sanitize_callback
は、引数が処理される前に、引数の入力を変換したり、不要な部分を取り除いたりするために使用されるべきです。
上記の例では、filter
パラメータが文字列であり、赤、緑、または青の値と一致することを確認する必要があります。validate_callback
を追加した後のコードがどのように見えるか見てみましょう。
/**
* This is our callback function that embeds our resource in a WP_REST_Response
*/
function prefix_get_colors( $request ) {
// In practice this function would fetch more practical data. Here we are just making stuff up.
$colors = array(
'blue',
'blue',
'red',
'red',
'green',
'green',
);
if ( isset( $request['filter'] ) ) {
$filtered_colors = array();
foreach ( $colors as $color ) {
if ( $request['filter'] === $color ) {
$filtered_colors[] = $color;
}
}
return rest_ensure_response( $filtered_colors );
}
return rest_ensure_response( $colors );
}
/**
* Validate a request argument based on details registered to the route.
*
* @param mixed $value Value of the 'filter' argument.
* @param WP_REST_Request $request The current request object.
* @param string $param Key of the parameter. In this case it is 'filter'.
* @return WP_Error|boolean
*/
function prefix_filter_arg_validate_callback( $value, $request, $param ) {
// If the 'filter' argument is not a string return an error.
if ( ! is_string( $value ) ) {
return new WP_Error( 'rest_invalid_param', esc_html__( 'The filter argument must be a string.', 'my-text-domain' ), array( 'status' => 400 ) );
}
// Get the registered attributes for this endpoint request.
$attributes = $request->get_attributes();
// Grab the filter param schema.
$args = $attributes['args'][ $param ];
// If the filter param is not a value in our enum then we should return an error as well.
if ( ! in_array( $value, $args['enum'], true ) ) {
return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not one of %s' ), $param, implode( ', ', $args['enum'] ) ), array( 'status' => 400 ) );
}
}
/**
* We can use this function to contain our arguments for the example product endpoint.
*/
function prefix_get_color_arguments() {
$args = array();
// Here we are registering the schema for the filter argument.
$args['filter'] = array(
// description should be a human readable description of the argument.
'description' => esc_html__( 'The filter parameter is used to filter the collection of colors', 'my-text-domain' ),
// type specifies the type of data that the argument should be.
'type' => 'string',
// enum specified what values filter can take on.
'enum' => array( 'red', 'green', 'blue' ),
// Here we register the validation callback for the filter argument.
'validate_callback' => 'prefix_filter_arg_validate_callback',
);
return $args;
}
/**
* This function is where we register our routes for our example endpoint.
*/
function prefix_register_example_routes() {
// register_rest_route() handles more arguments but we are going to stick to the basics for now.
register_rest_route( 'my-colors/v1', '/colors', array(
// By using this constant we ensure that when the WP_REST_Server changes our readable endpoints will work as intended.
'methods' => WP_REST_Server::READABLE,
// Here we register our callback. The callback is fired when this endpoint is matched by the WP_REST_Server class.
'callback' => 'prefix_get_colors',
// Here we register our permissions callback. The callback is fired before the main callback to check if the current user can access the endpoint.
'args' => prefix_get_color_arguments(),
) );
}
add_action( 'rest_api_init', 'prefix_register_example_routes' );
サニタイズ
上記の例では、enum内の値のみに入力を制限しているため、sanitize_callback
を使用する必要はありません。厳密な検証がなく、任意の文字列をパラメータとして受け入れた場合、sanitize_callback
を登録する必要があります。コンテンツフィールドを更新したい場合、ユーザーがalert('ZOMG Hacking you');
のようなものを入力した場合はどうなりますか。フィールド値は実行可能なスクリプトになる可能性があります。不要なデータを取り除いたり、データを希望の形式に変換したりするために、引数のsanitize_callback
を登録する必要があります。WordPressのsanitize_text_field()
をサニタイズコールバックとして使用する方法の例を示します:
/**
* This is our callback function that embeds our resource in a WP_REST_Response.
*
* The parameter is already sanitized by this point so we can use it without any worries.
*/
function prefix_get_item( $request ) {
if ( isset( $request['data'] ) ) {
return rest_ensure_response( $request['data'] );
}
return new WP_Error( 'rest_invalid', esc_html__( 'The data parameter is required.', 'my-text-domain' ), array( 'status' => 400 ) );
}
/**
* Validate a request argument based on details registered to the route.
*
* @param mixed $value Value of the 'filter' argument.
* @param WP_REST_Request $request The current request object.
* @param string $param Key of the parameter. In this case it is 'filter'.
* @return WP_Error|boolean
*/
function prefix_data_arg_validate_callback( $value, $request, $param ) {
// If the 'data' argument is not a string return an error.
if ( ! is_string( $value ) ) {
return new WP_Error( 'rest_invalid_param', esc_html__( 'The filter argument must be a string.', 'my-text-domain' ), array( 'status' => 400 ) );
}
}
/**
* Sanitize a request argument based on details registered to the route.
*
* @param mixed $value Value of the 'filter' argument.
* @param WP_REST_Request $request The current request object.
* @param string $param Key of the parameter. In this case it is 'filter'.
* @return WP_Error|boolean
*/
function prefix_data_arg_sanitize_callback( $value, $request, $param ) {
// It is as simple as returning the sanitized value.
return sanitize_text_field( $value );
}
/**
* We can use this function to contain our arguments for the example product endpoint.
*/
function prefix_get_data_arguments() {
$args = array();
// Here we are registering the schema for the filter argument.
$args['data'] = array(
// description should be a human readable description of the argument.
'description' => esc_html__( 'The data parameter is used to be sanitized and returned in the response.', 'my-text-domain' ),
// type specifies the type of data that the argument should be.
'type' => 'string',
// Set the argument to be required for the endpoint.
'required' => true,
// We are registering a basic validation callback for the data argument.
'validate_callback' => 'prefix_data_arg_validate_callback',
// Here we register the validation callback for the filter argument.
'sanitize_callback' => 'prefix_data_arg_sanitize_callback',
);
return $args;
}
/**
* This function is where we register our routes for our example endpoint.
*/
function prefix_register_example_routes() {
// register_rest_route() handles more arguments but we are going to stick to the basics for now.
register_rest_route( 'my-plugin/v1', '/sanitized-data', array(
// By using this constant we ensure that when the WP_REST_Server changes our readable endpoints will work as intended.
'methods' => WP_REST_Server::READABLE,
// Here we register our callback. The callback is fired when this endpoint is matched by the WP_REST_Server class.
'callback' => 'prefix_get_item',
// Here we register our permissions callback. The callback is fired before the main callback to check if the current user can access the endpoint.
'args' => prefix_get_data_arguments(),
) );
}
add_action( 'rest_api_init', 'prefix_register_example_routes' );
まとめ
WordPress REST APIのエンドポイントを登録する基本をカバーしました。ルートは、エンドポイントが存在するURIです。エンドポイントは、コールバック、メソッド、引数、およびその他のオプションのコレクションです。各エンドポイントは、register_rest_route()
を使用してルートにマッピングされます。デフォルトでは、エンドポイントはさまざまなHTTPメソッド、メインコールバック、権限コールバック、および登録された引数をサポートできます。WordPressと対話するための使用ケースをカバーするためにエンドポイントを登録できます。エンドポイントはREST APIとのコアインタラクションポイントとして機能しますが、この強力なAPIを完全に活用するために探求し理解すべき他の多くのトピックがあります。