Как вернуть массив JSON с помощью 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)
когда я запускаю это и запрашиваю каждый маршрут, я получаю ответы 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
маршрут просто приводит к ошибке. Что я делаю неправильно и как я могу вернуть JSON массив таким образом?
2 ответов
плагин JSON бутылки ожидает, что будут возвращены только дикты-не массивы. Существуют уязвимости, связанные с возвратом массивов 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)
согласно документации бутылки 0.12:
как упоминалось выше, словари Python (или их подклассы) являются автоматически преобразуется в строки JSON и возвращается в браузер с заголовком Content-Type, установленным в application / json. Этот упрощает реализацию API на основе json. Данные форматы 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)
и документ JSON, возвращенный веб-сервером, будет выглядеть так:
{"data": [{"id": 1, "name": "Test Item 1"}, {"id": 2, "name": "Test Item 2"}]}