Bottle を使用してAPIを作成していますが、これはこれまでのところ素晴らしいことです。ただし、JSON配列を返そうとすると、小さなハードルにぶつかります。テストアプリのコードは次のとおりです。
from bottle import route, run
@route('/single')
def returnsingle():
return { "id": 1, "name": "Test Item 1" }
@route('/containsarray')
def returncontainsarray():
return { "items": [{ "id": 1, "name": "Test Item 1" }, { "id": 2, "name": "Test Item 2" }] }
@route('/array')
def returnarray():
return [{ "id": 1, "name": "Test Item 1" }, { "id": 2, "name": "Test Item 2" }]
run(Host='localhost', port=8080, debug=True, reloader=True)
これを実行して各ルートをリクエストすると、最初の2つのルートから予想されるJSON応答を取得します。
/ single
{ id: 1, name: "Test Item 1" }
/ containsarray
{ "items": [ { "id": 1, "name": "Test Item 1" }, { "id": 2, "name": "Test Item 2" } ] }
そのため、辞書のリストを返して次のJSON応答を作成することを期待していました。
[ { "id": 1, "name": "Test Object 1" }, { "id": 2, "name": "Test Object 2" } ]
しかし、/array
routeはエラーになります。私は何を間違えていますか?この方法でJSON配列を返すにはどうすればよいですか?
BottleのJSONプラグインは、配列ではなくdictのみが返されることを期待しています。 JSON配列を返すことに関連する脆弱性があります。たとえば、 JSONハイジャックに関するこの投稿 を参照してください。
本当にこれを行う必要がある場合は、それを行うことができます。
@route('/array')
def returnarray():
from bottle import response
from json import dumps
rv = [{ "id": 1, "name": "Test Item 1" }, { "id": 2, "name": "Test Item 2" }]
response.content_type = 'application/json'
return dumps(rv)
Bottleの0.12ドキュメントによると:
上記のように、Python辞書(またはそのサブクラス)は自動的にJSON文字列に変換され、Content-Typeヘッダーをapplication/jsonに設定してブラウザーに返されます。これにより、jsonの実装が容易になります。ベースのAPI。json以外のデータ形式もサポートされています。詳細については、tutorial-output-filterを参照してください。
つまり、import json
や応答のcontent_type属性を設定する必要はありません。
したがって、コードは大幅に削減されます。
@route('/array')
def returnarray():
rv = [{ "id": 1, "name": "Test Item 1" }, { "id": 2, "name": "Test Item 2" }]
return dict(data=rv)
また、Webサーバーから返されるJSONドキュメントは次のようになります。
{"data": [{"id": 1, "name": "Test Item 1"}, {"id": 2, "name": "Test Item 2"}]}