Eve: как использовать разные конечные точки для доступа к одной и той же коллекции с разными фильтрами

У меня есть приложение Eve, публикующее простой интерфейс только для чтения (GET). Он взаимодействует с коллекцией MongoDB под названием centroids, в которой есть такие документы, как:

[
{
  "name":"kachina chasmata",
  "location":{
    "type":"Point",
    "coordinates":[-116.65,-32.6]
  },
  "body":"ariel"
},
{
  "name":"hokusai",
  "location":{
    "type":"Point",
    "coordinates":[16.65,57.84]
  },
  "body":"mercury"
},
{
  "name":"cañas",
  "location":{
    "type":"Point",
    "coordinates":[89.86,-31.188]
  },
  "body":"mars"
},
{
  "name":"anseris cavus",
  "location":{
    "type":"Point",
    "coordinates":[95.5,-29.708]
  },
  "body":"mars"
}
]

В настоящее время настройки (Eve) объявляют DOMAIN следующим образом:

crater = {
    'hateoas': False,
    'item_title': 'crater centroid',
    'url': 'centroid/<regex("[\w]+"):body>/<regex("[\w ]+"):name>',
    'datasource': {
        'projection': {'name': 1, 'body': 1, 'location.coordinates': 1}
    }
}

DOMAIN = {
    'centroids': crater,
}

Который будет успешно отвечать на запросы вида http://hostname/centroid/<body>/<name>. Внутри MongoDB это представляет запрос типа: db.centroids.find({body:<body>, name:<name>}).

Я также хотел бы предложить конечную точку для всех документов данного body. То есть запрос к http://hostname/centroids/<body> ответит на список всех документов body==<body>: db.centroids.find({body:<body>}).

Как это сделать?

Я попытался включить список правил в ключ DOMAIN centroids (имя коллекции базы данных), как показано ниже:

crater = {
...
}

body = {
    'item_title': 'body craters',
    'url': 'centroids/<regex("[\w]+"):body>'
}

DOMAIN = {
    'centroids': [crater, body],
}

но не работал...

AttributeError: 'list' object has no attribute 'setdefault'

person Brandt    schedule 17.07.2019    source источник
comment
Вы пробовали http://hostname/centroids?where={"body": <body>}?   -  person gcw    schedule 17.07.2019
comment
@gcw Да, действительно, это работает из коробки, если я сохраняю настройки по умолчанию, т.е., DOMAIN = {'centroids': {}}. В таком случае я мог бы использовать http://hostname/centroids?where={"body":"mars","name":"cañas"}. Ключевым моментом здесь является то, что я хочу предложить своему пользователю чистый интерфейс, созданный простыми конечными точками пути, не зависящими от базы данных. Например: http://hostname/centroids/mars или http://hostname/centroids/mars/cañas.   -  person Brandt    schedule 18.07.2019


Ответы (1)


Понятно!

Я предполагал, что ключи в структуре DOMAIN напрямую связаны с коллекцией, которую запрашивала Ева. Это верно для настроек по умолчанию, но их можно изменить внутри ресурсов источник данных.

Я понял это, обрабатывая ситуацию, аналогичную вопросу: я хотел, чтобы конечная точка hostname/bodies перечисляла все (уникальные) значения для body в коллекции centroids. Для этого мне нужно было установить для него агрегацию.

Следующие настройки дают мне именно это;)

centroids = {
    'item_title': 'centroid',
    'url': 'centroid/<regex("[\w]+"):body>/<regex("[\w ]+"):name>',
    'datasource': {
        'source': 'centroids',
        'projection': {'name': 1, 'body': 1, 'location.coordinates': 1}
    }
}

bodies = {
    'datasource': {
        'source': 'centroids',
        'aggregation': {
            'pipeline': [
                {"$group": {"_id": "$body"}},
            ]
        },
    }
}

DOMAIN = {
    'centroids': centroids,
    'bodies': bodies
}
  • Конечная точка, например, http://127.0.0.1:5000/centroid/mercury/hokusai дает мне name, body и coordinates из mercury/hokusai.
  • И конечная точка http://127.0.0.1:5000/bodies, список уникальных значений для body в centroids.

Красивый. Большой палец вверх Еве!

person Brandt    schedule 19.07.2019