重要な注意事項:レスポンスの変更について

コアのREST APIエンドポイントのレスポンスからデータを変更または削除すると、プラグインやWordPressコアの動作が壊れる可能性があり、可能な限り避けるべきです。

APIは、必要ないかもしれないフィールドや、サイトの動作に合わないフィールドを含む多くのフィールドをAPIレスポンスで公開しています。REST APIレスポンスからフィールドを変更または削除したくなるかもしれませんが、これは問題を引き起こすことになります。これには、標準のレスポンスを期待するモバイルクライアント、サイト管理を支援するサードパーティツール、またはwp-admin自体が含まれます。

必要なデータは少量かもしれませんが、APIはあなたが作業している機能だけでなく、すべてのクライアントにインターフェースを公開することを目的としていることを忘れないでください。レスポンスを変更することは危険です。

フィールドを追加することは危険ではないため、データを変更する必要がある場合は、変更したデータでフィールドを複製する方がはるかに良いです。フィールドを削除することは決して推奨されません。データの小さなサブセットを取得する必要がある場合は、_fieldsパラメータを使用するか、代わりにコンテキストで作業してください。

既存のコンテキストからフィールドを削除する必要がある場合は、その動作がオプトインであることを確認する必要があります。たとえば、フィールドの削除をトリガーするカスタムクエリパラメータを提供することによってです。

APIはレスポンスの変更を防ぐことはできませんが、コードはそれを強く非推奨とするように構成されています。内部的には、フィールド登録はフィルターによって動かされており、他に選択肢がない場合に使用できます。

register_rest_fieldとregister_metaの使用

WordPress REST APIレスポンスにデータを追加するために使用できる2つのメソッドがあります。register_rest_fieldregister_meta

register_rest_fieldは、任意のREST APIレスポンスにフィールドを追加するために使用でき、APIを使用してデータを読み書きすることができます。新しいRESTフィールドを登録するには、フィールドの値を取得または設定するためのコールバック関数を提供し、フィールドのスキーマ定義を手動で指定する必要があります。

register_metaは、REST APIを介してアクセスするために既存のカスタムメタ値をホワイトリストに登録するために使用されます。メタフィールドのshow_in_restパラメータをtrueに設定すると、そのフィールドの値はエンドポイントレスポンスの.metaキーで公開され、WordPressはそのメタキーへの読み書きのためのコールバックを設定します。これはregister_rest_fieldよりもはるかに簡単ですが、1つの注意点があります:

WordPress 4.9.8以前では、show_in_restを使用してregister_metaに設定されたメタフィールドは、特定のタイプのすべてのオブジェクトに登録されます。1つのカスタム投稿タイプがメタフィールドを表示すると、すべてのカスタム投稿タイプがそのメタフィールドを表示します。WordPress 4.9.8以降、register_metaを使用してobject_subtype引数を指定することで、メタキーの使用を特定の投稿タイプに制限することが可能です。

WordPress 5.3以前では、register_metaはスカラー値(stringintegernumberboolean)のみをサポートしていました。WordPress 5.3では、objectおよびarrayタイプのサポートが追加されました。

APIレスポンスにカスタムフィールドを追加する

register_rest_fieldの使用

register_rest_field関数は、REST APIレスポンスオブジェクトにフィールドを追加する最も柔軟な方法です。3つのパラメータを受け取ります:

  • 1.* $object_type:オブジェクトの名前(文字列)またはフィールドが登録されているオブジェクトの名前の配列。これは「post」、「terms」、「meta」、「user」または「comment」のようなコアタイプである可能性がありますが、カスタム投稿タイプの文字列名であることもできます。
  • 2.* $attribute:フィールドの名前。この名前はレスポンスオブジェクト内のキーを定義するために使用されます。
  • 3.* $args:フィールドの値を取得するために使用されるコールバック関数(‘get_callback’)、フィールドの値を更新するためのコールバック関数(‘update_callback’)、およびそのスキーマを定義するためのコールバック関数を定義するキーを持つ配列です。

$args配列の各キーはオプションですが、使用しない場合はその機能は追加されません。これは、値を読み取るためのコールバック関数を指定し、必要に応じて更新コールバックを省略してそのフィールドを読み取り専用にすることができることを意味します。

フィールドはrest_api_initアクションで登録する必要があります。このアクションをinitの代わりに使用すると、REST APIを使用しないWordPressへのリクエスト中にフィールド登録が行われるのを防ぎます。

コメントレスポンスに追加フィールドを読み書きする

  1. <?php
  2. add_action( 'rest_api_init', function () {
  3. register_rest_field( 'comment', 'karma', array(
  4. 'get_callback' => function( $comment_arr ) {
  5. $comment_obj = get_comment( $comment_arr['id'] );
  6. return (int) $comment_obj->comment_karma;
  7. },
  8. 'update_callback' => function( $karma, $comment_obj ) {
  9. $ret = wp_update_comment( array(
  10. 'comment_ID' => $comment_obj->comment_ID,
  11. 'comment_karma' => $karma
  12. ) );
  13. if ( false === $ret ) {
  14. return new WP_Error(
  15. 'rest_comment_karma_failed',
  16. __( 'Failed to update comment karma.' ),
  17. array( 'status' => 500 )
  18. );
  19. }
  20. return true;
  21. },
  22. 'schema' => array(
  23. 'description' => __( 'Comment karma.' ),
  24. 'type' => 'integer'
  25. ),
  26. ) );
  27. } );

この例は、投稿のレスポンスにkarmaというフィールドを追加することを示しています。comment_karmaフィールドが存在するため、機能しますが、コアでは使用されていません。コメントカルマの実際の実装には、別のエンドポイントを使用する必要があることに注意してください。

これは基本的な例です。特定のフィールドに必要な権限チェックやエラーハンドリングを慎重に考慮してください。

register_rest_fieldの動作

グローバル変数$wp_rest_additional_fieldsは、REST APIインフラストラクチャによって内部的に使用され、各オブジェクトタイプに追加されるレスポンスフィールドを保持します。REST APIは、このグローバル変数に追加するためのユーティリティ関数としてregister_rest_fieldを提供します。グローバル変数に直接追加することは、将来の互換性を確保するために避けるべきです。

各オブジェクトタイプ(投稿、ユーザー、ターム、コメントなど)に対して、$wp_rest_additional_fieldsはフィールドの定義の配列を含み、フィールドの値を取得または更新するために使用されるコールバックを含みます。

REST APIで登録されたメタと作業する

register_meta関数は、特定のオブジェクトタイプのメタフィールドを定義するプロセスを簡素化します。新しいメタキーを登録する際に'show_in_rest' => trueを設定することで、そのキーはREST APIを介してアクセス可能になります。

投稿レスポンスで投稿メタフィールドを読み書きする

  1. <?php
  2. // The object type. For custom post types, this is 'post';
  3. // for custom comment types, this is 'comment'. For user meta,
  4. // this is 'user'.
  5. $object_type = 'post';
  6. $meta_args = array( // Validate and sanitize the meta value.
  7. // Note: currently (4.7) one of 'string', 'boolean', 'integer',
  8. // 'number' must be used as 'type'. The default is 'string'.
  9. 'type' => 'string',
  10. // Shown in the schema for the meta key.
  11. 'description' => 'A meta key associated with a string meta value.',
  12. // Return a single value of the type.
  13. 'single' => true,
  14. // Show in the WP REST API response. Default: false.
  15. 'show_in_rest' => true,
  16. );
  17. register_meta( $object_type, 'my_meta_key', $meta_args );

この例は、投稿メタフィールドの読み取りと書き込みを許可する方法を示しています。このフィールドは、wp-json/wp/v2/posts/<post-id>へのPOSTリクエストを介して更新されるか、wp-json/wp/v2/posts/へのPOSTリクエストとともに投稿と共に作成されます。

カスタム投稿タイプに登録されたメタフィールドの場合、投稿タイプはcustom-fieldsサポートを持っている必要があります。そうでない場合、メタフィールドはREST APIに表示されません。

投稿タイプ特有のメタ

WordPress 4.9.8では、register_post_metaおよびregister_term_meta関数を使用して特定の投稿タイプまたはタクソノミーのメタを登録するサポートが追加されました。これらはregister_metaと同じルールに従いますが、最初のパラメータとしてオブジェクトタイプの代わりに投稿タイプまたはタクソノミーを受け取ります。以下のコードは、my_meta_keyの例を上記のように登録しますが、pageカスタム投稿タイプのみに対してのみです。

  1. $meta_args = array(
  2. 'type' => 'string',
  3. 'description' => 'A meta key associated with a string meta value.',
  4. 'single' => true,
  5. 'show_in_rest' => true,
  6. );
  7. register_post_meta( 'page', 'my_meta_key', $meta_args );

オブジェクトメタタイプ

WordPress 5.3では、メタを登録する際にobject タイプを使用するサポートが追加されました。重要なことに、objectはJSONオブジェクトを指し、これはPHPの連想配列に相当します。

  1. たとえば、以下のコードサンプルは、「release」という名前の投稿メタフィールドを登録し、指定されたJSONデータを受け入れます。
  2. ``````bash
  3. {
  4. "meta": {
  5. "release": {
  6. "version": "5.2",
  7. "artist": "Jaco"
  8. }
  9. }
  10. }
  11. `
  1. register_post_meta(
  2. 'post',
  3. 'release',
  4. array(
  5. 'single' => true,
  6. 'type' => 'object',
  7. 'show_in_rest' => array(
  8. 'schema' => array(
  9. 'type' => 'object',
  10. 'properties' => array(
  11. 'version' => array(
  12. 'type' => 'string',
  13. ),
  14. 'artist' => array(
  15. 'type' => 'string',
  16. ),
  17. ),
  18. ),
  19. ),
  20. )
  21. );
  1. #### 追加プロパティ
  2. デフォルトでは、プロパティのリストは厳密なホワイトリストです。リクエストにリストされていないプロパティが送信されると、REST APIはエラーを返します:`````your_property is not a valid property of Object.`````。プロパティ名が事前にわからない場合は、`````additionalProperties`````キーワードを使用できます。`````additionalProperties`````は、未知のプロパティを検証するために使用されるJSONスキーマを受け入れます。たとえば、追加のプロパティが数値であることを強制するには、以下のコードを使用できます。
  3. ``````bash
  4. {
  5. "meta": {
  6. "release": {
  7. "version": "5.2",
  8. "artist": "Jaco",
  9. "unknown_field": 5.3
  10. }
  11. }
  12. }
  13. `
  1. register_post_meta(
  2. 'post',
  3. 'version',
  4. array(
  5. 'single' => true,
  6. 'type' => 'object',
  7. 'show_in_rest' => array(
  8. 'schema' => array(
  9. 'type' => 'object',
  10. 'properties' => array(
  11. 'version' => array(
  12. 'type' => 'string',
  13. ),
  14. 'artist' => array(
  15. 'type' => 'string',
  16. ),
  17. ),
  18. 'additionalProperties' => array(
  19. 'type' => 'number',
  20. ),
  21. ),
  22. ),
  23. )
  24. );
  1. <a name="array-meta-type"></a>
  2. ### 配列メタタイプ
  3. WordPress 5.3では、`````array````` [タイプ](https://tools.ietf.org/html/draft-zyp-json-schema-04#section-3.5)の使用をサポートすることも追加されました。重要なことに、`````array`````はJSON配列を指し、これはPHPの数値配列に相当します。
  4. `````array`````メタを登録する際、`````type`````を`````array`````に設定するだけでは不十分で、WordPressに配列内のアイテムの期待される形式を通知する必要があります。これは、メタデータを登録する際にJSONスキーマエントリを書くことによって行われます。
  5. この値を提供しない場合、`````register_meta`````はfalseを返し、次の警告を発行します:`````When registering an "array" meta type to show in the REST API, you must specify the schema for each array item in "show_in_rest.schema.items".

以下のコードサンプルは、「projects」という名前の投稿メタフィールドを登録し、プロジェクト名のリストを含みます。指定されたJSONデータを受け入れます。

  1. {
  2. "meta": {
  3. "projects": [
  4. "WordPress",
  5. "BuddyPress"
  6. ]
  7. }
  8. }
  1. register_post_meta(
  2. 'post',
  3. 'projects',
  4. array(
  5. 'single' => true,
  6. 'type' => 'array',
  7. 'show_in_rest' => array(
  8. 'schema' => array(
  9. 'type' => 'array',
  10. 'items' => array(
  11. 'type' => 'string',
  12. ),
  13. ),
  14. ),
  15. )
  16. );

再びshow_in_resttrueの代わりに配列になり、schemaキーに対してJSONスキーマが指定されていることに注意してください。

  1. たとえば、指定されたJSONデータを受け入れるには、以下のメタ登録を使用します。
  2. ``````bash
  3. {
  4. "meta": {
  5. "projects": [
  6. {
  7. "name": "WordPress",
  8. "website": "https://wordpress.org"
  9. },
  10. {
  11. "name": "BuddyPress",
  12. "website": "https://buddypress.org"
  13. }
  14. ]
  15. }
  16. }
  17. `
  1. register_post_meta(
  2. 'post',
  3. 'projects',
  4. array(
  5. 'single' => true,
  6. 'type' => 'array',
  7. 'show_in_rest' => array(
  8. 'schema' => array(
  9. 'items' => array(
  10. 'type' => 'object',
  11. 'properties' => array(
  12. 'name' => array(
  13. 'type' => 'string',
  14. ),
  15. 'website' => array(
  16. 'type' => 'string',
  17. 'format' => 'uri',
  18. ),
  19. ),
  20. ),
  21. ),
  22. ),
  23. )
  24. );
  1. <a name="non-single-metadata"></a>
  2. ### 非単一メタデータ
  3. 非単一メタフィールドは、オブジェクトごとに1つの値ではなく、値の配列を持ちます。これらの値のそれぞれは、メタテーブルの別の行に保存されます。
  4. `````array`````および`````object`````タイプは、非単一メタフィールドでも使用できます。たとえば、以前の「release」メタキーが`````single`````を`````false`````に設定していた場合、以下のJSONデータを受け入れることができます。
  5. ``````bash
  6. {
  7. "meta": {
  8. "release": [
  9. {
  10. "version": "5.2",
  11. "artist": "Jaco"
  12. },
  13. {
  14. "version": "5.1",
  15. "artist": "Betty"
  16. }
  17. ]
  18. }
  19. }
  20. `

これにより、2つのメタデータベース行が生成されます。最初は{ "version": "5.2", "artist": "Jaco" }を含み、2番目は{ "version": "5.1", "artist": "Betty" }を含みます。

同様に、以下のデータは「projects」例に対してsinglefalseに設定されている場合に受け入れられます。

  1. {
  2. "meta": {
  3. "projects": [
  4. [
  5. "WordPress",
  6. "BuddyPress"
  7. ],
  8. [
  9. "bbPress"
  10. ]
  11. ]
  12. }
  13. }

これにより、2つのメタデータベース行が生成されます。最初は[ "WordPress", "BuddyPress" ]を含み、2番目は[ "bbPress" ]を含みます。

無効な保存値

メタフィールドの既存の値が登録されたタイプおよびスキーマに対して検証に失敗した場合、そのメタフィールドの値はnullとして返されます。そのnull値が更新リクエストを行う際にAPIに返されると、rest_invalid_stored_valueエラーが発生します:The %s property has an invalid stored value, and cannot be updated to null.。これを修正するには、有効な値でメタキーを更新するか、そのプロパティをリクエストから省略してください。

デフォルトメタデータ値

WordPress 5.5は、値が定義されていない場合にメタデータのデフォルト値を指定するための公式サポートを追加しました。たとえば、このコードスニペットを使用すると、priceメタフィールドは、まだ値がない場合に0.00に設定されます。

  1. register_post_meta(
  2. 'product',
  3. 'price',
  4. array(
  5. 'single' => true,
  6. 'type' => 'string',
  7. 'default' => '0.00',
  8. )
  9. );

APIレスポンスにリンクを追加する

WordPressは、関連リソースに移動しやすくするために、クエリされたリソースに関連付けられたリンクのリストを生成します。

  1. {
  2. "_links": {
  3. "self": [
  4. {
  5. "href": "https://make.wordpress.org/core/wp-json/wp/v2/posts/28312"
  6. }
  7. ],
  8. "collection": [
  9. {
  10. "href": "https://make.wordpress.org/core/wp-json/wp/v2/posts"
  11. }
  12. ],
  13. "author": [
  14. {
  15. "embeddable": true,
  16. "href": "https://make.wordpress.org/core/wp-json/wp/v2/users/8670591"
  17. }
  18. ],
  19. "replies": [
  20. {
  21. "embeddable": true,
  22. "href": "https://make.wordpress.org/core/wp-json/wp/v2/comments?post=28312"
  23. }
  24. ],
  25. "wp:term": [
  26. {
  27. "taxonomy": "category",
  28. "embeddable": true,
  29. "href": "https://make.wordpress.org/core/wp-json/wp/v2/categories?post=28312"
  30. },
  31. {
  32. "taxonomy": "post_tag",
  33. "embeddable": true,
  34. "href": "https://make.wordpress.org/core/wp-json/wp/v2/tags?post=28312"
  35. }
  36. ]
  37. }
  38. }

Make.WordPress.orgの投稿からのリンクのサンプル

これらのリンクはJSONレスポンスオブジェクトの_linksプロパティの下に表示されますが、WP_REST_Response::$dataに保存されず、WP_REST_Response::get_data()を介してアクセスすることはできません。代わりに、サーバーはレスポンスデータをエコーする直前にリンクデータをレスポンスに追加します。

カスタムリンクは、WP_REST_Response::add_link()メソッドを使用してレスポンスに追加できます。このメソッドは、リンク関係、URL、およびオプションでリンク属性のリストの3つのパラメータを受け取ります。たとえば、authorおよびwp:termリンクを追加するには。

  1. <?php
  2. $response->add_link( 'author', rest_url( "/wp/v2/users/{$post->post_author}" ) );
  3. $response->add_link( 'https://api.w.org/term', add_query_arg( 'post', $post->ID, rest_url( "/wp/v2/{$tax_base}" ) ) );

リンク関係は、IANAからの登録されたリンク関係またはあなたの管理下にあるURIでなければなりません。

authorは「コンテキストの著者」として説明される登録されたリンク関係であり、投稿を書いたWordPressユーザーを指すために使用します。投稿に関連付けられた用語を説明するリンク関係は存在しないため、WordPressはCURIEを使用してレスポンスを生成する際にhttps://api.w.org/term` URL. This is transformed towp:term`を使用します。

  1. ``````bash
  2. <?php
  3. $response->add_link( 'author', rest_url( "/wp/v2/users/{$post->post_author}" ), array(
  4. 'embeddable' => true,
  5. ) );
  6. $response->add_link( 'author', rest_url( "/wp/v2/users/{$additional_author}" ), array(
  7. 'embeddable' => true,
  8. ) );
  9. `

複数の著者の投稿へのリンクのサンプル実装。

  1. {
  2. "_links": {
  3. "author": [
  4. {
  5. "embeddable": true,
  6. "href": "https://yourwebsite.com/wp-json/wp/v2/users/1"
  7. },
  8. {
  9. "embeddable": true,
  10. "href": "https://yourwebsite.com/wp-json/wp/v2/users/2"
  11. }
  12. ]
  13. },
  14. "_embedded": {
  15. "author": [
  16. {
  17. "id": 1,
  18. "name": "Primary Author"
  19. },
  20. {
  21. "id": 2,
  22. "name": "Secondary Author"
  23. }
  24. ]
  25. }
  26. }

リンクが追加される順序が維持されます。

CURIEの登録

WordPressバージョン4.5は、コンパクトURI(CURIE)のサポートを導入しました。これにより、フルURLよりもはるかに簡単な識別子でリンクを参照できるようになります。

CURIEは、rest_response_link_curiesフィルターを使用して登録されます。たとえば。

  1. <?php
  2. function my_plugin_prefix_register_curie( $curies ) {
  3. $curies[] = array(
  4. 'name' => 'my_plugin',
  5. 'href' => 'https://api.mypluginurl.com/{rel}',
  6. 'templated' => true,
  7. );
  8. return $curies;
  9. }

これにより、リンクURLがhttps://api.mypluginurl.com/my_link` tomy_plugin:my_linkin the API response. The full URL must still be used when adding links usingWP_REST_Response::add_link`に変換されます。