Ресурс REST со свойством List - PullRequest
0 голосов
/ 28 июня 2010

Я хотел бы получить отзыв о моей текущей архитектуре.

У меня есть ресурс Person, доступный через запросы GET и PUT для: / users / people / {key}. Ресурс создает и принимает объекты Person в формате JSON.

Это пример JSON, который GET /users/people/{key} может вернуть:

{
 "age":29,
 "firstName":"Chiquita",
 "phoneNumbers":[
   {"key":"49fnfnsa0sas","number":"555-555-5555","deleted":false}
   {"key":"838943bdfb-f","number":"777-777-7777","deleted":false}
  ]
}

Как видите, у «Person» есть несколько типичных полей, таких как «firstName» и «age», а также более сложное поле типа коллекции: «phoneNumbers».

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

PUT users/people/{key}

{
 "firstName":"New first name",
}

Таким образом, намного меньше ненужной информации передается взад и вперед (степени меньше в зависимости от размера ресурса)

У меня вопрос: что мне делать со свойствами списка, такими как "phoneNumbers"? Должен ли я написать более сложный код, который проверяет существующие ключи PhoneNumber в старом списке и не касается их, если на них нет ссылок, обновляет их, если есть соответствующий ключ, и добавляет их, если существует PhoneNumber с новым ключом ? Или я должен написать какой-то более простой код, который обрабатывает каждое свойство списка «phoneNumbers» как просто другое поле, которое полностью перезаписывается, если оно включено в тело запроса «PUT»? Существует ли общепринятый подход к этому, когда одна стратегия оказалась менее проблемной, чем другая? или я должен использовать свое усмотрение?

Спасибо!

Ответы [ 3 ]

2 голосов
/ 28 июня 2010

Определение PUT состоит в том, что он должен иметь семантику замены. Глагол PATCH был введен для возможности частичного обновления. Смотри http://tools.ietf.org/html/rfc5789

Что касается того, как сделать формат diff, там действительно нет правильного или неправильного пути. Это действительно зависит от вашего контекста.

1 голос
/ 28 июня 2010

Как уже говорили другие, PUT требует замены всего ресурса.Тем не менее, как архитектор, вы разрабатываете ресурс.Возможно, запись Person содержит номера телефонов как часть этого.Или, может быть, это больше похоже на то, как вы бы создали реляционную базу данных с телефонными номерами в отдельной таблице.В этом случае GET / users / people / {key} получит только имя и возраст, и вы определите параметры запроса, если вы хотите, чтобы номера телефонов вместе с именем.GET / users / userphone / {key} получит ресурс, содержащий телефонные номера человека, массив.

Возвращаясь к определению ресурса Person, содержащего телефонные номера внутри него, нет ничего плохого в использовании POST,Например, классическое использование POST - это опубликовать комментарий на веб-странице или удалить комментарий.Нет причины, по которой вы не можете определить операцию POST для добавления или удаления номера телефона.POST - это метод «что угодно», хороший или плохой.

(я заметил, что здесь написано «Отправьте свой ответ», а не «Поставьте свой ответ», и по уважительной причине).

1 голос
/ 28 июня 2010

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

  • Для типичных сценариев необходимо будет отправлять туда и обратно большое количество данных.
  • Несколько человек могут редактировать одного и того же человека одновременно.

Если ваши люди имеют большие объекты, вы можете рассмотреть возможность использования diff / patch. Перед отправкой новой версии сравните ее со старой версией. Если одноэлементное поле (например, firstName) изменилось, просто укажите его в своем объекте JSON:

{
 "firstName":"New first name"
}

Для массива телефонных номеров перечислите номера телефонов, которые нужно удалить с помощью ключа, и укажите новые телефонные номера, которые нужно добавить, как обычно. Примерно так:

{
 "+phoneNumbers":[
  {"key":"123456789abc","number":"555-123-4567"}
 ],
 "-phoneNumbers":[
  "49fnfnsa0sas"
 ]
}

Вы также можете поискать в Google "json diff" и посмотреть, окажется ли какой-либо из найденных результатов полезным.

Как я уже говорил, если у вас нет веских причин для перехода на эту глубину сложности, вероятно, лучше всего просто попросить клиента повторно загрузить весь объект person для его обновления.

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