Фильтрация
Коллекции — это списки ресурсов. На развязанном (decoupled) сайте они используются для создания таких вещей, как список «Нового контента» или раздел «Мой контент» на стороне клиента.
Однако если вы отправите запрос без фильтров к конечной точке коллекции, например /jsonapi/node/article
, вы просто получите все доступные вам статьи.
Без фильтров нельзя получить только свои статьи или только статьи о ламах.
Это руководство научит вас создавать фильтры, как профессионал.
Быстрый старт
Самый простой и распространённый фильтр — это фильтр ключ-значение:
?filter[field_name]=value&filter[field_other]=value
Он возвращает все ресурсы, где "field_name" равно "value" и "field_other" равно "value".
Для всего остального — читайте дальше!
Краткое содержание
Модуль JSON:API обладает одной из самых мощных и функциональных систем фильтрации. Однако вся эта мощь требует небольшой кривой обучения.
В конце этой статьи вы сможете создавать сложные запросы и решать возникающие задачи, например: «Как получить список статей автора о ламах или самой быстрой птице в мире — сапсане?»
Мы начнём с основ, затем рассмотрим сокращения, которые делают написание фильтров быстрее и лаконичнее. И в конце приведём примеры фильтров из реального мира.
Если вы не новичок в Drupal, вероятно, вы уже использовали модуль Views для подобных задач. В отличие от REST-модуля из ядра Drupal, JSON:API не экспортирует результаты Views. Коллекции — это API-ориентированная альтернатива JSON:API для экспортируемых REST-дисплеев в Views.
Построение фильтров
Основные строительные блоки фильтрации JSON:API — это условия и группы. Условия утверждают, что что-то является истинным, а группы позволяют объединять эти утверждения в логические множества. Эти множества можно вкладывать друг в друга, создавая дерево условий:
Обычное представление:
a( b() && c( d() || e() ) )
Дерево:
a
/ \
b c
/ \
d e
Итак, что входит в условие?
Условие говорит TRUE или FALSE для ресурса, основываясь на утверждении, например: «Создана ли сущность данным пользователем?». Если условие ложно, ресурс не будет включён в результат.
Условие состоит из трёх основных частей: путь, оператор и значение.
- Путь — поле ресурса
- Оператор — метод сравнения
- Значение — то, с чем сравниваем
В виде псевдокода условие выглядит так:
($field !== 'space')
$field
— путь к полю!==
— оператор'space'
— значение
В JSON:API условие оформляется как ключ-значение в строке URL:
?filter[a-label][condition][path]=field_first_name
&filter[a-label][condition][operator]=%3D
&filter[a-label][condition][value]=Janis
У каждого условия/группы должно быть имя (label).
Группы условий
Чтобы объединить условия, используются группы. Каждая группа имеет соединение: AND или OR.
?filter[rock-group][group][conjunction]=OR
&filter[janis-filter][condition][path]=field_first_name
&filter[janis-filter][condition][value]=Janis
&filter[janis-filter][condition][memberOf]=rock-group
&filter[joan-filter][condition][path]=field_first_name
&filter[joan-filter][condition][value]=Joan
&filter[joan-filter][condition][memberOf]=rock-group
&filter[last-name-filter][condition][path]=field_last_name
&filter[last-name-filter][condition][operator]=STARTS_WITH
&filter[last-name-filter][condition][value]=J
Пути (Paths)
Пути позволяют фильтровать по значениям связанных сущностей.
Пример фильтрации по названию карьеры пользователя:
?filter[career][condition][path]=field_career.name
&filter[career][condition][value]=Rockstar
Для фильтрации по вложенным сущностям можно использовать точечную нотацию:
some_relationship.1.some_attribute
Фильтрация по подсвойствам поля также возможна:
field_phone.country_code
Сокращения
Для простых фильтров достаточно:
?filter[field_first_name]=Janis
Фильтры и контроль доступа
Фильтры — не контроль доступа! Даже если вы фильтруете данные, это не защищает их от несанкционированного доступа. Всё равно проверяйте права на сервере.
Чтобы уменьшить ненужные запросы, фильтруйте то, к чему пользователь не имеет доступа, заранее:
?filter[status][value]=1
Примеры фильтров
1. Только опубликованные узлы
filter[status][value]=1
2. Узлы по значению ссылки на сущность
filter[uid.id][value]=UUID
3. Вложенные фильтры (созданные пользователем admin)
filter[uid.name][value]=admin
4. Массив значений (созданные admin и john)
filter[uid.name][operator]=IN
filter[uid.name][value][1]=admin
filter[uid.name][value][2]=john
5. Группировка условий (опубликовано и создано admin)
filter[and-group][group][conjunction]=AND
filter[name][condition][path]=uid.name
filter[name][condition][value]=admin
filter[name][condition][memberOf]=and-group
filter[status][condition][path]=status
filter[status][condition][value]=1
filter[status][condition][memberOf]=and-group
6. Вложенные группы (продвинуто или закреплено и создано admin)
filter[and-group][group][conjunction]=AND
filter[or-group][group][conjunction]=OR
filter[or-group][group][memberOf]=and-group
filter[admin][condition][path]=uid.name
filter[admin][condition][value]=admin
filter[admin][condition][memberOf]=and-group
filter[sticky][condition][path]=sticky
filter[sticky][condition][value]=1
filter[sticky][condition][memberOf]=or-group
filter[promote][condition][path]=promote
filter[promote][condition][value]=1
filter[promote][condition][memberOf]=or-group
7. Заголовок содержит "Foo"
filter[title][operator]=CONTAINS
filter[title][value]=Foo
8. Комплексные поля (например, адрес)
filter[field_address][condition][path]=field_address.locality
filter[field_address][condition][value]=Mordor
9. Термины таксономии (теги)
filter[taxonomy_term--tags][condition][path]=field_tags.name
filter[taxonomy_term--tags][condition][operator]=IN
filter[taxonomy_term--tags][condition][value][]=tagname
10. Дата
filter[field_test_date][condition][value]=2019-06-27
11. Пустой массив
filter[my-field][condition][path]=my_field
filter[my-field][condition][operator]=IS NULL
Статья с сайта Drupal Documentation.