logo icon

WordPress REST APIでイマドキHeadless CMS

WordPress REST APIでイマドキHeadless CMS

正直あまり時流に乗れていないのですが、昨今フロントエンドとバックエンドを分離してフロントにより自由度を! とのコンセプトのもと「Headless(ヘッドレス) CMS」なるものが流行しているそうです。

国内ではあまりサービスは見られないものの、海外ではHeadless CMSの先駆けとして「Elemeno」、そしてFacebook社も「GraphCMS」をリリースしています。

確かにCMSからViewを分離できれば、

  • CMS側ではJSON(API)のみになるためフロント側が言語に依存しない
  • ホスティングされたものが使えるため自前のサーバーがいらず、セキュリティ等もおまかせ

等のメリットがあります。

とはいえ、やはりそこは枯れたWordPress。
痒いところに手が届くプラグイン群日本語のUIはクライアントワークには欠かせません。

そこで、「インストールしたらまずはREST APIをオフに」等いわれてはいますが、そこを敢えてWordPressをJSON出力マシーンとして利用し、ViewはReact等のナウいライブラリを使ってやってみたいと思います。

なお、この記事はWordPress Advent Calendar 2017、22日目の記事です。
そしてわたしはモロ(@moro_is)です。

WordPressのViewを無効化

まずはWordPressのViewをなくす必要があるため、空っぽのThemeを用意します。

https://github.com/moroi/headless-wordpress

はい。
空のindex.php style.cssと、いくつかの設定を詰め込んだfunctions.phpのみです。

<?php
function my_customize_rest_cors() {
  remove_filter( 'rest_pre_serve_request', 'rest_send_cors_headers' );
  add_filter( 'rest_pre_serve_request', function( $value ) {
    header( 'Access-Control-Allow-Origin: *' );
    return $value;
  });
}
add_action( 'rest_api_init', 'my_customize_rest_cors', 15 );
?>

個人的にせっかくWordPressの制約から開放される以上、あまりfunctions.phpで複雑なことをしたくなかったため、あくまで新しいAPIを生やしたりはせずにおります。

my_customize_rest_cors()はクロスドメイン対策のため同ドメイン上での実装の場合は不要で、もし別ドメインでの運用の場合もAccess-Control-Allow-Origin: *は避けて、個別にホワイトリスト対応(Access-Control-Allow-Origin: https://example.com)のようなことをしたほうがいいかも知れません。

プラグイン周り

WordPressの利点でもある豊富なプラグインは活かしたかったため、いくつか導入しました。

Advanced Custom Fields(ACF to REST API)

https://wordpress.org/plugins/advanced-custom-fields/

言わずと知れたカスタムフィールドを便利にするプラグイン。
併せてACF to REST APIを入れることでAPI側からも簡単にカスタムフィールドの値を取得できるようになります。

Jetpack by WordPress.com

https://wordpress.org/plugins/jetpack/

こちらもWP公式の多機能便利プラグイン。
これを導入することで、WordPress.com経由で「WordPress.com Jetpack API」が利用できるようになり、例えば

  • アクセス数ランキング
  • 「メニュー」の取得

等もできるようになります。
WordPress REST APIと比べると

  • WordPress.com経由のためアクセス元が制限できない
  • 若干通信が遅い

等のデメリットもありますが、場合によっては重宝するかも知れません。

No Category Base (WPML)

フロント側を例えばReact等で制作する場合、恐らくReact-Router等使うので実際的には必要ないのですが、例えばフロント側で用意するのが面倒くさいSitemap.xml等は

  • WordPress アドレス (URL)をapi.example.com
  • サイトアドレス (URL)をexample.com
  • WordPressの「パーマリンク設定」をフロント側と揃える

にして、URLの辻褄を合わせればGoogle XML Sitemapsでさくっと実装できます。

WP REST API Menus

先述のWordPress.com Jetpack APIでもメニューは取れるのですが珍しいAPI対応プラグインだったので一応。

APIのデータを取得する

以上でWordPressのHeadless CMS化はほぼ完了、あとは「WP REST API v2 Documentation」を参考に思う様データを取得するだけです。
この辺りはある程度情報が豊富なため検索すればすぐに調べられますが、基本的な部分のみ念のため書いておきます。

WordPress REST API

新着投稿5件を取得

http://api.example.com/wp-json/wp/v2/posts?per_page=5

新着投稿5件を「おまけ情報を添えて」取得

http://api.example.com/wp-json/wp/v2/posts?_embed&per_page=5

新着投稿5件を取得

http://api.example.com/wp-json/wp/v2/posts?per_page=5

カテゴリーID「7」の新着投稿5件を取得

http://api.example.com/wp-json/wp/v2/posts?categories=7&per_page=5

タグ「75」の新着投稿を5件ずつ取得した場合の4ページ目を取得

http://api.example.com/wp-json/wp/v2/posts?tags=75&page=4&per_page=5

検索

http://api.example.com/wp-json/wp/v2/posts?search=テキスト

ID「284」の個別投稿を取得

http://api.example.com/wp-json/wp/v2/posts/284

ID「284」の個別投稿を「おまけ情報を添えて」取得

http://api.example.com/wp-json/wp/v2/posts/284?_embed

カテゴリー一覧

http://api.example.com/wp-json/wp/v2/categories

タグ一覧

http://api.example.com/wp-json/wp/v2/tags

WordPress.com Jetpack API

要Author認証

投稿ID「278」の関連記事を取得

https://public-api.wordpress.com/rest/v1/sites/example.com/posts/278/related

アクセス数ランキングを取得

https://public-api.wordpress.com/rest/v1.1/sites/example.com/stats/top-posts

メニューID「4」のメニューを取得

https://public-api.wordpress.com/rest/v1.1/sites/example.com/menus/4

散々既出の情報が多く恐縮ですが以上です。

なお、肝心のフロント部分はhttps://github.com/moroi/react-wordpressでせっせと開発中です。
ぜひPR等でご助力くださいませ。

ではでは。