Прежде чем читать мой ответ, я хотел бы сказать, что я согласен с @Neil. Мы должны выбрать наши сражения. Мы обычно хотим сделать все возможное, но иногда для обсуждения недостаточно места, и нам приходится принимать решения против нашей воли.
В любом случае, в ответе Нила я скучаю по еще одной вещи. Документация . Просто чтобы убедиться, что разработчики знают, что запросы POST /search
безопасны.
Это сказал.
1. Дайте шанс ПОЛУЧИТЬ
Рассмотрим GET
вариант в первую очередь. Проверьте максимальную длину URL этого вопроса . Оцените, превышает ли ваша самая длинная строка запроса более 2000 символов. Если это не так, и вы не ожидаете, что будет, пойти с GET
. Это может показаться некрасивым, но, по крайней мере, вы можете добавить в закладки URL-адрес и, конечно, он обладает всеми преимуществами, вытекающими из семантики метода (идемпотентность, безопасность и кэширование)
1.1 Попробуйте кодировать строку запроса
Например, в базе 64. Даже javascript поддерживает кодировки базы 64 .
Вот как это работает:
- Создайте JSON со всеми фильтрами и нормализуйте его.
- Разобрать его в строку
- Кодируй это
- Отправьте закодированный JSON как запрос param (
/search?q=SGVsbG8gV29ybGQh....
).
- На стороне сервера декодируйте параметр q .
- Десериализовать строку JSON
Ранее сделайте максимально длинную строку JSON, закодируйте ее и возьмите длину. Оцените, соответствует ли закодированная строка URL-адресу. Я реализовал следующий фрагмент на Fiddle.js для тестирования. (Я надеюсь, что это все еще работает) 1
Кодирование Base 64 является детерминированным и обратимым, поэтому шансов на столкновение нет.
С помощью закодированных запросов мы также можем сохранять результаты поиска в БД, добавлять закладки в URL, обмениваться ссылками и т. Д. И, конечно, нам не нужно экранировать / удалять строку.
1.2 Попробуйте с псевдонимами
Читая этот блог о том, как создавать REST API, я вспомнил еще одну альтернативу. Псевдонимы для общих запросов .
Я нахожу это интересным по следующим причинам
Сократите длину строки запроса. Это делает API чище и удобнее для пользователя
ПОЛУЧИТЬ / тикеты /? Статус = закрыто и закрытоAt = xxx против
GET / тикеты / недавно закрыто /
Комбинируется с большим количеством псевдонимов или большим количеством параметров запроса.
ПОЛУЧИТЬ / билеты /? Статус = закрыто и закрытоAt = xxx & в течение = 30 минут против
ПОЛУЧИТЬ / билеты / недавно закрытое /? В течение = 30 минут
Мы можем комбинировать псевдонимы с закодированными строками запроса
ПОЛУЧИТЬ / тикеты /? Статус = закрыто & закрытоAt = xxx & в течение = 30 минут против
GET / тикеты / недавно закрыто /? Q = SGVsbG8g ...
1: Я использовал JSON, но мы могли бы использовать другие форматы, как только мы сможем десериализовать его на стороне сервера.
search?q=t
,search?q=te
,search?q=test
и так далее. Попробуйте ограничить частоту отправки запроса, чтобы не повредить вашему серверу. В качестве альтернативы вы также можете вернуть много информации и выполнить фильтрацию на стороне клиента. Это хорошо работает, если пользователь вводит широкие категории, которые могут сильно сузить круг.