2010-06-27 4 views
0

Мне нужна некоторая обратная связь по моей текущей архитектуре.Ресурс REST со свойством List

У меня есть ресурс «Человек», доступный через запросы 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} 
    ] 
} 

Как вы можете видеть, «Человек» имеет некоторые типичные поля, такие как «FirstName» и «возраст», а также хитроумном коллекции -тип: "phoneNumbers".

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

PUT users/people/{key} 

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

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

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

Спасибо!

+0

Чтобы уточнить, это для страницы «Изменить контакт» или аналогичный, где, для данного объекта существуют синглеты (возраст, firstName и т. д.) и коллекции (номер телефона)? –

+0

Эй, Джо, это звучит правильно. –

ответ

1

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

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

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

{ 
"firstName":"New first name" 
} 

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

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

Вы также можете Google поиск «JSon диф» и посмотреть, если какой-либо из результатов вы найдете полезны.

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

2

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

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

+0

PATCH звучит как лучшее описание того, что я делаю. Я использовал PUT, потому что хотел сообщить идемпотентность операции, хотя, строго говоря, это может быть POST. Как вы думаете, мудрость использования PATCH, поскольку она настолько новая и, вероятно, не поддерживается повсюду? –

1

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

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

(я заметил кнопку здесь говорит «Post Ваш ответ», а не «Помещенный Ваш ответ», и не зря.)

Смежные вопросы