Я думал о пакетном чтении и записи в среде RESTful и, кажется, пришел к выводу, что у меня есть более общие вопросы о кэшировании HTTP. (Ниже я использую запятые (",") для разделения идентификаторов нескольких записей, но эта деталь не относится к обсуждению.)
Я начал с этой проблемы:
1. Один GET
признан недействительным при пакетном обновлении
GET /farms/123 # get info about Old MacDonald's Farm
PUT /farms/123,234,345 # update info on Old MacDonald's Farm and some others
GET /farms/123
Как сервер кэширования между клиентом и сервером Farms узнает, что его кеш /farms/123
становится недействительным, когда он видит PUT
?
Потом я понял, что это тоже проблема:
2. Пакет GET
аннулирован единичным (или пакетным) обновлением
GET /farms/123,234,345 # get info about a few farms
PUT /farms/123 # update Old MacDonald's Farm
GET /farms/123,234,345
Как кеш узнает, что нужно аннулировать множественную ферму GET
, когда он видит, что PUT проходит?
Итак, я решил, что проблема была действительно только с пакетными операциями. Тогда я понял, что любые отношения могут вызвать подобную проблему. Допустим, у фермы ноль или один владелец, а у владельца может быть ноль или одна ферма.
3. Один GET
признан недействительным в результате обновления связанной записи.
GET /farms/123 # get info about Old MacDonald's Farm
PUT /farmers/987 # Old MacDonald sells his farm and buys another one
GET /farms/123
Как кеш узнает, что единственный GET должен быть признан недействительным, когда он видит, что PUT проходит?
Даже если вы измените модели на более RESTful, используя модели отношений, вы получите ту же проблему:
GET /farms/123 # get info about Old MacDonald's Farm
DELETE /farm_ownerships/456 # Old MacDonald sells his farm...
POST /farm_ownerships # and buys another one
GET /farms/123
В обеих версиях #3 первый GET должен возвращать что-то вроде (в JSON):
farm: {
id: 123,
name: "Shady Acres",
size: "60 acres",
farmer_id: 987
}
И второй GET должен вернуть что-то вроде:
farm: {
id: 123,
name: "Shady Acres",
size: "60 acres",
farmer_id: null
}
Но не может! Даже если вы правильно используете ETag
s. Вы не можете ожидать, что кэширующий сервер проверит содержимое на наличие ETag
s — содержимое может быть зашифровано. И вы не можете ожидать, что сервер уведомит кеши о том, что записи должны быть признаны недействительными — кеши не регистрируются на серверах.
Так есть ли заголовки, которые мне не хватает? Вещи, указывающие на то, что кеш должен выполнять HEAD
перед любыми GET
для определенных ресурсов? Я полагаю, что мог бы жить с двойными запросами для каждого ресурса, если бы я мог сообщить кешам, какие ресурсы, вероятно, будут часто обновляться.
А как насчет проблемы, когда один кеш получает PUT
и знает, что его кеш нельзя признать недействительным, а другой его не видит?
pathInfo
, поэтому проблемы не существует. +++Invalidates-Other
было именно то, о чем я изо всех сил пытался сформулировать вопрос, прежде чем нашел ваш отличный вопрос. - person maaartinus   schedule 22.10.2016