Пакетная обработка через REST-сервис

Существуют ли какие-либо рекомендации по выполнению BATCH-операций через REST для команд POST, PUT, PATCH?

Текущая парадигма, которой я придерживаюсь, заключается в том, что полезная нагрузка JSON указывается в теле для всех трех операций:

a) POST для возврата местоположения созданного ресурса
b) PUT/PATCH возвращает 201, если обновление прошло успешно

Для пакетной операции я намерен принять набор объектов JSON в теле полезной нагрузки, но пытаюсь понять, что вернуть клиенту.

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

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

Но это отклоняется от моей парадигмы, изложенной в пунктах (а) и (б) выше.

Вместо этого имеет ли смысл возвращать клиенту идентификатор, представляющий идентификатор самой пакетной операции?

Затем клиент выполнит последующий запрос GET, чтобы получить результат запрошенной операции.

Такой подход кажется разумным? Если да, имеет ли смысл блокировать клиента при последующем GET, если операция не завершена ИЛИ имеет ли смысл всегда возвращать самое последнее состояние, то есть набор ответов для каждого из элементов, которые клиент запросил для обработки .

Идеи/мысли/предложения?

Поскольку REST — это архитектурный стиль, в котором нет обязательно четких указаний и указаний о том, как должны быть реализованы действия для HTTP-команд, очевидно, что здесь нет правильного или неправильного ответа.

Я ищу решение, которое будет элегантным, естественным и интуитивно понятным.


person Abhijeet Patel    schedule 25.04.2014    source источник
comment
ОТДЫХ — это не рекомендация. Это архитектурный стиль.   -  person Eric Stein    schedule 25.04.2014
comment
Нужны ли для каждого ресурса пакетные операции или только одна?   -  person Eric Stein    schedule 25.04.2014
comment
Можно поподробнее о вашей задаче?   -  person inf3rno    schedule 25.04.2014
comment
@Eric: я согласен с тем, что REST - это архитектурный стиль. Использование слова «рекомендация» в этом контексте в первую очередь связано с тем, что я видел разные реализации того, как реализуются действия для глаголов HTTP. Нет четкого ответа, как следует обрабатывать операцию PATCH, которая, например, принимает массив. Должны ли вы возвращать набор результатов или должны возвращать один результат? ИМХО, было бы странно говорить, что партия не удалась, если некоторые операции завершились успешно. Как бы вы указали, какие элементы были успешно обработаны?   -  person Abhijeet Patel    schedule 25.04.2014
comment
@AbhijeetPatel из RFC 5789, раздел 2, абзац 6: сервер ДОЛЖЕН применять весь набор изменений атомарно [...] Существует также RFC 6902 для форматирования JSON для PATCH, который обрабатывает массивы.   -  person Eric Stein    schedule 25.04.2014


Ответы (2)


Операции REST должны быть атомарными, как видно извне. То есть, если одна часть запроса не выполняется, то все состояние сервера должно вернуться к состоянию до запроса и возвращен ответ 4xx или 5xx (так, например, запрос может быть повторен целиком без вредных последствий, если не получилось с первого раза). Однако это не имеет ничего общего с пакетными операциями как таковыми — таким запросом может быть любой запрос.

Пакетные операции нарушают другое ограничение REST, ограничение универсального интерфейса (определяемое методами HTTP и их работой с ресурсом по указанному URL-адресу).

Если вы хотите выполнять пакетные операции, откажитесь от попыток вызвать ваш API RESTful, потому что вы уже потеряли преимущества, которые дает REST, и просто лжете себе.

Если вы хотите сохранить эти преимущества, откажитесь от пакетных операций.

person Nicholas Shanks    schedule 25.04.2014
comment
Создание идемпотентной пакетной операции легко решается реализацией. Что касается того, чтобы не вызывать API RESTful, потому что есть пакетная операция, это кажется чрезмерно прагматичным. Вам просто нужно по-другому думать о создаваемом ресурсе, в этом случае новый ресурс — это пакетная операция. - person Leon; 25.04.2014
comment
@Leon Если вы «создаете» ресурс в /batch-ops/12 и можете запросить этот ресурс, чтобы получить текущее состояние операции, то да, это RESTful. Если вы просто публикуете в /batch/make-new-users, то нет, это не REST, это RPC. - person Nicholas Shanks; 26.04.2014

REST — это архитектурный стиль.

Я реализую API, чтобы всегда возвращать результат того, что было обновлено. Таким образом, в случае POST он вернет созданный объект, а PATCH и PUT вернет обновленный объект.

В зависимости от размера пакета я бы либо возвращал массив того, что было обработано, либо, альтернативно, массив идентификаторов того, что было обработано.

Если пакетная операция выполняется долго, верните идентификатор для пакета, но сделайте до боли ясно, что конечная точка отличается от других конечных точек.

бывший. если вы создаете пользователя, отправляя сообщение на http://somesite.com/users

отправлять пакетные запросы на http://somesite.com/batch/users

При получении возвращается статус пакетной операции, пока она еще выполняется, при завершении возвращается массив записей, которые были обновлены.

Самое главное — согласованность, что бы вы ни выбрали, всегда придерживайтесь одного и того же подхода при пакетной работе во всей системе.

person Leon    schedule 25.04.2014
comment
ОТДЫХ не является рекомендацией. Это архитектурный стиль. - person Eric Stein; 25.04.2014