はじめに
Node.js製のCMSであるKeystoneJSではレスポンスをhtmlではなくjsonで返すAPIもほぼ準備されている(実際に使うには多少コード修正が必要)のですが、公式ドキュメントでの記載がなく、gistの内容も若干古いようなので、現時点で最新のバージョンで試して、注意点などを残しておきます。
Gist
元になるのはコミッターのJedWatson氏の記事です
先に差分となる部分を書いておくとルーティングで
app.get('/api/post/list', keystone.initAPI, routes.api.posts.list);
でなく
app.get('/api/post/list', keystone.middleware.api, routes.api.posts.list);
のように第二引数がkeystone.initAPI
からkeystone.middleware.api
に変わります。
他はGist通りで動作します。
環境
Mac
Node.js v7.0.0
npm 3.10.8
generator-keystone@0.4.2
mongod --version 3.0.6 #brewでinstall
generatorでinstall
npm install -g yoeman $ npm install -g generator-keystone $ mkdir myproject $ cd myproject $ yo keystone $ cd my-site # my-siteという名前で新規ディレクトリを作成してinstallした場合 $ npm install --save keystone@next
なおまだベータの4.0を選んだのはこの記事の賞味期限を延ばすため、できるだけ最新にしておこうといった程度の理由です。
$ npm start
で起動します。
※なお、npm startでMongoDBはローカル環境で起動済みである必要があります
ブラウザから localhost:3000
でアクセスできます。
ブログ一覧をAPI取得できるようにする例
API作成
mkdir routes/api
で新規にフォルダを作成し
routes/views/blog.js
を上記フォルダにコピーします。
次に
routes/index.jsを以下のように修正します
//略
// Import Route Controllers
var routes = {
views: importRoutes('./views'),
//追加[1]ここから
api: importRoutes('./api')
//追加[1]ここまで
};
// Setup Route Bindings
exports = module.exports = function (app) {
// Views
app.get('/', routes.views.index);
app.get('/blog/:category?', routes.views.blog);
app.get('/blog/post/:post', routes.views.post);
app.get('/gallery', routes.views.gallery);
app.all('/contact', routes.views.contact);
//追加[2]ここから
app.get('/api/blog/:category?', keystone.middleware.api, routes.api.blog);
//追加[2]ここまで
// NOTE: To protect a route so that only admins can see it, use the requireUser middleware:
// app.get('/protected', middleware.requireUser, routes.views.protected);
};
//略
これでkeystoneを再起動すれば/api/blog
で/blog
と同じコンテンツが表示されます。
htmlからjsonへ
ここで routes/api/blog.jsを編集し
view.render('blog');
を
に置き換えれば済みそうですが
view.on('init', function (next) {
略
}
は
view.render('blog');
の記述がないと動作しない。
実際Gistのサンプルにはview.on
は使われていませんね。
補足
Gistに対するコメントの中に
res.apiResponse でなく res.send or res.json
でいいんじゃないの?という指摘があり
自分も気になって理由を調べてみたのですが
コードを見る限り jsonとjsonpを自動で切り替えてくれる制御が入っていました。
意味のないwrapperではなさそうです。
次の目標
React+SPA化を試してみたいですね