Статус HTTP 412 (с предварительным условием сбой) и версией базы данных

Я реализую веб-службу RESTful, которая обращается к базе данных. Объекты в базе данных имеют версию для обнаружения нескольких обновлений. Например, если текущее значение {"name":"Bill", "comment":"tinker", "version":3}, если один пользователь PUTs {"name":"Bill", "comment":"tailor", "version":3}, запрос будет успешным (200 OK), а новое значение будет {"name":"Bill", "comment":"tailor", "version":4}. Если второй пользовательский PUTs {"name":"Bill", "comment":"sailor", "version":3"}, запрос будет терпеть неудачу (409 Conflict), потому что номер версии не соответствует.

Существуют существующие интерфейсы, отличные от RESTful, поэтому дизайн баз данных не может быть изменен. Интерфейс RESTful вызывает существующий интерфейс, который обрабатывает детали проверки версии.

Эмпирическое правило в веб-службах RESTful заключается в том, чтобы следить за деталями HTTP, когда это возможно. Было бы лучше в этом случае использовать условный заголовок в запросе и вернуть 412 Precondition Failed, если версия не соответствует? Соответствующий заголовок представляется If-Match. Этот заголовок принимает ETag (тег Entity), который может быть хешем представления текущего состояния ресурса.

Если бы я сделал это, ETags был бы для явки, потому что версия все равно была бы реальной вещью, которую я тестирую.

Есть ли какая-то причина, по которой я должен это делать, кроме как "сделать ее более RESTful", что бы это ни значило?

Ответ 1

Соответствующая вещь - всегда следить за спецификацией HTTP, если вы используете HTTP, и причина заключается в том, чтобы позволить людям, которые правильно понимают спецификацию ,.

412 следует использовать только в том случае, если предварительное условие (например, If-Match) вызвало сбой соответствия версии, тогда как 409 следует использовать, если объект вызовет конфликт (сама спецификация HTTP ссылается на это поведение в определении 409).

Следовательно, клиент, который не отправляет ETags, не ожидает 412. И наоборот, клиент, который отправляет ETags, не поймет, что это ETags, вызывающие 409.

Я бы придерживался в одном направлении. Вы говорите, что "схема базы данных не может быть изменена", но это не останавливает вас (прямо на уровне HTTP-сервера), чтобы извлечь версию из представления datbase и поместить ее в ETag, а затем по пути, возьмите заголовок If-Match и верните его в поле версии.

Но делать это полностью в самом теле сущности не запрещено. Это просто требует, чтобы вы объяснили концепцию и то, как она работает, тогда как с помощью решения ETag вы можете просто указать людей на спецификацию HTTP.

Изменить: И флаг версии не должен быть хешем текущего ресурса; версия вполне приемлема. ETag: "3" - это действительно действующий ETag.