How to implement an extended list of built-in objects

I am trying to use Eve to provide a RESTful API for a simple list of items.

I would like to use 1) one HTTP request to create a list (possibly with initial elements), 2) one HTTP request to add element (s) (general operation), 3) one HTTP request to get a list (including all child elements). In other words:

1) POST /lists with body

 { "title": "My List", "items": [{ "name": "Alice" }, { "name": "Bob" }] } 

2) POST /lists/555555555555555555555555/items with body

 { "name": "Carol" } 

3) GET /lists/555555555555555555555555

 { "_id": "555555555555555555555555", "title": "My List", "items": [{ "_id": "aaaaaaaaaaaaaaaaaaaaaaaa", "name": "Alice" }, { "_id": "bbbbbbbbbbbbbbbbbbbbbbbb", "name": "Bob" }, { "_id": "cccccccccccccccccccccccc", "name": "Carol" }] } 

I did not understand how to do this with Eve. I can do (1) using the built-in dicts list, but then I can not do (2) - I needed to send a POST element, and then a PATCH list ( ? ). I can do (2) using sub-resources, but then I can not do (1) ( "value '{'name': 'Alice'}' cannot be converted to a ObjectId" ). Or am I missing something?

If all three cannot be fulfilled, perhaps at least (2) and (3)?

+5
source share
1 answer

I figured out how to implement (2) and (3) using database event hooks to embed embedded child documents in the parent list before it returns to the client (and also remove the children when the parent is removed). This works and supports the expected use of REST for individual list items. However, this leads to two database queries.

I suspect that (1) can also be implemented using an event hook, but this is enough for now.

Any further improvements / suggestions are welcome. It would be nice if there was an easier way to accomplish this (keywords: One-to-many relationships with embedded documents ).

settings.py:

 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 } 

main.py:

 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 

Using

 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 
+3
source

Source: https://habr.com/ru/post/1263448/


All Articles