リストレベルと項レベルCRUD動作を同時にサポートします

作者:張ジョン(John Chang)

これは、リストレベルCRUD動作と項レベルCRUD動作の両方をサポートする簡単な項リストをどのように実装するかの例である。

特に、リスト全体(すべての項目を含む)を単一のGETを使用して取得することができるはずであり、パッチリストではなく、単一のPOSTを使用して1つの項を追加することもできる。

解決策は,データベースイベントフックを用いて埋め込みサブ文書に注入することである. (items )を親リストに追加し、親リストが削除されたときに子項目を削除する。それが二つのデータベース照会をもたらすにもかかわらず、これは可能だ。

main.py

from eve import Eve
from bson.objectid import ObjectId

app = Eve()
mongo = app.data.driver


def after_fetching_lists(response):
    list_id = response['_id']
    f = {'list_id': ObjectId(list_id)}
    response['items'] = list(mongo.db.items.find(f))


def after_deleting_lists(item):
    list_id = item['_id']
    f = {'list_id': ObjectId(list_id)}
    mongo.db.items.delete_many(f)

app.on_fetched_item_lists += after_fetching_lists
app.on_deleted_item_lists += after_deleting_lists

app.run()

settings.py

import os

DEBUG = True

MONGO_HOST = os.environ.get('MONGO_HOST', 'localhost')
MONGO_PORT = os.environ.get('MONGO_PORT', 27017)
MONGO_USERNAME = os.environ.get('MONGO_USERNAME', 'user')
MONGO_PASSWORD = os.environ.get('MONGO_PASSWORD', 'user')
MONGO_DBNAME = os.environ.get('MONGO_DBNAME', 'listtest')

RESOURCE_METHODS = ['GET', 'POST', 'DELETE']
ITEM_METHODS = ['GET', 'PUT', 'PATCH', 'DELETE']

DOMAIN = {
    'lists': {
        'schema': {
            'title': {
                'type': 'string'
            }
        }
    },
    'items': {
        'url': 'lists/<regex("[a-f0-9]{24}"):list_id>/items',
        'schema': {
            'list_id': {
                'type': 'objectid',
                'data_relation': {
                    'resource': 'lists',
                    'field': '_id'
                }
            },
            'name': {
                'type': 'string',
                'required': True
            }
        }
    }
}

用法

$ curl -i -X POST http://127.0.0.1:5000/lists -d title="My List"
HTTP/1.0 201 CREATED

{
    "_id": "58960f83a663e2e6746dfa6a",
    :
}

$ curl -i -X POST http://127.0.0.1:5000/lists/58960f83a663e2e6746dfa6a/items -d 'name=Alice'
HTTP/1.0 201 CREATED

$ curl -i -X POST http://127.0.0.1:5000/lists/58960f83a663e2e6746dfa6a/items -d 'name=Bob'
HTTP/1.0 201 CREATED

$ curl -i -X GET http://127.0.0.1:5000/lists/58960f83a663e2e6746dfa6a
HTTP/1.0 200 OK

{
    "_created": "Sat, 04 Feb 2017 17:29:39 GMT",
    "_etag": "01799f6be25a044ab95cfeb2dc0f834d11b796d8",
    "_id": "58960f83a663e2e6746dfa6a",
    "_updated": "Sat, 04 Feb 2017 17:29:39 GMT",
    "items": [
        {
            "_created": "Sat, 04 Feb 2017 17:30:06 GMT",
            "_etag": "72ad9248ad5bf45c7bfe3e03a1b9bc384d94572f",
            "_id": "58960f9ea663e2e6746dfa6b",
            "_updated": "Sat, 04 Feb 2017 17:30:06 GMT",
            "list_id": "58960f83a663e2e6746dfa6a",
            "name": "Alice",
            "quantity": 1
        },
        {
            "_created": "Sat, 04 Feb 2017 17:30:13 GMT",
            "_etag": "447f51b057fb5e0a70472e96ff883c64b5e2e308",
            "_id": "58960fa5a663e2e6746dfa6c",
            "_updated": "Sat, 04 Feb 2017 17:30:13 GMT",
            "list_id": "58960f83a663e2e6746dfa6a",
            "name": "Bob",
            "quantity": 1
        }
    ],
    "title": "My List"
}

$ curl -i -X DELETE http://127.0.0.1:5000/lists/58960f83a663e2e6746dfa6a/items/58960f9ea663e2e6746dfa6b -H "If-Match: 72ad9248ad5bf45c7bfe3e03a1b9bc384d94572f"
HTTP/1.0 204 NO CONTENT

$ curl -i -X GET http://127.0.0.1:5000/lists/58960f83a663e2e6746dfa6a
HTTP/1.0 200 OK

{
    "_created": "Sat, 04 Feb 2017 17:29:39 GMT",
    "_etag": "01799f6be25a044ab95cfeb2dc0f834d11b796d8",
    "_id": "58960f83a663e2e6746dfa6a",
    "_updated": "Sat, 04 Feb 2017 17:29:39 GMT",
    "items": [
        {
            "_created": "Sat, 04 Feb 2017 17:30:13 GMT",
            "_etag": "447f51b057fb5e0a70472e96ff883c64b5e2e308",
            "_id": "58960fa5a663e2e6746dfa6c",
            "_updated": "Sat, 04 Feb 2017 17:30:13 GMT",
            "list_id": "58960f83a663e2e6746dfa6a",
            "name": "Bob",
            "quantity": 1
        }
    ],
    "title": "My List"
}