Читатели, плохо знакомые с этой темой, будут поражены бесконечным обсуждением того, что вы должны делать, и относительным отсутствием уроков из опыта. Тот факт, что REST является «более предпочтительным», чем SOAP, является, я полагаю, высокоуровневым обучением на основе опыта, но, боже, чего мы добились? Это 2016 год. Диссертация Роя была в 2000 году. Что мы разработали? Это было весело? Было ли легко интегрироваться? Поддерживать? Будет ли он справляться с ростом смартфонов и нестабильной мобильной связи?
По словам ME, реальные сети ненадежны. Запрашивает тайм-аут. Соединения сбрасываются. Сети отключаются на часы или дни за раз. Поезда идут в туннели с мобильными пользователями на борту. Для любого данного запроса (как иногда признается во всем этом обсуждении) запрос может упасть в воду на своем пути, или ответ может упасть в воде на обратном пути. В этих условиях выдача запросов PUT, POST и DELETE непосредственно на основные ресурсы всегда казалась мне немного жестокой и наивной.
HTTP ничего не делает для обеспечения надежного завершения запроса-ответа, и это прекрасно, потому что это правильно работа сетевых приложений. Разрабатывая такое приложение, вы можете перепрыгивать через обручи, чтобы использовать PUT вместо POST, а затем больше обручей, чтобы выдать определенный тип ошибки на сервере, если вы обнаружите повторяющиеся запросы. Вернувшись к клиенту, вам придется перепрыгивать через обручи для интерпретации этих ошибок, повторного выбора, повторной проверки и повторной отправки.
Или вы можете сделать это : рассматривайте ваши небезопасные запросы как эфемерные однопользовательские ресурсы (назовем их действиями). Клиенты запрашивают новое «действие» на основном ресурсе с пустым POST к ресурсу. POST будет использоваться только для этого. Как только надежно завладеет URI только что созданного действия, клиент помещает небезопасный запрос в URI действия, а не в целевой ресурс . Разрешить действие и обновить «реальный» ресурс - это правильно работа вашего API, и здесь он отделен от ненадежной сети.
Сервер выполняет бизнес, возвращает ответ и сохраняет его в соответствии с согласованным URI действия . Если что-то идет не так, клиент повторяет запрос (естественное поведение!), А если сервер его уже видел, он повторяет сохраненный ответ и больше ничего не делает .
Вы быстро заметите сходство с обещаниями: мы создаем и возвращаем заполнитель для результата, прежде чем что-либо делать. Также как и обещание, действие может быть успешным или неудачным один раз, но его результат может быть получен повторно.
Лучше всего то, что мы даем отправляющим и принимающим приложениям возможность связать уникально идентифицированное действие с уникальностью в соответствующих средах. И мы можем начать требовать и обеспечивать !, ответственное поведение клиентов: повторять ваши запросы сколько угодно, но не начинайте генерировать новое действие, пока не получите окончательный результат от уже существующего.
Таким образом, многочисленные острые проблемы уходят. Повторные запросы на вставку не будут создавать дубликаты, и мы не создадим реальный ресурс, пока не получим данные. (столбцы базы данных могут оставаться не обнуляемыми). Повторные запросы на обновление не будут попадать в несовместимые состояния и не будут перезаписывать последующие изменения. Клиенты могут (повторно) извлекать и без проблем обрабатывать исходное подтверждение по любой причине (сбой клиента, отсутствие ответа и т. Д.).
Последовательные запросы на удаление могут видеть и обрабатывать исходное подтверждение, не вызывая ошибку 404. Если все происходит дольше, чем ожидалось, мы можем ответить временно, и у нас есть место, где клиент может проверить окончательный результат. Самая приятная часть этого паттерна - это его свойство кунг-фу (панда). Мы берем слабость, склонность клиентов повторять запрос каждый раз, когда они не понимают ответ, и превращаем его в силу :-)
Прежде чем сказать мне, что это не RESTful, рассмотрите многочисленные способы соблюдения принципов REST. Клиенты не создают URL. API остается доступным для обнаружения, хотя и с небольшим изменением семантики. HTTP-глаголы используются надлежащим образом. Если вы думаете, что это огромное изменение для реализации, я могу вам сказать по опыту, что это не так.
Если вы думаете, что у вас будет огромное количество данных для хранения, давайте поговорим об объемах: типичное подтверждение обновления составляет доли килобайта. HTTP в настоящее время дает вам одну или две минуты, чтобы ответить окончательно. Даже если вы храните действия только в течение недели, клиенты имеют достаточно шансов наверстать упущенное. Если у вас очень большие объемы, вам может потребоваться выделенное хранилище значений ключей, совместимое с кислотой, или решение в памяти.