Idem potencji
Po RFC PUT musiałby dostarczyć pełny obiekt do zasobu. Głównym tego powodem jest to, że PUT powinien być idempotentny. Oznacza to, że żądanie, które się powtarza, powinno dać taki sam wynik na serwerze.
Jeśli zezwolisz na częściowe aktualizacje, nie będzie to już możliwe. Jeśli masz dwóch klientów. Klient A i B mogą ewoluować następujący scenariusz:
Klient A pobiera obraz z obrazów zasobów. Zawiera opis obrazu, który jest nadal aktualny. Klient B umieszcza nowy obraz i odpowiednio aktualizuje opis. Obraz się zmienił. Klient A widzi, że nie musi zmieniać opisu, ponieważ jest tak, jak chce i umieszcza tylko obraz.
Doprowadzi to do niespójności, do obrazu dołączone są niewłaściwe metadane!
Jeszcze bardziej irytujące jest to, że każdy pośrednik może powtórzyć żądanie. W przypadku, gdy zdecyduje jakoś PUT nie powiodło się.
Znaczenie PUT nie może zostać zmienione (chociaż można go niewłaściwie użyć).
Inne opcje
Na szczęście istnieje inna opcja, to PATCH. PATCH to metoda, która pozwala częściowo zaktualizować strukturę. Możesz po prostu wysłać częściową strukturę. W przypadku prostych aplikacji jest to w porządku. Nie ma gwarancji, że ta metoda będzie silna. Klient powinien wysłać zapytanie w następującej formie:
PATCH /file.txt HTTP/1.1
Host: www.example.com
Content-Type: application/example
If-Match: "e0023aa4e"
Content-Length: 20
{fielda: 1, fieldc: 2}
A serwer może odpowiedzieć 204 (bez zawartości), aby oznaczyć sukces. W przypadku błędu nie można zaktualizować części struktury. Metoda PATCH jest atomowa.
Wadą tej metody jest to, że nie wszystkie przeglądarki obsługują to, ale jest to najbardziej naturalna opcja w usłudze REST.
Przykładowe żądanie łatki:
http://tools.ietf.org/html/rfc5789#section-2.1
Łatanie Jsona
Opcja json wydaje się być dość kompleksowa i interesująca. Wdrożenie może być jednak trudne dla stron trzecich. Musisz zdecydować, czy Twoja baza użytkowników może to obsłużyć.
Jest to również nieco skomplikowane, ponieważ musisz zbudować mały interpreter, który konwertuje polecenia na częściową strukturę, której będziesz używać do aktualizacji swojego modelu. Ten interpreter powinien również sprawdzić, czy podane polecenia mają sens. Niektóre polecenia się znoszą. (napisz fielda, usuń fielda). Myślę, że chcesz zgłosić to klientowi, aby ograniczyć czas debugowania po jego stronie.
Ale jeśli masz czas, jest to naprawdę eleganckie rozwiązanie. Nadal powinieneś sprawdzić poprawność pól. Możesz połączyć to z metodą PATCH, aby pozostać w modelu REST. Ale myślę, że POST byłby do przyjęcia tutaj.
Idzie źle
Jeśli zdecydujesz się na opcję PUT, co jest nieco ryzykowne. W takim razie nie powinieneś przynajmniej odrzucać błędu. Użytkownik ma określone oczekiwania (dane zostaną zaktualizowane), a jeśli je przerwiesz, nie zapewnisz programistom dobrego czasu.
Możesz wybrać wycofanie: 409 Konflikt lub 403 Zakazane. To zależy, jak spojrzysz na proces aktualizacji. Jeśli zobaczysz to jako zestaw reguł (systemowo-centrycznych), konflikt będzie ładniejszy. Coś w rodzaju tych pól nie można aktualizować. (W sprzeczności z zasadami). Jeśli widzisz to jako problem z autoryzacją (zorientowany na użytkownika), powinieneś powrócić zabronione. Z: nie masz uprawnień do zmiany tych pól.
Nadal powinieneś zmusić użytkowników do wysłania wszystkich pól, które można modyfikować.
Rozsądną opcją do tego jest ustawienie podrzędnego zasobu, który oferuje tylko modyfikowalne dane.
Osobista opinia
Osobiście wybrałbym (jeśli nie musisz pracować z przeglądarkami) prosty model PATCH, a następnie rozszerzyłem go o procesor łatek JSON. Można to zrobić, rozróżniając typy mime: Typ mime łatki json:
application / json-patch
I json: application / json-patch
ułatwia wdrożenie go w dwóch fazach.