Частичное обновление сложных типов в RESTful Service - PullRequest
2 голосов
/ 12 января 2011

Я использую JSON с сервисом RESTful.Реализация такая:

GET на http://hostname/a возвращает

{
    "a": {
        "b": {
            "c1": "data1",
            "c2": "data2" 
        } 
    }
}

GET на http://hostname/a/b возвращает

{
    "b": {
        "c1": "data1",
        "c2": "data2" 
    } 
}

Я хотелзнать правильное поведение POST (и PUT) на http://hostname/a

{
    "a": {
        "b": {
            "c1": "newdata" 
        } 
    }
}

Должно ли оно просто обновить c1 значением «newdata» или заменить весь ресурс b, тем самым просто содержащий c1 (то есть c2перезаписывается и больше не существует)

Ответы [ 3 ]

2 голосов
/ 12 января 2011

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

Вот упрощенный ответ:
По общему мнению, метод HTTP PUT имеет семантику замены, поэтому c2 перезаписывается и больше не существует.
Метод PATCH был недавно введен, чтобы помочь людям справляться с частичными обновлениями.

Теперь, есть два осложнения сценария:
1) Почему PUT должен заменить семантику? Каковы негативные последствия частичного обновления? Мне еще предстоит услышать действительно убедительный аргумент.

На самом деле, в спецификации HTTP не указано, что PUT имеет семантику замены, она говорит :

Метод PUT запрашивает, чтобы вложенное представление храниться в URI действующего запроса

однако, это также говорит

HTTP / 1.1 не определяет, как PUT метод влияет на состояние происхождения сервер.

2) Принято считать, что если вы предполагаете, что PUT имеет семантику замены, то сервер может включать некоторое содержимое в представление, которое не заменяется. например Если представление содержит ссылки, выполнение PUT представления, которое не содержит этих ссылок, не «удаляет» эти ссылки. То же самое для поля метки времени или последних измененных данных. Вечный вопрос - как определить, какой контент удаляется, когда клиент опускает, а какой остается, потому что сервер так говорит!

Лично я избегал PUT, потому что нашел семантику «замены» слишком сдерживающей. Однако в последнее время Майк Келли и Майк Амундсен начинают убеждать меня, что, возможно, PUT следует считать более гибким, чем мы в настоящее время считаем.

1 голос
/ 12 января 2011

Прежде всего, если вы измените ресурс 'b', почему бы вам не отправить POST (или PUT) на http://hostname/a/b вместо просто http://hostname/a?Если что-то стоит указать / связать, оно должно быть реализовано как ресурс в соответствии с философией RIA и имеет собственный URI.

0 голосов
/ 12 января 2011

Если вы установите PUT на http://hostname/a, что происходит с кэшированными копиями http://hostname/a/b? Как долго они могут быть не синхронизированы?

Если ответ «они не кэшированы» ...?

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

...