はじめに
モバイルアプリなどのサンプルを作成している際、通信先の Web API を JSON Server で立てている方も多いかと思います。
以前に正常に動作していたサンプルが、久しぶりに触ったら動かなくなっていたので原因探りました。
結論として、JSON Server の挙動が 0 系列と 1 系列で変わった、というのが判明しました。
そもそも JSON Server とは
Web API で返して欲しいデータを JSON ファイルで定義しておき、インストールした json-server
コマンドの引数として渡して起動するだけで簡易的な Web API(CRUD 操作に対応)が用意できるというツールです。
% json-server data.json
JSON Server started on PORT :3000
Press CTRL-C to stop
Watching data.json...
(˶ᵔ ᵕ ᵔ˶)
Index:
http://localhost:3000/
Static files:
Serving ./public directory if it exists
Endpoints:
http://localhost:3000/messages
http://localhost:3000/cats
http://localhost:3000/users
上記の例では、エンドポイントである /messages
, /cats
, /users
に対応したデータ形式の定義が data.json にあり、これらのリソースへの CRUD 操作が用意されています。
簡単ですね。
JSON Server の変更点
いろいろ細かい変更点がある(たとえば、用意するデータは JSON5 フォーマットが使えるようになったとか)ようですが、一番影響度の大きいのが id 列の扱いです。
バージョン 0 系列
id プロパティを指定せずに JSON を POST すると、新規リソースに対して自動的に連番の整数が採番されます。
そのため、Web クライアント側のプログラムでは id を Int
型などの整数型で扱うようにプログラムを作成します。
バージョン 1 系列
id プロパティが文字列に変更され、POST 時には id にランダムな?文字列(公式ドキュメント上はどんな文字列なのかは触れられていない)の値が設定されます。
なお、JSON Server の 0 系列用に作成しておいた JSON ファイル(id が整数)を JSON Server 1 系列で利用すると、以下のような挙動となります。
GET でリソースを取得
- id の値がダブルクォートで囲まれて返される
POST で新規リソースを登録
- 既存の id の値がダブルクォートで囲まれる
- 新規リソースの id はランダムな?文字列が登録される
例
{
"messages": [
{
"id": 1,
"icon": "info.circle",
"headline": "共用部の掃除について",
"body": "入居者の皆様\n10月28日に、業者による共用部の掃除があります。",
"created_at": "9/27/2022, 9:00 AM"
},
[
{
"id": "1",
"icon": "info.circle",
"headline": "共用部の掃除について",
"body": "入居者の皆様\n10月28日に、業者による共用部の掃除があります。",
"created_at": "9/27/2022, 9:00 AM"
},
{
"id": "412c",
"headline": "トイレのドア開けて",
"body": "ドアが壊れました。\nトイレからでられないので、大家さんに連絡して開けてもらってください!",
"icon": "sos.circle",
"created_at": "2/9/2024, 10:51:17 AM"
}
影響
たとえば、Swift で以下のようなコードを書いていると、JSON Server の 1 系列では id の型が合わずに実行時エラーが発生します。
struct Message: Identifiable, Codable {
let id: Int? // "412c" などの文字列に変換できずにエラー
let icon: String
let headline: String
let body: String
let createdAt: String
}
まとめ
JSON Server の 0 系列を利用していた場合は、id が整数である前提のコードを記述していることがほとんどかと思われます。
その場合は、0 系列のバージョン指定して JSON Server をインストールすると良いでしょう。
sudo npm install -g json-server@0.17.4