はじめに
node.jsを使ってモックAPIサーバを立てます。
よくある方法
jsonファイルからAPIサーバのモック作るときはjson-serverがいい感じです。下記のようなjsonを用意しておくと /users
, /users/1
といったエンドポイントを自動生成してくれます。詳しくは公式ドキュメントを読むといいです。
{
"users": [
{"id": 1, "email": "hoge@example.com", "profile": {"id": 1, "name": "coldplay"}},
{"id": 2, "email": "saba@example.com", "profile": {"id": 2, "name": "deathcab"}}
]
}
json:api互換ではjson-serverが使えない
対象のAndroidアプリのバックエンドAPIは json:api 互換となっています。json:api形式では上記の方法ではうまくいきません。
下記のように単純に配列にオブジェクトが入った状態で表現できないからです。
複数の場合のフォーマット
{
"data": [
{"id": 1, "type": "users", "attributes": {"email": "hoge@example.com"}, "relationships": {"profile": {"id": 1, "type": "profiles"}}, "included": [{"data": {"id": 1, "type": "profiles", "attributes": {"name": "coldplay"}}}]},
{"id": 1, "type": "users", "attributes": {"email": "hoge@example.com"}, "relationships": {"profile": {"id": 2, "type": "profiles"}}, "included": [{"data": {"id": 2, "type": "profiles", "attributes": {"name": "deathcab"}}}]}
]
}
単数の場合のフォーマット
{
"data": {
"id": 1,
"type": "users",
"attributes": {"email": "hoge@example.com"},
"relationships": {"profile": {"id": 1, "type": "profiles"}},
"included": [{"data": {"id": 1, "type": "profiles", "attributes": {"name": "coldplay"}}}]
}
}
解法(Expressで実装する)
src/test/dummy/server.js
var express = require('express')
var app = express();
var _ = require('lodash-node')
var router = express.Router();
var users = [
{"id": 1, "type": "users", "attributes": {"email": "hoge@example.com"}, "relationships": {"profile": {"id": 1, "type": "profiles"}}, "included": [{"data": {"id": 1, "type": "profiles", "attributes": {"name": "coldplay"}}}]},
{"id": 1, "type": "users", "attributes": {"email": "hoge@example.com"}, "relationships": {"profile": {"id": 2, "type": "profiles"}}, "included": [{"data": {"id": 2, "type": "profiles", "attributes": {"name": "deathcab"}}}]}
]
function find(resources, id) {
return _.find(resources, function(resource) {
return parseInt(resource.data.id) === parseInt(id);
})
}
function toCollectionFmt(resources) {
return _.reduce(resources, function(acc, resource) {
acc['data'].push(resource.data)
return acc
}, { data: [] })
}
router.get('/:resources', function(req, res) {
console.log('get: ' + req.params.resources)
res.json(toCollectionFmt(eval(req.params.resources)))
})
router.get('/:resources/:id', function(req, res) {
console.log('get: ' + req.params.resources + '/' + req.params.id)
resource = find(eval(req.params.resources), req.params.id)
res.json(resource)
})
app.use('/', router)
app.listen(3000)
console.log('the server is ready!')
json:api
json:apiはYahuda Katzによって提唱された規格で、HALなどで問題となっていた相互参照によるネスト問題などを、フラットに出力することで解決してくれる良いものです。一読あれ。
Links
retrofitでjson:apiを扱う方法を今度書きます。
retrofit + realmで実践的なアプリを書く方法を今度書きます。