Я создаю общий API с контентом и схему, которая может быть определена пользователем. Я хочу добавить логику фильтрации к ответам API, чтобы пользователи могли запрашивать конкретные объекты, которые они хранили в API. Например, если пользователь хранит объекты событий, они могут делать такие вещи, как фильтр:
- Массив содержит:
properties.categories
содержитEngineering
- Большая, чем:
properties.created_at
старше2016-10-02
- Не равно:
properties.address.city
неWashington
- Равно:
properties.name
Meetup
- и др.
Я пытаюсь создать фильтрацию в строке запроса ответов API и придумать несколько вариантов, но я не уверен, какой синтаксис для нее лучше...
1. Оператор как вложенный ключ
/events?properties.name=Harry&properties.address.city.neq=Washington
В этом примере используется только вложенный объект для конкретных операторов (например, neq
, как показано). Это приятно, потому что это очень просто и легко читается.
Но в тех случаях, когда свойства события могут быть определены пользователем, он сталкивается с проблемой, когда существует потенциальное столкновение между свойством с именем address.city.neq
с использованием оператора нормального равенства, а свойство с именем address.city
используя не равный оператор.
Пример: Stripe API
2. Оператор в качестве ключевого суффикса
/events?properties.name=Harry&properties.address.city+neq=Washington
Этот пример похож на первый, за исключением того, что вместо .
используется разделитель +
(который эквивалентен пробелу), а не .
, так что нет путаницы, поскольку ключи в моем домене могут " t содержит пробелы.
Одним из недостатков является то, что это немного сложнее читать, хотя это спорно, поскольку оно может быть истолковано как более ясно. Другой может быть, что немного сложнее разобрать, но не так много.
3. Оператор как префикс значения
/events?properties.name=Harry&properties.address.city=neq:Washington
Этот пример очень похож на предыдущий, за исключением того, что он перемещает синтаксис оператора в значение параметра вместо ключа. Это позволяет устранить небольшую сложность при анализе строки запроса.
Но это происходит за счет того, что больше не существует возможности дифференцировать между равным оператором, проверяющим литеральную строку neq:Washington
, и не равным оператором, проверяющим строку Washington
.
Пример: API Sparkpay
4. Пользовательский параметр фильтра
/events?filter=properties.name==Harry;properties.address.city!=Washington
В этом примере используется один параметр запроса верхнего уровня, filter
, чтобы пространство имен помещало всю логику фильтрации в. Это приятно в том, что вам никогда не придется беспокоиться о столкновении пространства имен верхнего уровня. (Хотя в моем случае все обычаи вложены под properties.
, поэтому это не проблема в первую очередь.)
Но это происходит из-за того, что требуется сложная строка запроса, когда вы хотите сделать базовую фильтрацию равенства, что, вероятно, приведет к необходимости часто проверять документацию. И использование символов для операторов может привести к путанице для неочевидных операций, таких как "рядом" или "внутри" или "содержит".
Пример: API Google Analytics
5. Пользовательский параметр подробного фильтра
/events?filter=properties.name eq Harry; properties.address.city neq Washington
В этом примере используется аналогичный параметр верхнего уровня filter
как предыдущий, но в нем указаны слова со словами вместо определения их символами и пробелы между ними. Это может быть немного читаемо.
Но это происходит за счет наличия более длинного URL-адреса и множества пробелов, которые необходимо закодировать?
Пример: API OData
6. Параметры фильтра объектов
/events?filter[1][key]=properties.name&filter[1][eq]=Harry&filter[2][key]=properties.address.city&filter[2][neq]=Washington
В этом примере также используется параметр верхнего уровня filter
, но вместо создания полностью настраиваемого синтаксиса для него, который имитирует программирование, вместо этого создается определение объектов для фильтров с использованием более стандартного синтаксиса строки запроса. Это может принести немного больше "стандартных".
Но это происходит из-за того, что он очень многословен для ввода текста и его трудно разобрать.
Пример Magento API
Учитывая все эти примеры или другой подход, какой синтаксис лучше всего? В идеале было бы легко построить параметр запроса, так что играть в строке URL можно, но также не создавать проблем для будущей совместимости.
Я склоняюсь к # 2, поскольку он кажется разборчивым, но также не имеет некоторых недостатков других схем.