3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Android開発するときのモックAPIサーバ(json:api互換)

Posted at

はじめに

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で実践的なアプリを書く方法を今度書きます。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?