Доступ к версиям/ревизии объекта в RESTful API

При разработке RESTful API мы столкнулись с проблемой доступа к различным версиям "одного и того же объекта". Скажем, объект страницы идентифицируется уникальным ключом и доступен по GET/api/page/pagekey. Его можно обновить, отправив PUT/api/page/pagekey и соответствующий документ в теле.

Теперь наша система отслеживает старые версии страницы, которые мы также хотим получить через API. Предположим, что более старая версия документа - это версия 1. Кажется, существует как минимум два способа разработки API для доступа к этой конкретной версии страницы:

  • GET/api/page/pagekey/1
  • GET/api/page/pagekey? version = 1

Первый вариант отображает конкретную версию как свой собственный ресурс; второй вариант предоставляет существующему ресурсу дополнительный контекст версии.

  • Является ли вариант (1) или (2) лучшим решением? Или есть еще лучший способ сделать это?
  • В варианте (1) запрос на номер версии, который не существует, например. /api/page/pagekey/ 7 может вызывать HTTP 404 Not Found, что очень удобно. Будет ли это также действительным ответом на состояние при рассмотрении варианта (2), где мы изменим только контекстную "версию" существующего ресурса, которая без параметра версии вернет ответ HTTP 200 Ok?

Ответ 1

Каждый URL-адрес ресурса должен быть постоянной ссылкой для идентификации этого ресурса.

GET /api/page/{id}/{rev}

Это, безусловно, постоянная ссылка на конкретную версию ресурса. Итак, это прекрасно. Но обратите внимание, что постоянная ссылка не требует, чтобы содержимое было одинаковым с течением времени:

GET /api/page/{id}

Это вернет последнюю ревизию, которая будет прекрасна и со временем изменит содержимое. Чтобы расширить это, вы можете даже иметь временные ресурсы, подобные этому, и быть RESTful:

GET /api/page/latest 

Но, /api/page/{id}?version={rev} также будет работать и не нарушит никаких концепций RESTful.

Я думаю, что /{id}/{rev} немного чище, поскольку он конкретно идентифицирует этот ресурс в адресе URL и чувствует себя немного более корректным, чем создание его параметра. Причина в том, что params должны быть модификаторами того, как извлекать содержимое и не обязательно мутировать отдельный ресурс, который вы извлекаете. В вашем случае, поскольку каждая версия различна, представляется более уместным четкое обращение к ресурсу. Но даже это не нарушает никаких правил или концепций RESTful url, и если вы попросите 10 человек, вы можете получить другой ответ:)

В любом случае, вы, вероятно, должны гарантировать, что временный ресурс /api/page/{id} возвращает последнюю версию.

Ответ 2

Почти по определению у REST не будет понятия "тот же объект". Если вам это нужно в вашем протоколе, вам нужно будет иметь какой-то "идентификатор". Так просто:)

Параметр URL - один из очевидных способов. "/1" или "? Version = 1", безусловно, являются двумя хорошими альтернативами, которые вы выбираете, это просто вопрос предпочтения (а также вопрос о том, сколько "других вещей" вы также можете захотеть).

В любом случае вам все равно придется справляться с ошибками "версия не найден" и изящно восстанавливаться.

ИМХО...