我正在尝试使用Eve为简单的项目列表提供RESTful API。
我想使用1)一个HTTP请求来创建一个列表(可能带有初始项),2)一个HTTP请求添加一个项(一个常见的操作),3)一个HTTP请求来获取列表(包括所有子项)。换句话说:
1)POST /lists
与身体
{
"title": "My List",
"items": [{
"name": "Alice"
},
{
"name": "Bob"
}]
}
2)POST /lists/555555555555555555555555/items
与身体
{
"name": "Carol"
}
3)GET /lists/555555555555555555555555
{
"_id": "555555555555555555555555",
"title": "My List",
"items": [{
"_id": "aaaaaaaaaaaaaaaaaaaaaaaa",
"name": "Alice"
},
{
"_id": "bbbbbbbbbbbbbbbbbbbbbbbb",
"name": "Bob"
},
{
"_id": "cccccccccccccccccccccccc",
"name": "Carol"
}]
}
我还没弄明白如何用Eve做这件事。我可以(1)使用嵌入的dicts列表,但是我不能做(2) - 我必须POST一个项目,然后PATCH列表(?)。我可以做(2)使用子资源,但我不能做(1)("value '{'name': 'Alice'}' cannot be converted to a ObjectId"
)。或者我错过了什么?
如果不能完成所有这三项,至少可以(2)和(3)?
答案 0 :(得分:3)
我想出了如何实现(2)和(3),使用数据库事件挂钩将嵌入的子文档注入父列表,然后将其返回给客户端(并且还删除父项时的子项)被删除)。这适用于并支持单个列表项上的预期REST使用。但是,它会产生两个数据库查询。
我怀疑(1)也可以使用事件挂钩实现,但现在就足够了。
欢迎任何进一步的改进/建议。如果有更简单的方法可以实现这一目标(关键字:One-to-Many Relationships with Embedded Documents)。
RESOURCE_METHODS = ['GET', 'POST', 'DELETE']
ITEM_METHODS = ['GET', 'PUT', 'PATCH', 'DELETE']
lists = {
'schema': {
'title': {
'type': 'string'
}
}
}
items = {
'url': 'lists/<regex("[a-f0-9]{24}"):list_id>/items',
'schema': {
'name': {'type': 'string',
'required': True
},
'list_id': {
'type': 'objectid',
'required': True,
'data_relation': {
'resource': 'lists',
'field': '_id'
}
}
}
}
DOMAIN = {
'lists': lists,
'items': items
}
from bson.objectid import ObjectId
def before_returning_lists(response):
list_id = response['_id']
response['items'] = list(db.items.find({'list_id': ObjectId(list_id)}))
def after_deleting_lists(item):
list_id = item['_id']
db.items.delete_many({'list_id': ObjectId(list_id)})
app.on_fetched_item_lists += after_fetching_lists
app.on_deleted_item_lists += after_deleting_lists
curl -X POST http://127.0.0.1:5000/lists -d title="My List"
# (2)
curl -X POST http://127.0.0.1:5000/lists/5895fdb5a663e2dcad9e7647/items -d 'name=Alice'
curl -X POST http://127.0.0.1:5000/lists/5895fdb5a663e2dcad9e7647/items -d 'name=Bob'
curl -X POST http://127.0.0.1:5000/lists/5895fdb5a663e2dcad9e7647/items -d 'name=Carol'
# (3)
curl -X GET http://127.0.0.1:5000/lists/5895fdb5a663e2dcad9e7647