API Fetch について
WordPressのブロック開発メモ その11 REST API へのアクセス
基本的な REST API
WordPressでREST APIを使う前編
WordPressでREST APIを使う後編 REST APIの登録と REST コントローラ
REST API コントローラの実装
WP_REST_Controller メソッド前編
(σ・ω・)σ WP_REST_Controller メソッド後編 追加フィールド
WordPress REST API Controllerを実装してみる。
追加フィールド
WordPressのREST APIについて知っている必要があります。
例えば投稿を取得する場合、フィールドには投稿IDやタイトル、更新日などのフィールドが存在します。
これらフィールドに後付けで独自のフィールドを追加できるのが「追加フィールド
」です。
追加フィールドの設定はregister_rest_field()
関数を使います。
さらにmeta
フィールドにメタキーを後付けで追加する方法もあります。
今回は追加フィールドの方についてです。
WP_REST_Controller
にはメタフィールドのためのメソッドがいくつか含まれてます。
protected function get_object_type()
スキーマ設定の中からオブジェクトタイプを取得します。
add_action('rest_api_init', function(){
$controller = new class extends WP_REST_Controller
{
public function myExec()
{
$objectType = $this->get_object_type();
echo $objectType;
}
public function get_item_schema()
{
return [
'$schema' => 'http://json-schema.org/draft-04/schema#',
// ここが取得される
'title' => 'kurage',
// ...略
];
}
};
$controller->myExec();
});
kurage
get_item_schema()
から得たスキーマからtitle
の項目があれば取得する。
今回の例ではkurage
を取得できます。
protected function get_additional_fields( $object_type = null )
register_rest_field()
で登録した属性の一覧を取得する。
このメソッドの第一引数(オブジェクトタイプ)とregister_rest_field()
の第一引数は合わせる。
add_action('rest_api_init', function(){
register_rest_field(
'kurage',
'ikasan',
[
'get_callback' => fn() => '墨はくどー',
'update_callback' => fn($value) => null
]
);
register_rest_field(
'kurage',
'takosan',
[
'get_callback' => fn() => 'タコ殴りだべー!',
'update_callback' => fn($value) => null
]
);
$controller = new class extends WP_REST_Controller
{
public function myExec()
{
echo "<pre>";
// ここの値
$fields = $this->get_additional_fields('kurage');
}
public function get_item_schema()
{
return [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'kurage',
// ...略
];
}
};
$controller->myExec();
});
追加フィールド(名前はkurage
)の属性一覧「ikasan
, takosan
」が取得されているのが確認できる。
- 今回は
kurage
を渡したが、引数が無ければ$this->get_pbject_type()
から取得される。
protected function add_additional_fields_schema( $schema )
今まで$this->get_items_schema()
内で使用してきたメソッドです。
アイテムのフィールドに追加フィールド(register_rest_field()
でスキーマ設定したもの)をマージして返します。
引数のスキーマにtitle
プロパティがあり、追加フィールドの設定でschema
プロパティがあれば、それを$schema['properties]
にマージして返します。
add_action('rest_api_init', function(){
register_rest_field(
'kurage',
'ikasan',
[
'get_callback' => fn() => '墨はくどー',
'update_callback' => fn($value) => null,
// ここにschemaを設定していると、add_additional_fields_schema()を呼び出した時にマージされる。
'schema' =>
[
'description' => 'I have 10 legs.',
'type' => 'string'
]
]
);
register_rest_field(
'kurage',
'takosan',
[
'get_callback' => fn() => 'タコ殴りだべー!',
'update_callback' => fn($value) => null
]
);
$controller = new class extends WP_REST_Controller
{
public function myExec()
{
$schema = [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'kurage',
'type' => 'object',
'properties' => [
'uni' => [
'description' => 'toge toge',
'type' => ['string', 'null']
],
'kame' => [
'description' => 'noko noko',
'type' => ['string', 'null'],
]
]
];
// ここの値
$newSchema = $this->add_additional_fields_schema($schema);
}
};
$controller->myExec();
});
$this->add_additional_fields_schema()
に渡すスキーマと、その戻り値のスキーマの違いをしらべます。
- $schemaの値
- $newSchemaの値
register_rest_field()
で指定した追加フィールドのikasan
がスキーマに追加されていることがわかる。
以下のように、
register_rest_field('kurage', 'ikasan', [ 'schema' => [...] ])
第三引数にschema
プロパティを追加すると、
それが$newSchema['properties][ikasan]
に追加されることがわかる。
コードを簡素化して書くと以下のようになります(実際のコードと違います)。
protected function add_additional_fields_schema( $schema )
{
$fields = $this->get_additional_fields( $schema['title'] );
foreach($fields as $k => $v)
{
if($v['schema'])
{
$schema['properties'][$k] = $v['schema'];
}
}
return $schema;
}
protected function update_additional_fields_for_object( $data_object, $request )
アイテムの保存&更新の時、一緒に追加フィールド一覧を更新するようにします。
具体的にはregister_rest_field()
で設定したupdate_callback
を実行します。
なのでcreate_item()
やupdate_item()
から呼び出します。
内部のコードを簡素化すると次のようになります(実際のコードと違います)。
protected function update_additional_fields_for_object( $data_object, $request )
{
$fields = $this->get_additional_fields();
foreach( $fields as $fn => $option)
{
call_user_cunc(
$option['update_callback'],
$request[$fn],
$data_object,
$fn,
$request,
$this->get_object_type()
);
}
}
protected function add_additional_fields_to_object( $response_data, $request )
アイテムの取得時、一緒に追加フィールド一覧からデータを取得し、第一引数にマージして返します。
具体的にはregister_rest_field()
で設定したget_callback
を実行します。
prepare_item_for_response()
から呼び出します。
内部のコードを簡素化すると次のようになります(実際のコードと違います)。
protected function add_additional_fields_to_object( $response_data, $request )
{
$fields = $this->get_additional_fields();
foreach($fields as $fn => $options)
{
$response_data[$fn] = call_user_func(
$options['get_callback'],
// ... 略
);
}
return $response_data;
}
実際には $this->get_fields_for_response()
でフィルタリングします。
public function get_item_schema()
スキーマを$this->get_item_schema()
で作成しますが、
WordPress本体の実装(WP_REST_Controller
の派生クラス)では
- スキーマはキャッシュする
$this->add_additional_fields_schema()
で追加フィールドをマージする
という実装のされかたをしてます。
add_action('rest_api_init', function(){
$controller = new class extends WP_REST_Controller
{
public function get_item_schema()
{
if( $this->schema )
{
return $this->add_additional_fields_schema($this->schema);
}
$schema = [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'kurage',
'type' => 'object',
'properties' => [
'uni' => [
'description' => 'toge toge',
'type' => ['string', 'null']
],
'kame' => [
'description' => 'noko noko',
'type' => ['string', 'null'],
]
]
];
$this->schema = $schema;
return $this->add_additional_fields_schema($this->schema);
}
};
$controller->myExec();
exit;
});
add_action('rest_api_init', function(){
register_rest_field(
'kurage',
'ikasan',
[
'get_callback' => fn() => '墨はくどー',
'update_callback' => fn($value) => null,
// ここにschemaを設定していると、add_additional_fields_schema()を呼び出した時にマージされる。
'schema' =>
[
'description' => 'I have 10 legs.',
'type' => 'string'
]
]
);
register_rest_field(
'kurage',
'takosan',
[
'get_callback' => fn() => 'タコ殴りだべー!',
'update_callback' => fn($value) => null
]
);
$controller = new class extends WP_REST_Controller
{
public function myExec()
{
// ここの値
$schema = $this->get_item_schema();
}
public function get_item_schema()
{
$this->schema = $this->schema ?? [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'kurage',
'type' => 'object',
'properties' => [
'uni' => [
'description' => 'toge toge',
'type' => ['string', 'null']
],
'kame' => [
'description' => 'noko noko',
'type' => ['string', 'null'],
]
]
];
return $this->add_additional_fields_schema($this->schema);
}
};
$controller->myExec();
exit;
});
- get_item_schema()の実装コードを見やすいよう書き直してます。
スキーマの値と、追加フィールドがマージされた値を返すように実装してます。
作成されたスキーマの結果を見て確認できます。