🤨

[Web API]レスポンスデータ設計(配列を返す) PythonでJSON配列データ作る

2023/06/21に公開

はじめに


WEB APIのレスポンスデータとして配列を返したい場合、どのようなフォーマットで返すのが良いのか調べた結果、「配列をそのまま返さずに、配列をオブジェクトで包む」フォーマットの方が良いという結論に至りましたのでその理由と、Pythonでのレスポンスデータ作成処理についても参考程度に載せます。

配列とフォーマット

WEB APIのレスポンスデータとして配列を返したい場合、具体的には以下の2つがあります。

  • 配列をそのまま返す
  • 配列をオブジェクトとして包む
配列をそのまま返す
[
    {
        "userid": "1001",
        "name": "JAMES"
    },
    {
        "userid": "1002",
        "name": "JOHN"
    },
    {
        "userid": "1003",
        "name": "ROBERT"
    }
]
配列をオブジェクトとして包む
[
    "users": [
        {
            "userid": "1001",
            "name": "JAMES"
        },
        {
            "userid": "1002",
            "name": "JOHN"
        },
        {
            "userid": "1003",
            "name": "ROBERT"
        }
]

どちらがいいの?

以下のメリット、デメリットから「配列をそのまま返さずに、配列をオブジェクトで包む」フォーマットの方が良いという結論に至りました。

  • JSON仕様
    • JSONとしてはどちらでも問題ない。
  • 「配列をそのまま返す」メリット
    • 配列だけ返した方がサイズが小さくなる。→そんなに変わらない。
  • 「配列をオブジェクトとして包む」メリット
    • 何のデータか明確
  • 「配列をそのまま返す」デメリット
    • セキュリティ上のリスク
      • トップレベルが配列であるJSONは、JSONインジェクションのリスクが大きくなる。
        ※script要素を使ってブラウザで読みことができない(Cookieではなくリクエストヘッダに認証情報などを追加しなければ取得できない)APIの場合は、問題ないと言える。

Pythonでのレスポンスデータ生成処理

json.dumpsでJSON文字列にします。

import json

list_data = [{"userid": "1001","name": "JAMES"},{"userid": "1002","name": "JOHN"},{"userid": "1003","name": "ROBERT"}]
json_data = json.dumps(list_data, indent=2, ensure_ascii=False)
print(json_data)

だと、こうなる。

[
  {
    "userid": "1001",
    "name": "JAMES"
  },
  {
    "userid": "1002",
    "name": "JOHN"
  },
  {
    "userid": "1003",
    "name": "ROBERT"
  }
]

「配列をオブジェクトとして包む」ためにはこうする。
辞書オブジェクトに入れて、json.dumpsでJSON文字列にします。

import json

list_data = [{"userid": "1001","name": "JAMES"},{"userid": "1002","name": "JOHN"},{"userid": "1003","name": "ROBERT"}]
dict_data = {'users': list_data}
json_data = json.dumps(dict_data, indent=2, ensure_ascii=False)
print(json_data)

こうなる。

{
  "users": [
    {
      "userid": "1001",
      "name": "JAMES"
    },
    {
      "userid": "1002",
      "name": "JOHN"
    },
    {
      "userid": "1003",
      "name": "ROBERT"
    }
  ]
}

OK!!

参考文献

  • 『Web API The Good Parts』(水野貴明 著, オライリー・ジャパン社, 2014年11月)

Discussion