REST API дизайн для веб-страниц с мастерами

11

У меня есть веб-страница в формате мастера. Кнопка отправки в API будет на 4-м шаге мастера. Однако я хочу, чтобы введенные данные были сохранены в базе данных перед переходом к следующему шагу в мастере. Я также хочу, чтобы REST API работал для страниц, имеющих одну вкладку.

Поэтому я разработал API для параметра запроса action = draft или submit. Если действие является черновым, обязательны только определенные поля. Если действие отправлено, все поля являются обязательными. Проверки в сервисном уровне REST API будут выполняться на основе параметра запроса. Похоже, я должен явно указать условия if / else в документации. Это приемлемая форма дизайна RESTful? Какой будет лучший дизайн с этими требованиями?

TechCrunch
источник
3
Почему промежуточные данные должны храниться в БД?
Dan1701
2
@ Dan1701: чтобы вы могли возобновить работу мастера с другого компьютера. При заполнении длинных сложных форм заполнение всех необходимых данных может занять несколько дней, поскольку у пользователя может не быть готовых всех необходимых данных, или пользователю может потребоваться собрать дополнительные файлы для загрузки из разных мест. Если вы можете возобновить работу с другого устройства, вы можете загрузить мастер для загрузки фотографии с мобильного телефона и продолжить вводить подробное описание / аргумент с использованием реальных клавиш на рабочем столе и т. Д.
Lie Ryan
В этом случае, я думаю, ответ @ guillaume31 имеет смысл.
Dan1701,

Ответы:

7

Поскольку вы хотите сохранить вещи на сервере между шагами мастера, кажется вполне приемлемым рассматривать каждый шаг как отдельный ресурс. Что-то в этом роде:

POST /wizard/123/step1
POST /wizard/123/step2
POST /wizard/123/step3

Включив гиперссылки в ответ, вы можете проинформировать клиента о том, что он может сделать после этого шага - перейти вперёд или назад для промежуточных шагов, и ничего для последнего шага. Вы можете увидеть пример этого на рисунке 5 здесь .

guillaume31
источник
Я использую Angular для пользовательского интерфейса. Поэтому я не уверен, насколько полезен конечный автомат. Но я думаю, что пошаговый ресурс кажется более значимым, чем управление другой таблицей. Кроме того, я должен быть в состоянии представить все за один шаг. Познакомится с этим дизайном сегодня. Спасибо за помощь.
TechCrunch
Пожалуйста. Кстати, подход с двумя столами не является взаимоисключающим. Наличие одного HTTP-ресурса на шаг не диктует вашу объектную модель на сервере приложений, не говоря уже о схеме базы данных. Это просто веб-представление.
guillaume31
1
@TechCrunch В основном Гийом означает, что объект / таблица, представляющая форму, может быть разбита на части, где часть модели сохраняется на каждом шаге. Фактически, вы можете просто сделать каждый «шаг» формой для части всей модели . И если вы воспользуетесь этим подходом, это сделает архитектуру невероятно простой. Каждый POST для сервера будет (создавать или) обновлять одну и ту же модель, и каждый GET будет загружать одну и ту же модель, и каждый шаг будет формой для заполнения наборов полей, которые имеют смысловой смысл (принадлежат друг другу). И просто иметь логическое значение для модели in_progressили draft.
Крис Cirefice
3

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

У нас есть две таблицы: Item и UnfinishedItem. Когда пользователь заполняет данные с помощью мастера, данные сохраняются в таблице UnfinishedItem. На каждом шаге мастера сервер проверяет данные, введенные на этом шаге. Когда пользователь завершает работу с мастером, мастер отображает скрытую / доступную только для чтения форму на странице подтверждения, которая показывает все данные, подлежащие отправке. Пользователь может просмотреть эту страницу и вернуться к соответствующему шагу, чтобы исправить ошибки. Когда пользователь удовлетворен своими записями, он нажимает кнопку «Отправить», и мастер затем отправляет все данные в скрытых / доступных только для чтения полях формы на сервер API. Когда сервер API обрабатывает этот запрос, он повторно запускает все проверки, которые он выполнял на каждом шаге мастера, и выполняет дополнительные проверки, которые не вписываются в отдельные этапы (например, глобальные проверки, дорогостоящие проверки).

Преимущества двухстолового подхода:

  • в базе данных вы можете иметь более жесткие ограничения для таблицы Item, чем для таблицы UnfinishedItem; вам не нужно иметь дополнительные столбцы, которые действительно потребуются после завершения работы мастера.

  • Агрегировать запросы по готовым Элементам для отчетности проще, так как вам не нужно помнить, чтобы исключить UnfinishedItems. В нашем случае нам никогда не требовалось выполнять агрегированные запросы между Item и UnfinishedItems, так что это не проблема.

Недостаток:

  • Это склонно к дублированию логики проверки. Веб-инфраструктура, которую мы использовали, Django, делает это немного более терпимым, так как мы использовали наследование модели с небольшим количеством мета-магии, чтобы изменить ограничения, которые должны быть разными в Item и UnfinishedItem. Django генерирует большую часть базы данных и формы проверки из модели, и нам нужно только взломать несколько дополнительных проверок поверх этого.

Другие возможности, которые я рассмотрел, и почему мы не пошли с ними:

  • сохранение данных в файлах cookie или локальном хранилище: пользователь не может продолжить отправку с другого устройства или удалить историю браузера.
  • сохранить UnfinishedItem как неструктурированные данные (например, JSON) в базе данных или вторичном хранилище данных: мне придется определить логику синтаксического анализа и не могу использовать автоматическую проверку модели / формы Django.
  • сделайте проверку за шаг на стороне клиента: мне придется продублировать логику проверки между Python / Django и JavaScript.
Ли Райан
источник
1
+1 за указание проверок на моделях типа «черновик» и «готовых» моделях; Я не думал об этом, и это важный момент, который следует принимать во внимание. В противном случае у вас, вероятно, будет куча ifутверждений, проверяющих состояние черновика во всех ваших проверках, что было бы просто нехорошо. Хотя некоторые очень сложные фреймворки, такие как Ruby on Rails, могут значительно упростить эту проблему, если реализованы правильно.
Крис Cirefice
1

Я реализовал это способом, подобным сочетанию решений @ guillauma31 и @Lie Ryan.

Вот ключевые понятия:

  1. Существует 3 шага мастера, который может быть частично сохранен до завершения.
  2. Каждый шаг имеет свой собственный ресурс (например /users/:id_user/profile/step_1,. .../step_2, И т. Д.)
  3. На каждом шаге данные и статус завершения могут быть получены с помощью запросов GET и сохранены с помощью запросов PATCH.
  4. Каждый ресурс имеет свои правила проверки введенных данных.
  5. Каждый шаг возвращает ключ, который необходимо использовать при вводе следующего шага, чтобы гарантировать последовательность. После использования или создания нового токен теряет силу.
  6. На последнем шаге у нас есть все необходимые данные в базе данных и отображается экран подтверждения. Это подтверждение вызывает другой ресурс, чтобы пометить данные как завершенные (например:) .../profile/confirm. Этот ресурс не должен получать все данные снова. Он только помечает данные как правильные и полные.
  7. Существует запланированная процедура, которая стирает эти неполные записи, которые имеют более нескольких дней.

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

API не имеет состояния и атомарен.

Чтобы «мастер одного шага» работал с этой настройкой, вам нужно изменить некоторые вещи, такие как удаление потока токенов или создание ресурса для возврата токенов в зависимости от типа мастера, или даже создание нового ресурса только для заполнения этого конкретного шаг мастера (вроде PUT /users/:id_user/profile/).

Рикардо Соуза
источник