Мнения, необходимые для атомарности RESTful PUT - PullRequest
7 голосов
/ 22 сентября 2009

Мои коллеги и я внедряем ряд HTTP-сервисов RESTful, и мы пытаемся убедиться, что мы а) следуем спецификации и б) делаем "правильные" вещи, когда в спецификации не хватает деталей.

Вот особая ситуация, к которой мы пришли и ищем мнения сообщества:

Предположим, у вас есть ресурс / Люди / Боб, и ваш клиент собирается обновить его с помощью PUT. Сервер может создавать представления для / People / Bob в приложении / json и text / html. Сервер может интерпретировать представления для / People / Bob в приложении / json.

Учитывая этот запрос:

PUT /People/Bob
Content-Type: application/json
Accept: application/xml

{ name: "Still Bob" }

Сервер не может создать представление XML, но он может обрабатывать входящий JSON. Итак, мы знаем, что правильный ответ - вернуть серверу статус 406.

Вопрос в том, должен ли сервер выполнить обновление для / People / Bob?

Ответы [ 5 ]

2 голосов
/ 22 сентября 2009

Вопрос заключается в следующем: должен ли сервер выполнить обновление для / People / Bob?

С спецификации HTTP , 406 означает:

Ресурс, идентифицированный запросом, способен генерировать только объекты ответа, которые имеют неприемлемые характеристики содержимого в соответствии с заголовками принятия, отправленными в запросе.

Если это не запрос HEAD, ответ ДОЛЖЕН включать в себя объект, содержащий список доступных характеристик объекта и местоположений, из которых пользователь или пользовательский агент может выбрать наиболее подходящий. Формат объекта определяется типом мультимедиа, указанным в поле заголовка Content-Type. В зависимости от формата и возможностей пользовательского агента, выбор наиболее подходящего варианта МОЖЕТ выполняться автоматически. Однако эта спецификация не определяет какого-либо стандарта для такого автоматического выбора.

   Note: HTTP/1.1 servers are allowed to return responses which are
  not acceptable according to the accept headers sent in the
  request. In some cases, this may even be preferable to sending a
  406 response. User agents are encouraged to inspect the headers of
  an incoming response to determine if it is acceptable.

Если ответ может быть неприемлемым, пользовательский агент ДОЛЖЕН временно прекратить получение дополнительных данных и запросить у пользователя решение о дальнейших действиях.

Это примечание по поводу HTTP / 1.1 может быть вашим ответом. Я читаю это как "вы можете вернуть 200 в ответ на запрос PUT / People / Bob, когда пользовательский агент указывает application / xml в заголовке Accept, выбирая любой подходящий тип контента, и что этот результат может быть предпочтительнее возвращение 406. "

При этом сценарии PUT будет успешным на сервере, вернет 200, но клиент получит представление application / json. Клиент должен иметь возможность обрабатывать эту возможность, убедившись, что он понимает тип мультимедиа, указанный в заголовке Content-type, и ведет себя четко определенным образом, если это не так.

Но это всегда так.

Еще одна вещь: вы можете подумать о том, чтобы не использовать обычные типы мультимедиа, такие как application / xml и application / json, а вместо этого определять свои собственные типы мультимедиа, возможно, на основе XHTML или JSON. Все соединение клиент-сервер в RESTful-приложении происходит через типы носителей. Без типов мультимедиа, достаточно богатых для представления концепций вашего домена, вы не полностью указали свой REST API.

2 голосов
/ 22 сентября 2009

+ 1 для философии ОТДЫХА.

Без детального знания спецификации HTTP я бы просто выбрал один из вариантов и задокументировал вопрос и выбор.

Я бы предпочел, чтобы сервер не отвечал как запрошенный, тогда он вообще не должен обрабатывать любой запрос.

Но это может не сработать в некоторых сценариях, поэтому вам, возможно, придется сделать обратное.

1 голос
/ 22 сентября 2009

Единственный выход из вашей загадки - иметь успешный PUT возврат 204 (без контента). Таким образом, заголовок Accept клиента не имеет отношения к вопросу о том, выполняется ли обновление.

Клиент «RESTful» (или, по крайней мере, «HTTP-охват») будет знать, что не нужно обновлять свою текущую «страницу», и что ему нужно будет сделать GET, чтобы обновить свое представление о справедливой PUT ресурс. Заголовок Accept для этого GET теперь, конечно, является отдельной проблемой от атомарности обновления.

1 голос
/ 22 сентября 2009

Я бы сказал «да» в теории, но «нет» для реального применения.

Я вижу логику не обрабатывать, если есть ошибка. Поскольку вы возвращаете 406, а не 500, я знаю, что это не ошибка в предоставленных мною данных, а скорее способ представления результата.

Тем не менее, некоторые приложения не будут проверять коды ошибок; они просто увидят, что он вернулся с ошибкой, а не с запрашиваемым XML, и предположят, что транзакция не удалась.

Я предполагаю, что вы не обрабатываете application / xml не является реальной проблемой, но для целей вопроса - если это на самом деле разворачивается как реальная служба, вы почти наверняка захотите иметь возможность Представление XML, поскольку это (я подозреваю) наиболее распространенное взаимодействие RESTful, и многие вызывающие абоненты, вероятно, будут жестко запрограммированы для использования XML.

Подводя итог: если вы на самом деле не предоставляете application / xml, то я бы сказал, что не выполняйте обновление. Если вы работаете со всеми стандартами, но вы планируете непредвиденные обстоятельства, когда пользователь запросит application / fooSomethingNonStandard, тогда продолжите и выполните обновление, но не забудьте ответить 406.

0 голосов
/ 23 сентября 2009

Я бы либо преуспел и возвратил бы 200, используя метод, предложенный Ричем выше, или 406 и потерпел бы неудачу. Протокол не допускает более детального подхода, смешивающего 2xx (Успех) с кодами 4xx (Ошибка), поэтому можно прочитать 4xx, что означает НЕ Успех.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...