1. ホーム
  2. Ruby on Rails
  3. RailsからWordPressの記事一覧をREST APIで取得する

RailsからWordPressの記事一覧をREST APIで取得する

目次

  1. はじめに
  2. REST APIとは
  3. REST API で記事一覧を取得してみる
  4. ページを分割して取得する
  5. Rails側からWordPressの記事一覧を取得
  6. まとめ

はじめに

WordPressのVersion4.7系で遂にWordPressのREST APIが標準で搭載されるようになりました。
4.7.1ではセキュリティ上致命的なバグがありましたが、4.7.2以降は今のところ安定しています。
WordPress の脆弱性対策について IPA

このREST APIを上手く活用することで、記事一覧を外部サービスから取得したり更新したりすることが可能になります。
今回は「Ruby on Rails側で業務システム、WordPressでメディアを運営している中で、業務システム側にメディアの記事情報を表示させたい」などのケースにおいて記事を取得する方法をご紹介します。

REST APIとは

WordPress REST APIはVersion4.7から採用された、RESTfulなAPIです。
記事を取得することはもちろん、記事の作成や更新まで外部から行うことができます。
日本語ドキュメント

今までXML-RPCによる記事投稿等は機能として用意されていましたが、REST APIを使用することでより柔軟に記事などを外部から参照・更新することができます。
例えばWordPressのURLの後ろに /wp-json/wp/v2/posts をつけてアクセスする(GETメソッド)だけで記事一覧を取得できます。

REST API で記事一覧を取得してみる

こちらのデモサイトにアクセスしてみてください。
https://demo.wp-api.org/wp-json/wp/v2/posts
するとJSON形式で画面上に記事の一覧が表示されるはずです。

POINT!!

Google Chromeの場合、こちらの JSONView という拡張機能を使うことでJSONが見やすい形式になります。
Firefoxの場合はこちらです。

Rails側からWordPressの記事一覧を取得

一覧を取得する為には先述のGETメソッドで取得したいエンドポイントにアクセスする必要があります。
Ruby標準の net/http というライブラリを使うこともできますが、net/http はもちろん、拡張機能も豊富でより便利な Faraday を使ってみましょう。

まず、Gemfileに gem 'faraday' を追加し、 bundle install しましょう。

# まず接続設定をおこなう
conn = Faraday.new(url: 'https://demo.wp-api.org') do |faraday|
  faraday.request  :url_encoded             # form-encode POST params
  faraday.response :logger                  # log requests to STDOUT
  faraday.adapter  Faraday.default_adapter  # make requests with Net::HTTP
end

# GETで記事一覧を取得する
response = conn.get '/wp-json/wp/v2/posts'  

# JSONをパースする
parsed_articles = JSON.parse(response.body) 

# 記事一覧が出て来るので展開する
parsed_articles.each do |article|
  p article['id'] #記事id
  p article['title'] #タイトル
  p article['content'] #本文
end

こんな感じで表示することができます。
contentはHTMLタグが含まれているので、適度にsanitizeして表示させましょう。

ページを分割して取得する

これで一件落着かと思いきや、そうではありません。
今回は全ての記事を取得し、そちらで処理をしたいという要件となります。

実は1ページ分(1回のリクエスト)で取得できる記事は100記事までです。
この記事数の指定は per_page で設定できますが、
例えばこのように500ページを指定してアクセスするとエラーが出るはずです。
https://demo.wp-api.org/wp-json/wp/v2/posts?per_page=500

その為、100記事以上あるページについては一回のリクエストで取得できない為、
ページ分割して取得していく必要があります。

per_page のデフォルト値は10ですが、100を指定してみましょう。
また page オプションを指定することで指定のページの記事を取得することができます。
つまり、1〜100件目までの記事を取得したい場合は
https://demo.wp-api.org/wp-json/wp/v2/posts?per_page=100&page=1
となり、101件目から200件目までの記事を取得したい場合は、
https://demo.wp-api.org/wp-json/wp/v2/posts?per_page=100&page=2
となるわけです。
※デモページの記事数を超えてしまう為、2つ目はエラーになります。

POINT!!

pageやper_page以外にも指定できるパラメータがいくつかあります。
例えばsearchで検索したい項目を指定することができます。
https://demo.wp-api.org/wp-json/wp/v2/posts?search=Quia
こちらのURLの場合、「Quia」が含まれるpostsを検索することができます。
他にもstatusを指定し非公開の記事のみを取得することなど、様々なパラメータがあるのでぜひ調べてみてください。
list-postsに関するドキュメント

記事数を超えたページ数を指定するとエラーとなる為、
全体のページ数がどれくらいなのか把握する必要があります。
この値はheaderのx-wp-totalpages に入っているので
これを利用しましょう。

前置きが長くなりましたが、こんなコードで記事一覧を表示することができます。
app/services/wp_client.rb

class WpClient
  # まずコネクション設定
  def initialize
    @conn = Faraday.new(url: WORDPRESS_URI) do |builder|
      builder.request :url_encoded
      builder.response :logger
      builder.adapter :net_http
    end
  end

  # 記事一覧を取得
  def list_articles(path)
    res = @conn.get do |req|
      req.url path
    end
  end
end

次にこの記事一覧を取得します。

wp_client = WpClient.new
path = 'wp-json/wp/v2/posts?per_page=100'
res  = wp_client.list_articles(path)
 # トータルページ数取得
total_pages = res.headers['x-wp-totalpages']
total_pages.times do |n|
  next_path = "#{path}&page=#{n}"
  res = wp_client.list_articles(next_path)
  parsed_articles = JSON.parse(res.body) 
  # 個々の記事を表示させる(割愛)
end

こんな感じですね。
実際に使う際はもう少しすっきりさせたいところです。
また、わかりやすいようにページ数取得の為の処理を最初に挟みましたが、まとめてやってしまったほうが楽かもしれません。

Advance Custom Fieldsの値も取得

投稿に紐付けられたカスタムフィールドはそのままでも取得できますが、Advance Custom Fieldsで設定した値を取得したいという場合もあるかと思います。
その場合はACF to REST APIというプラグインを使いましょう。
ACF to REST API

これで先程のURIにGETメソッドでアクセスすることで、Advance Custom Fieldsの値も取得することができます。

まとめ

WordPressのREST APIを使用することで、簡単に記事の取得や作成をすることができます。
今回は記事一覧の取得だけでしたが、今後は記事の作成や更新等、より便利な内容をご紹介していきます。

Author Profile

eishis
eishis
SIerやスタートアップ、フリーランスを経て2016年11月にeishis, Inc.を設立。
マーケター・ディレクター・エンジニアなど何でも屋。
COBOLからReactまで色んなことやります。

この記事は
参考になりましたか?

PAGE TOP