<rmcreative>

RSS

Сортировка и фильтрация в REST API

15 августа 2016

Среди информации по построению REST API встречаются две рекомендации на тему сортировки и фильтрации. Сортировку делать вот так:

GET /users?sort=-created_at,username

Сортируем по убыванию по дате создания и по имени пользователя в алфавитном порядке.

Фильтры делать вот так:

GET /tickets?status=open&assignee=123

Получаем открытые тикеты, назначенные на пользователя с ID=123.

Вроде всё красиво, но что если у очередного ресурса появится поле sort? GET-параметр уже зарезервирован для сортировки, использовать его для фильтрации не получается. Выхода два: либо заставить пользователя никогда не использовать поле sort (а к нему со временем добавится like и ещё что-нибудь) либо ввести для фильтрации отдельный параметр filter. Значение лучше всего описать в формате JSON: не придётся заботиться о специальных правилах экранирования, да и поддержка его есть во всех клиентах.

GET /tickets?filter={"status": "open", "assignee": 123}

В случае отдельного параметра, хоть синтаксис и не настолько интуитивен, конфликт имён исключается.

Комментарии RSS

  1. №10628
    zelenin
    zelenin 15 авг. 2016 г., 16:28:44

    Можно написать продолжение статьи, начинающееся со слов "Вроде всё красиво, но что если у очередного ресурса появится поле filter?" Или я не понял решаемую проблему?

  2. №10629
    Sam
    Sam 15 авг. 2016 г., 17:34:44

    zelenin, ну появится. Тогда будет так:

    GET /tickets?filter={"status": "open", "filter": "test"}
    
  3. №10630
    Andrey Bocharov
    Andrey Bocharov 15 авг. 2016 г., 18:37:54

    Sam, как начет варианта - использование cлужебных префиксов? Например, _sort, _filter.

  4. №10632
    Sam
    Sam 15 авг. 2016 г., 21:33:54

    И почему полей с такими именами не может быть?

  5. №10634
    Andrey Bocharov
    Andrey Bocharov 15 авг. 2016 г., 21:58:27

    И почему полей с такими именами не может быть?

    А почему должны? Часто встречаете названия полей с подчеркиванием в качестве префикса?

  6. №10636
    Sam
    Sam 15 авг. 2016 г., 23:52:49

    И не такое бывает :) В issue Yii сообщали об именовании полей юникодом с пробелами, например.

  7. №10641
    Дмитрий
    Дмитрий 16 авг. 2016 г., 12:59:06

    Sam, а есть какие-то рекомендации по структуре ответа в API? Чтобы с результатом запроса (есть там данные или нет) можно было легко работать и в web-app, и в mobile-app.

    Может какие-то советы из личного опыта (а то об этом информации крайне мало).

    Я сейчас использую такой формат (пока только json):

    data: {},
    errors: {},
  8. №10643
    Sam
    Sam 16 авг. 2016 г., 13:59:45

    Есть jsonapi.org/. Большинство рекомендаций вполне соответствует действительности. Не все, но большинство.

  9. №10829
    Егор
    Егор 08 янв. 2017 г., 20:13:18

    Как вариант можно использовать массив: GET /ticket?formName[status]=open&formName[assignee]=123

    Суть та же, но более привычная структура параметров. Да и в GridView уже есть такая реализация. Метод load() у моделей умеет читать такой формат.

  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.