この記事をおすすめしたい人
- WordPressのREST APIから不要な項目を削除したい人
- 少しでもREST APIを軽量化したい人
- つまりオレ
今回はWordPressのREST APIから不要な項目を削除していきます。
とは言っても、「context=embed」指定や「_links」の削除でかなり減らせているので、今回はそれの総仕上げになります。
最後にコピペ用コードを置いています。
まずは削除する項目を決める
削除すべき項目は2パターン考える必要があります。
記事一覧に使用するAPI(記事本文が不要)、記事ページに使用するAPI(記事本文が必要)の2つです。
以下、「_links」の削除まで終わっている状態の続きで考えます。
記事一覧に使用するAPIの削除項目
残っている項目はこんな↓感じです。
{
"id": 101,
"date": "2020-08-13T23:29:33",
"slug": "wp-rest-slug",
"type": "post",
"link": "https://dev.ore-shika.com/wp-rest-slug/",
"title": {
"rendered": "(略)"
},
"excerpt": {
"rendered": "(略)",
"protected": false
},
"author": 1,
"featured_media": 0
}
何を削除するかは人によるので、今回は僕基準で考えます。 適宜読み替えてください。
- 「type」:
投稿タイプ指定でAPI叩いてるので既知です。不要。 - 「link」:
REST APIを利用する側でスラッグからURLを再生成予定です。不要。 - 「excerpt」:
別途「All In One SEO Pack」のSEOディスクリプションを追加予定。不要。 - 「author」:
このサイトは僕しか書いてないので不要。 - 「featured_media」:
アイキャッチ画像のIDですが、ここから取得するともっかいAPI叩かないといけないので別途追加します。不要。
後はtitleがオブジェクトになっているので文字列にスリム化します。
以上6点。
記事ページに使用するAPIの削除項目
残っている項目はこんな↓感じです。
{
"id": 101,
"date": "2020-08-13T23:29:33",
"date_gmt": "2020-08-13T14:29:33",
"guid": {
"rendered": "https://dev.ore-shika.com/?p=101"
},
"modified": "2020-08-13T23:33:14",
"modified_gmt": "2020-08-13T14:33:14",
"slug": "wp-rest-slug",
"status": "publish",
"title": {
"rendered": "(略)"
},
"content": {
"rendered": "(略)",
"protected": false
},
"parent": 0,
"comment_status": "open",
"ping_status": "open",
"sticky": false,
"template": "",
"format": "standard",
"meta": [],
"categories": [
14,
8
],
"tags": []
}
記事一覧の方で削除した項目は除外しています。
追加で削除する項目はこの↓ような感じに。
- 「date_gmt」:
日本時間でしか処理していないので不要。 - 「guid」:
ショートリンクではアクセスしないので不要。 - 「modified_gmt」:
日本時間(略)。 - 「status」:
公開記事しか取得しないので不要。 - 「parent」:
投稿ページは階層構造持たせていないので不要。固定ページの方はパンくず用に必要になるケースがありそう。 - 「comment_status」:
コメントは未使用なので不要。 - 「ping_status」:
不要。 - 「sticky」:
このサイトでは未使用なので不要。使っている場合は必要になりそう。 - 「template」:
不要。 - 「format」:
不要。 - 「meta」:
どこの値のことだろ。必要なデータは揃っているのでたぶん不要。 - 「categories」:
必要だがこの状態からカテゴリ情報を取得するともう1回APIを叩かないといけないので別途用意。不要。 - 「tags」:
同上で不要。
titleとcontentは同様に文字列にします。
アクションフック「rest_prepare_post」から削除
rest_prepare_postというアクションフックは前回「_links」の削除で使用しました。
rest_prepare_postの第1引数であるWP_REST_Responseには「data」というプロパティがあり、この中に連想配列としてAPIが返すデータが入っています。
この中から不要なキーを全部unsetします。
以下、functions.phpへの追加コードです。
記事一覧に使用するAPIの削除
rest_prepare_postには前回の「_links」削除のコードも入っているんですが、今はとりあえず削除しています。
//アクションフックの追加
add_action('rest_prepare_post', 'remove_post_links', 10, 3);
//コールバック関数
function remove_post_links($response, $post, $request) {
//不要な要素の削除
unset($response->data['type']);
unset($response->data['link']);
unset($response->data['excerpt']);
unset($response->data['author']);
unset($response->data['featured_media']);
//titleをただの文字列に
$response->data['title'] = $response->data['title']['rendered'];
return $response;
}
出力結果↓。
{
"id": 101,
"date": "2020-08-13T23:29:33",
"slug": "wp-rest-slug",
"title": "(略)"
}
チョーすっきりしました。
記事ページに使用するAPIの削除
後半が記事ページ用のコードとなります。
//アクションフックの追加
add_action('rest_prepare_post', 'remove_post_links', 10, 3);
//コールバック関数
function remove_post_links($response, $post, $request) {
//embed用の要素の削除
unset($response->data['type']);
unset($response->data['link']);
unset($response->data['excerpt']);
unset($response->data['author']);
unset($response->data['featured_media']);
//titleの文字列化
$response->data['title'] = $response->data['title']['rendered'];
//view用の要素の削除
unset($response->data['date_gmt']);
unset($response->data['guid']);
unset($response->data['modified_gmt']);
unset($response->data['status']);
unset($response->data['parent']);
unset($response->data['comment_status']);
unset($response->data['ping_status']);
unset($response->data['sticky']);
unset($response->data['template']);
unset($response->data['format']);
unset($response->data['meta']);
unset($response->data['categories']);
unset($response->data['tags']);
//contentの文字列化
if ( isset($response->data['content']) ) {
$response->data['content'] = $response->data['content']['rendered'];
}
return $response;
}
contentの文字列化で条件分岐を入れていますが、僕はこの処理をembedとviewとで使い回す予定なので、contentが未定義の時(embedの時)はcontentに触れないようにしています。
(参照するとエラーが出ます)
unsetの方は存在しないキーに対してもエラーが出ないので問題ありません。
出力結果↓。
{
"id": 101,
"date": "2020-08-13T23:29:33",
"modified": "2020-08-13T23:33:14",
"slug": "wp-rest-slug",
"title": "(略)",
"content": "(略)"
}
こちらもチョーすっきり。
上記コードの注意点
titleとcontentの中身への参照方法が変わります。
REST APIの利用先がJavaScriptフレームワークの場合、
const title = json.title.rendered
const content = json.content.rendered
とアクセスしていたものがこの↓ように変わります。
const title = json.title
const content = json.content
減量効果もそれほどあるわけじゃないですし、これはやらない方がいいかもですね。 不要なトラブルを招きそう。
その他、unsetした項目については自分でunsetしたんだからアクセスできなくても怒らないでください。
削除でのサイズ減量効果
記事一覧(embed)の減量効果
初期状態(context=view)から「context=embed」への変更や「_links」の削除、そして今回の実験と段階的に比較します。
取得するのは「_links」削除の記事まで公開されている状態での、最新記事10件取得した際のAPIレスポンスサイズです。
- 初期状態
=254KB - 「context=embed」
=17.6KB - +「_links」の削除
=8.26KB - +その他の要素の削除
=2.33KB
どやぁ!!
前回の状態からも7割以上減らせました。
最初の状態と比較すると99%以上減らせています。
これだけ減らせるともうほとんど気にならないですね。
記事ページの減量効果
こちらはどうしても記事本文を含む都合、あまり減量を期待しているわけでもないですが一応。
「_links」含めた不要な要素を全削除で、減量前15KBの記事が13.2KBまで減りました。
10%ちょっとですかね。
特にこだわりがある場合を除けばこれはやらなくてもいいかも。
コピペで使えるまとめ
WordPressのREST APIを極限までスリムにするコードまとめです。 functions.phpに追加します。 今回のテスト結果に加え、前回の「_links」削除の内容も含みます。
//アクションフックの追加
add_action('rest_prepare_post', 'remove_post_links', 10, 3);
//コールバック関数
function remove_post_links($response, $post, $request) {
//embed用の要素の削除
unset($response->data['type']);
unset($response->data['link']);
unset($response->data['excerpt']);
unset($response->data['author']);
unset($response->data['featured_media']);
//以下、「_links」削除関連
$links = $response->get_links();
foreach ( $links as $key => $value) {
$response->remove_link($key);
}
return $response;
}
汎用性と効率(軽量化すべきはembedモード)を重視した結果、viewモード用のunsetと、titleとcontentの文字列化は除外しています。
必要な人は本文へ戻ってコピペしてください。
以上、WordPressからお届けしました!
WP REST APIカスタマイズ編の目次