Плохо ли создавать заголовки http ETag с использованием первичных ключей базы данных? - PullRequest
1 голос
/ 14 февраля 2020

Могу ли я использовать ключ базы данных (из неизменяемого объекта) в качестве ETag?

Я пытаюсь заставить браузер и / или прокси-сервер работать для моего веб-приложения (например, python / * 1030) *, но я не думаю, что это особенно актуально). Во всем, что я читал об ETag, они обычно обсуждаются как ха sh (предположительно stati c) ресурса.

В моем случае в моей базе данных есть класс объектов, которые нельзя редактировать. Для каждого из этих объектов может быть создано несколько разных представлений. Генерация представлений, по крайней мере, некоторых из них, требует некоторой работы на сервере, но в целом получаемый результат является легковесным. Таким образом, выполнение работы по генерации всей страницы, а затем взятию га sh, было бы неэффективным, и я также могу просто отправить ответ в этот момент.

Я думаю, что поскольку каждое представление построено на неизменяемом объекте базы данных, ключа этого объекта (плюс URL-адрес запроса) достаточно, чтобы узнать, хорош ли кэш клиента или нет. Но это будет означать использование одного и того же ETag для множества разных ресурсов. Насколько я могу судить, похоже, что это должно сработать, но

  • Против официальной спецификации c о том, как предполагается использовать ETag? Например, всегда ли должен быть уникальный ETag для разных ресурсов?
  • Будет ли это плохой идеей по какой-то другой причине?

Немного больше контекста

У моего приложения есть URL-адреса вида:

example.com/view/<name>/<version>/<view>/<additional view args>

БД имеет уникальный индекс для комбинация <name> и <version>. Но есть специальное ключевое слово latest для версии, которое заставляет сервер найти самую последнюю запись с <name>. Независимо от того, какое представление запрашивается, оно полностью определяется объектом, найденным по имени и версии. Поэтому, если клиент отправляет заголовок запроса с If-none-match: <key>, я всегда возвращаю 304 независимо от запрошенного представления, если (а) они не запросили версию latest и (б) первичный ключ последней версии в БД не соответствует заголовку If-none-match.

1 Ответ

1 голос
/ 15 февраля 2020

Я предлагаю прочитать RF C 7232 , что довольно просто и даст вам отличное понимание условной проверки.

Ваше желание избежать вычисления ответа, прежде чем узнавать, есть ли совпадение разумно и допустимо. Как ясно из стандарта, вам нужно выбрать непрозрачное значение. Хэши - это только один из особых случаев. (На самом деле они требуют особого упоминания, поскольку теоретически возможны коллизии.) Стандарт специально дает пример использования номера версии для ETag:

Например, ресурс, который имеет спецификацию реализации c управления версиями, применяемую ко всем изменениям, для точного различения представлений может использоваться внутренний номер редакции, возможно, в сочетании с идентификатором отклонения для согласования содержимого.

Вы также спрашиваете, есть ли ETag должен быть разным для каждого ресурса. ответ - это не:

Не существует никакой уникальности для представлений разных ресурсов (т. Е. Один и тот же строгий валидатор может использоваться для представлений нескольких ресурсов в одном и том же). время и не подразумевает, что эти представления эквивалентны).

Некоторые будут обеспокоены раскрытием идентификаторов базы данных для клиента. У меня нет сильного чувства по этому поводу, но, конечно, этого легко избежать, хешируя или иным образом скрывая идентификатор.

Глядя на ваш конкретный дизайн c, кажется, что просто с помощью version для вашего ETag будет достаточно. Фактически, для всех ресурсов, кроме latest, представляется, что существует только одно возможное представление. Если это так, вы должны установить кэширование этих записей навсегда, и на самом деле не имеет значения, что такое ETag. Затем для latest используйте короткое время кэширования и используйте version (или первичный ключ, если хотите) для ETag.

...