Я думал о пакетном чтении и записи в среде 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
с - содержимое может быть зашифровано. И вы не можете ожидать, что сервер уведомит кэши о том, что записи должны быть признаны недействительными - кэши не регистрируются на серверах.
Так есть ли заголовки, которые мне не хватает? Вещи, которые указывают, что кэш должен делать HEAD
перед любыми GET
с для определенных ресурсов? Я полагаю, что я мог бы справиться с двойными запросами для каждого ресурса, если бы я мог сообщать кешам, какие ресурсы, вероятно, будут часто обновляться.
А как насчет проблемы, когда один кеш получает PUT
и знает, что его кэш недействителен, а другой не видит его?