WordPressのREST APIから「guid」など不要な項目を削除する

シェアする:

この記事をおすすめしたい人

  • 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からお届けしました!

シェアする: