• web dev JSON Спека-соглашение по HTTP доступу к JSON ресурсам
    tools.ietf.org
    После множества статей про REST у меня сложилось стойкое déjà vu, хотя, наверное, имеет право на жизнь.
    ♡ recommended by @grouzen, @kb, @ComradeDOS
  • If a server implements version control for a resource, and the resource version is incorrectly specified by a client for an operation that modifies the resource, the server SHOULD indicate this with a 412 Precondition Failed status code.

    Хмм. А мы у себя через Accept: и всякие там vnd.projectname.web-2.0+json (или как там оно) делаем версионинг, и в случае неподдержки API возвращаем 415 ошибку "media type not supported", а не 412.
  • @kb, почитал про 412 — это какая-то более общая ошибка, относящаяся ко всем заголовкам впринципе. надо будет её тоже запилить, когда что-то другое будет отваливаться :)
  • @kb, Мы еще не доросли до проблем версионирования, но пока идея такая: документация версионируется ресурсом. Версионирование API подумываю сделать через схему данных, в sdk определяется вся рутина по работе с версиями; если клиент хочет поменять версию, то запускай migration-скрипт на свою базу и повышает/понижает версию протокола. Тут правда момент, что клиентам выдается своя база CouchDB в полное распоряжение.
  • @kb, да, 412 очень полезная ошибка(;
  • @Kxepal, Они же версионирование самого ресурса обсуждают, а не версионирование API. Чо за 412 воще, я считаю, что в случае, описанном в этом драфте, нужно возвращать 409 Conflict.
  • @Laz, 409 это при конфликте состояния ресурса, а все же не для случае "извините, вы ошиблись веткой"
  • @Kxepal, С педивикии про 409:
    Indicates that the request could not be processed because of conflict in the request, such as an edit conflict.
    Версионирование, как я понимаю, нужно как раз для предотвращения конфликтов редактирования.
  • @Laz, а вообще, ты прав:
    w3.org
    Conflicts are most likely to occur in response to a PUT request. For example, if versioning were being used and the entity being PUT included changes to a resource which conflict with those made by an earlier (third-party) request, the server might use the 409 response to indicate that it can't complete the request. In this case, the response entity would likely contain a list of the differences between the two versions in a format defined by the response Content-Type.
  • @Laz, ну, по-моемую это одно и то же, в смысле и то и то делается через хитрый Accept. ты говоришь media-type, в котором хочешь увидеть ресурс, а в него включаешь и версию api, и версию ресурса и что еще там придумаешь.
  • @kb, Ну, версию API действительно имеет смысл включать в параметры медиа типа. А вот версию самого ресурса — не уверен. Ведь от версии к версии меняется только состояние, представление остаётся тем же, а медиа тип (и его параметры) описывает представление.
  • @Laz, собственно версия ресурса и описывает это состояние. если честно, у меня сложилась некая каша, можно я разделю точки зрения?
    есть версионирование веткой: грубо и топорно {version}{collection}/{id}/{action}
    есть версионирование медиа типом: таким образом можно варьировать возвращаемую схему данных в зависимости от указанной версии и определять доступные для указанной версии операции
    есть версионирование ресурса: оно определяет состояние данных ресурса и эта версия в идеале должна хорошо лечь в Etag

    из такой картины я вот понял, что моя попытка версионировать схему данных через сами данные просто глупа и неправильна, благо все только на стадии разработки дизайна(:
  • @Kxepal, Хмм, не знал про Etag, спасибо. Получается, что поле _ver, предложенное в сабжевом драфте, не нужно. А для версионирования API мне более правильным показалось использование параметров медиа типа — application/vnd.example.type; v=1 — то есть вариация второго варианта. Указывать версию в урле, по-моему, как-то не очень красиво.
  • @Laz, в зависимости от контекста. если ты контролируешь конкурентные обновления ресурса, то _rev тебе очень нужна для определения кто победил, а кто опоздал и создает конфликтную ситуацию — собственно так устроена MVCC и так работает CouchDB, при этом так же используется как значение Etag, поскольку однозначно определяет состояние ресурса. А версия в урле да, но, например, для GET-only ветки ресурсов такое решение смотрится достаточно красиво и просто.
  • @Kxepal, Когда клиент обновляет ресурс, в заголовке If-Match он указывает, какую версию ресурса он видел последней. Если кто-то успел изменить ресурс до него, то есть версия ресурса не совпадает с If-Match, сервер должен ответить кодом 412 (это из rfc2616#14.24, таки странно, почему не 409). Честно говоря, мне до версионирования ресурсов ещё далеко, так что я об этом пока не задумывался, возможно, имеет смысл передавать версию и в заголовке, и в представлении. До версионирования мне API ещё дальше, но я уже начитался статей REST-гуру, которые пишут, что версия в урле не комильфо. Хотя, согласен, это упрощает жизнь клиентам.
  • @Laz, Кстати, есть же медиа типы, в которые версию ну никак не запихнёшь, например, image/ или audio/ Тут окромя ETag ничего не остаётся.
  • @Laz, 412 определяет ошибку на уровне разбора метаданных т.к. заголовков, 409 же на уровне обработки тела запроса.
  • @Laz, мне кажется что для api посылать wildcard медиа-тип не самый удачный вариант, хотя в таком случае можно делать fallback на минимальную/максимальную версию или отправлять 412 и просить уточнить запрос
  • @Kxepal, Написав wildcard я имел в виду что-то типа "в любой из этих типов не запихнёшь версию ресурса". В api использовать wildcard, наверное, не стоит. В Accept разве что.