Веб-сервис RESTful и транзакции с базой данных

#php #rest

#php #rest

Вопрос:

В последнее время я испытываю трудности с архитектурой Rest: p и обычно у меня возникает много проблем с этим. Допустим, у меня есть ресурс с именем «user», и у этого пользователя может быть список автомобилей. Я пытаюсь сразу вставить этого пользователя и его список автомобилей в базу данных. Я знаю, что должен сделать это с помощью HTTP-глагола POST. Но как бы мне этого добиться? Должен ли я отправлять только один URL-адрес с идентификацией пользователя и списком автомобилей, каким-либо образом закодированным, или я должен использовать ресурс «user» для вставки пользователя, а затем для каждого автомобиля вызывать URL-адрес ПУБЛИКАЦИИ в ресурсе с именем «car»?

Второй подход имеет проблему. Этот процесс должен быть реализован с помощью транзакции базы данных. Если что-то пойдет не так при вставке car, я хочу, чтобы пользователь не был зарегистрирован в базе данных.

Я знаю, что архитектуры RESTful должны быть без состояния, так как я могу реализовать такую транзакцию, используя функциональные возможности базы данных? Я знаю, что могу сам реализовать какую-то транзакцию, но я хотел, чтобы это было более автоматизировано.

Заранее спасибо.

Ответ №1:

Есть несколько способов, которыми вы можете это сделать, в зависимости от языков, которые вы используете во фронтальной и серверной части, и от того, как вы планируете отправлять эти данные. Я бы решил проблему следующим образом, предполагая, что вы используете PHP и MySQL:

  1. Подготовьте данные, поэтому что-то вроде user=123amp;cars[]=1amp;cars[]=2amp;cars[]=3 (я использую var cars[] , поскольку это отправит массив в PHP, и вы можете добиться этого, назвав свои поля ввода как cars[] )
  2. Опубликуйте это в своем бэкэнде
  3. Затем ваш серверный сервер обработает пользователя и добавит их в базу данных, если их там нет.
  4. Тогда у меня была бы таблица, иллюстрирующая взаимосвязь между пользователем и машинами, что-то вроде:

    СОЗДАЙТЕ ТАБЛИЦУ box_to_category (user_id int(11) НЕ РАВЕН НУЛЮ, car_id int (11) НЕ РАВЕН НУЛЮ);

  5. В этой таблице я бы очистил все машины, связанные с этим пользователем, а затем добавил новые машины, размещенные в серверной части ( user_id будут связаны с a user в users таблице, а car_id будут связаны с a car в cars таблице)

Это простая настройка.

Комментарии:

1. При таком подходе я знаю, как это сделать:p. Конечно, это правильный ответ. Я хотел узнать другой подход, при котором вы отправляли бы каждый car по URL-адресу, поэтому вам пришлось бы реализовать какую-то систему транзакций базы данных. Но, поскольку вы продемонстрировали этот подход, позвольте мне спросить вас кое о чем.. При таком подходе давайте представим, что нашим пользователем был какой-нибудь арабский шейх, и у него много машин. Если бы это было так, вы могли бы в конечном итоге создать URL-адрес, слишком большой для отправки, верно? Поскольку это метод POST, решением было бы увеличить МАКСИМАЛЬНЫЙ РАЗМЕР POST на сервере? А если бы это был запрос GET?

2. И при таком подходе невозможно отправить объект в закодированном виде? Допустим, я хотел отправить автомобили и отправить их идентификатор и имя. Как бы вы поступили? Массив типа carId[]=1amp; carId[]=2amp;carName[]amp;carName[] и сопоставить два массива по их индексу? Или есть способ отправить объект каким-либо образом в закодированном виде?

3. Да, вам пришлось бы увеличить максимальный размер публикации, и я бы не рекомендовал делать это через GET. Однако максимальный размер записи для PHP по умолчанию составляет 8 МБ, что является большим объемом текста. Что касается выполнения этого как закодированного объекта, да, это тоже хорошо, все, что работает для вас. ИМО, я бы сказал, что лучше сделать это за один вызов, который экономит 1000 машин, а не 1 и 1000 вызовов для пользователя, а затем для каждой машины.

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

5. JSON — это всегда хорошее место для начала: json.org/js.html , но опять же, поскольку вы должны делать это как POST, вам действительно не нужно ничего кодировать.