MT6のData APIから取得したJSONをキャッシュしたりMTMLで出力したり...
公開日 : 2013-08-23 13:35:58
Movable Type 6の発表からMTDDC祭りも一段落を迎えましたが、Data APIの話の続きを少し。
RESTfulはAPIでデータ形式はJSONでということであれば、JavaScriptやPHPなんかで利用するというのが手軽そうに見えますが、早速以下のようなページを発見。
コードがPHPなのにカテゴリがPerlなのが何だけども。記事一覧を取得するサンプルのPHPコードが載っています。これ何てWordPress...(ry
<?php $baseurl = 'http://www.example.com/mt/mt-data-api.cgi/v1/sites/1/entries'; $json = file_get_contents($baseurl); $output = json_decode($json); echo "<table>"; foreach ( $output->items as $data ){ echo "<tr><th>ID</th><th>タイトル</th><th>本文</th><th>URL</th></tr>"; echo "<tr><td>{$data->id}</td><td>{$data->title}</td><td>{$data->body}</td><td>{$data->permalink}</td></tr>"; } echo "</table>";
で、以下のように扱えるプラグインを先日書いたのです(item,versionは省略可)。
<mt:JSON2MTML
instance="http://www.example.com/mt/mt-data-api.cgi"
request="/sites/1/entries" item="items" version="v1">
<mt:if name="__first__"><table></mt:if>
<tr><td><mt:var name="title"><mt:var name="body"><mt:var name="permalink"></td></tr>
<mt:if name="__last__"></table></mt:if>
</mt:JSON2MTML>
さて、本題。Data API を本当に活用しようと思うと色々ハードルがあるよね、一番は「重さ」。これ、実際には中の人も苦心してるというか、PSGI前提かキャッシュするかしないと使えないよねってポロッと吐いていたように思うのですが、吐いてたよね? (誰)
@susipaku これまであった単なるブログ更新用のAPIと決定的に違うのは、そういうのも可能になる拡張性でしょうね まぁ重いのでフロントキャッシュとかよく考える必要がありそうですけど
— たけゆー (@uzuki05) August 7, 2013
@susipaku 大事なことなので2度言いますが クッソ重いですね 現段階では。
— たけゆー (@uzuki05) August 7, 2013
— Junnama Noda (@junnama) August 7, 2013
@junnama @susipaku @uzuki05 今のDATA APIのPHP版だとすれば、無理にテンプレートを通さなくてもいいんではないでしょうか。
— Kentaro Suzuki (@riatw) August 11, 2013
無理にテンプレートを通さなくていいって、そりゃまぁその通りで、今回以下の改良をしました。
- 取得したJSONデータをキャッシュ(ファイルキャッシュ)する
- raw_data モディファイア付けることで、テンプレートを通さずにJSON文字列をそのまま出力する
ダイナミックパブリッシングもしくはDynamicMTMLで、以下のようなテンプレートを書くことで、PHPを使ったMT6のData APIのキャッシュ付きPROXYのように使えるようになります。
<mt:var name="request.api" setvar="request"><mt:json2mtml
instance="http://www.example.com/mt/mt-data-api.cgi"
request="$request" raw_data="1" cache_ttl="600"></mt:json2mtml>
以下のようなリクエストを送信
api.json?api=%2fsites%2f2%2fentries%3fsortOrder%3dascend
リクエストとパラメタをURLエンコードしてパラメタに付与してやれば、そのままPHPからData APIにアクセスして返し、結果をキャッシュします。cache_ttl="auto" とすれば mt-config.cgi で DataAPICacheTtl に指定された秒数が有効期間になります(デフォルトは600秒=10分)。またキャッシュディレクトリは同じく mt-config.cgi に DataAPICacheDir として指定してください。もちろん、PHP(スタティックパブリッシング時はMT(Perl)から読み書きできる領域を指定する必要があります。
余談? になりますが、キャッシュって生成するより削除するタミンングが難しいんですよね。関連するデータが更新された時にキャッシュを削除する、という運用になると思うのですが、MTの場合はPerlで実装しなくちゃならないのですね... ま、いーんですけど。
追記
なおRails4では削除はupdated_atをキーに含めておくことで更新があるとヒットしなくなるってアプローチになってます>削除 RT @junnama @riatw @susipaku @uzuki05 キャッシュ実装しました。 http://t.co/McXMjFMjBP
— たけゆー (@uzuki05) August 23, 2013
updated_at="entry"モディファイアを付与することで、更新/削除のタイミングでキャッシュをクリアするようにしました。同一のMT上で動かしていることが前提になりますが。
追記(その2)
MT通さないPHP軽量版。値の渡し方も同じ形式で行ける。例: /mt-data-api-proxy.php/v1/sites/2/entries?sortOrder=decend&updated_at=entry&cache_ttl=800