W projektowaniu RESTful API PUT i PATCH to dwie metody HTTP używane do aktualizowania zasobów na serwerze, ale różnica między PUT a PATCH w interfejsach API REST polega na sposobie przeprowadzania aktualizacji i scenariuszach, w których każdy z nich jest najodpowiedniejszy. Obie metody mają na celu modyfikowanie istniejących danych, ale zrozumienie różnic PUT i PATCH w interfejsie REST API może pomóc programistom w dokonaniu najlepszego wyboru w zależności od charakteru aktualizacji, którą muszą wykonać. W tym poście na blogu przyjrzymy się różnicom PUT i PATCH w REST API, koncentrując się na debacie PATCH vs update REST, kiedy należy używać każdego z nich, a także zapewnimy wskazówki dotyczące wyboru właściwej metody dla różnych przypadków użycia.
Co to jest PUT w interfejsach API REST?
Aby zrozumieć różnicę między PUT a PATCH w interfejsach API REST, najpierw musimy wiedzieć, czym jest PUT. Na podstawie Sekcja 9.6 RFC 2616, metoda PUT w interfejsie API REST żąda, aby załączona jednostka była przechowywana pod dostarczonym identyfikatorem URI żądania.
Jeśli URI żądania odnosi się do już istniejącego zasobu, załączoną jednostkę POWINNO się uważać za zmodyfikowaną wersję tej znajdującej się na serwerze źródłowym. Jeśli URI żądania nie wskazuje na istniejący zasób i ten URI może zostać zdefiniowany jako nowy zasób przez żądającego agenta użytkownika, serwer pochodzenia może utworzyć zasób z tym URI.
Innymi słowy, metoda PUT służy do aktualizacji całego zasobu na serwerze. Dzięki temu PUT jest bardziej „kompletną” aktualizacją, często używaną, gdy konieczna jest pełna wymiana zasobu.
Zatem PUT jest najlepszy w następujących przypadkach użycia:
- Aktualizacja kompletnego zasobu (np. aktualizacja profilu użytkownika o wszystkie nowe informacje).
- Zastąpienie całego elementu lub rekordu.
- Gdy tożsamość zasobu jest jasna, a jego dane wymagają pełnego odświeżenia.
W systemach takich jak Elastyczne wyszukiwanieAby zagwarantować spójność danych, konieczne są operacje idempotentne. Na przykład aktualizacja dokumentu w Elasticsearch za pomocą PUT zapewnia, że to samo żądanie może zostać powtórzone bez niezamierzonych skutków ubocznych.
Co to jest PATCH w interfejsach API REST?
Teraz, gdy omówiliśmy PUT w interfejsach API REST, przyjrzyjmy się, czym jest PATCH w interfejsach API REST i jak działa, zanim porównamy PUT z PATCH w interfejsach API REST. Jak określono w RFC 5789, metoda PATCH w REST API żąda, aby zestaw zmian opisanych w encji żądania został zastosowany do zasobu identyfikowanego przez URI żądania.
Jest to zgodne z rozróżnieniem API PUT i PATCH REST, w którym wysyłane są tylko te dane, które wymagają modyfikacji, a serwer stosuje te zmiany do istniejącego zasobu bez zmiany całego zasobu. Programiści często tworzą łatki odzwierciedlające te przyrostowe zmiany, zapewniając minimalny transfer danych i wydajne aktualizacje.
Dlatego metoda PATCH w REST API lepiej sprawdza się w następujących przypadkach użycia:
- Aktualizacja tylko podzbioru pól w zasobie (np. zmiana adresu e-mail lub numeru telefonu użytkownika). Przykład API PATCH może polegać na wysłaniu tylko nowej wiadomości e-mail, pozostawiając inne pola nietknięte.
- Poprawa wydajności poprzez minimalizację ładunku danych.
- Gdy chcesz aktualizować zasób przyrostowo, zamiast go całkowicie zastępować.
- Twórz poprawki, aby uwzględnić określone zmiany w polach, takie jak modyfikacja adresu e-mail użytkownika, bez wpływu na niepowiązane dane.
Dla platform takich jak bezgłowy CMS które często obsługują złożone struktury treści, użycie PATCH do mniejszych aktualizacji — takich jak modyfikacja pojedynczego pola — może zmniejszyć obciążenie serwera i poprawić wydajność.
Po omówieniu tych dwóch metod powinieneś mieć przyzwoite pojęcie o tym, czym są PUT i PATCH w interfejsach API REST. Zanim jednak przejdziemy do różnicy między PUT a PATCH w interfejsach API REST, musimy porozmawiać o Idempotencji w tych dwóch metodach.
Idempotencja w poprawce PUT vs w interfejsach API REST
W interfejsach API REST idempotencja odnosi się do właściwości operacji, która powtarzana wielokrotnie z tymi samymi danymi wejściowymi daje ten sam wynik. Oznacza to, że wielokrotne wykonanie tego samego żądania powinno mieć taki sam efekt na serwerze, niezależnie od tego, ile razy zostanie wykonane. Jest to ważne dla zapewnienia stabilności i przewidywalności interfejsu API. Ale jakie to ma znaczenie dla różnicy PUT i PATCH w REST API?
Metoda PUT i idempotencja
Metoda PUT w REST API jest zawsze idempotentna, ponieważ ma na celu zastąpienie całego zasobu o określonym URI danymi dostarczonymi w żądaniu. Innymi słowy, jeśli wielokrotnie wykonasz żądanie PUT z tymi samymi danymi zasobów, wynik będzie zawsze taki sam.
Dlaczego PUT jest idempotentny? Kiedy wysyłasz żądanie PUT, w zasadzie mówisz serwerowi: „To jest kompletny i dokładny stan, jaki chcę dla tego zasobu”. Niezależnie od tego, czy wyślesz żądanie PUT raz, czy wiele razy, wynikowy zasób będzie zawsze identyczny.
Rozważmy na przykład scenariusz, w którym aktualizujesz adres e-mail użytkownika. Jeśli wielokrotnie wykonasz to samo żądanie PUT, wynik nie ulegnie zmianie, ponieważ zasób jest za każdym razem zastępowany tymi samymi danymi.
Przykład:
| PUT /users/1{„nazwa użytkownika”: „jan_doe”, „e-mail”: „[email protected]”} |
Jeśli wyślesz tę prośbę wiele razy, wynik będzie zawsze taki sam:
| {„nazwa użytkownika”: „jan_doe”, „e-mail”: „[email protected]”} |
Nawet jeśli dane użytkownika już takie są, ponowne wysłanie żądania niczego nie zmienia. Zastępuje dane tymi samymi danymi, dzięki czemu efekt żądania pozostaje taki sam niezależnie od tego, ile razy zostanie ono powtórzone. To właśnie sprawia, że PUT jest idempotentny.
Metoda PATCH i idempotencja
Z drugiej strony metoda PATCH w REST API jest również ogólnie idempotentna, ale z większą elastycznością. Tworząc poprawki, upewnij się, że operacje są idempotentne (np. ustawianie wartości), aby uniknąć niezamierzonych skutków ubocznych wynikających z powtarzających się żądań. To, czy PATCH jest idempotentny, zależy od operacji i modyfikowanych danych.
Dlaczego PATCH jest idempotentny? W przypadku żądań PATCH idempotencja oznacza, że wielokrotne zastosowanie tej samej poprawki będzie miało ten sam rezultat. Dzieje się tak pod warunkiem, że sam plaster nie powoduje dodatkowych skutków ubocznych lub zmian przy wielokrotnym stosowaniu. Jeśli będziesz aplikował ten sam plaster z tymi samymi danymi, wynik powinien pozostać niezmieniony po pierwszej aplikacji.
Na przykład, jeśli aktualizujesz tylko adres e-mail użytkownika, wielokrotne wysyłanie tego samego żądania PATCH nie spowoduje zmiany wyniku po raz pierwszy, nawet jeśli żądanie zostanie wysłane kilka razy. Adres e-mail użytkownika pozostanie taki sam, a stan zasobu nie ulegnie zmianie.
Przykład API PATCHA:
| PATCH /users/1{„e-mail”: „[email protected]”} |
Jeśli adres e-mail miał już adres [email protected], ponowne zastosowanie tego PATCHA nie spowoduje żadnych zmian, czyniąc go idempotentnym.
Jednak w niektórych przypadkach PATCH może również nie być idempotentny. Na przykład, jeśli operacja PATCH modyfikuje licznik lub dodaje elementy do listy (takie jak zwiększanie liczby lub dołączanie do tablicy), wielokrotne stosowanie tego samego PATCH może prowadzić do różnych wyników. Naruszyłoby to właściwość idempotencji.
Przykład nieidempotentnej łatki REST API:
| PATCH /licznik/1{„przyrost”: 1} |
Jeśli zastosujesz ten PATCH wielokrotnie, licznik będzie się zwiększał, co za każdym razem daje inną wartość. Nie jest to idempotentne, ponieważ wynik zmienia się przy każdym zastosowaniu.
Teraz, gdy znasz już podstawy, możemy przyjrzeć się przykładowym scenariuszom, aby lepiej zrozumieć różnicę między PUT a PATCH w interfejsach API REST.
Przykładowe scenariusze: PUT vs PATCH w interfejsach API REST
Pomijając teorię, spójrzmy na różnicę między PUT i PATCH na przykładach, obejmujących zarówno operacje idempotentne, jak i nieidempotentne.
Scenariusz 1: Żądanie PUT – zastąpienie całego zasobu
Wyobraź sobie punkt końcowy API do zarządzania produktami w systemie e-commerce. Musisz zaktualizować wszystkie szczegóły produktu, w tym jego nazwę, cenę i opis. Jest to typowy przykład metody HTTP PUT vs PATCH, gdzie PUT służy do zastąpienia pełnego zasobu produktu.
Produkt początkowy:
| GET /products/1001{„id”: 1001, „nazwa”: „Laptop”, „cena”: 999,99, „opis”: „Wydajny laptop.”} |
Chcesz zaktualizować cenę i opis produktu. Wysyłasz żądanie PUT z całym zasobem:
Żądanie PUT:
| PUT /products/1001{„id”: 1001, „nazwa”: „Laptop”, „cena”: 899,99, „opis”: „Wydajny laptop w obniżonej cenie.”} |
Jeśli wykonasz to żądanie PUT raz lub wiele razy, wynik będzie zawsze taki sam. Szczegóły produktu zostaną zaktualizowane w celu odzwierciedlenia nowej ceny i opisu, a za każdym razem będzie ten sam wynik. Zapewnia to idempotentny charakter PUT.
Wynik (po żądaniu PUT):
| {„id”: 1001, „nazwa”: „Laptop”, „cena”: 899,99, „opis”: „Wydajny laptop w obniżonej cenie.”} |
Scenariusz 2: Żądanie PATCH – aktualizacja części zasobu
Rozważmy teraz prośbę o PATCH, aby zaktualizować tylko część szczegółów produktu, np. opis. Przykład API PATCH: Jeśli chcesz zmienić opis produktu, ale nie jego cenę, lepszym wyborem będzie PATCH. Aby to zaimplementować, należy utworzyć łatki zawierające tylko pola wymagające modyfikacji, takie jak opis w tym przykładzie API REST PATCH.
Produkt początkowy:
| GET /products/1001{„id”: 1001, „nazwa”: „Laptop”, „cena”: 999,99, „opis”: „Wydajny laptop.”} |
Żądanie PATCHA:
| PATCH /products/1001{„opis”: „Lekki i wydajny laptop.”} |
Kiedy wyślesz to żądanie PATCH, zaktualizowane zostanie tylko pole opisu. Jeśli wielokrotnie wyślesz to samo żądanie PATCH, opis pozostanie niezmieniony po pierwszej aktualizacji, co sprawi, że żądanie będzie idempotentne.
Wynik (po żądaniu PATCH):
| {„id”: 1001, „nazwa”: „Laptop”, „cena”: 999,99, „opis”: „Lekki i wydajny laptop.”} |
Jeśli ponownie zastosujesz ten sam PATCH, opis produktu będzie nadal taki sam, jak po pierwszym PATCHU. Wynik jest spójny, co sprawia, że PATCH jest idempotentny w tym scenariuszu.
Scenariusz 3: Żądanie PATCH – operacja nieidempotentna
Przyjrzyjmy się nieidempotentnej operacji PATCH. Załóżmy, że istnieje punkt końcowy salda portfela użytkownika i chcesz zwiększyć saldo. Przykładową różnicę pomiędzy PUT i PATCH można zilustrować tutaj: PATCH za każdym razem doda wartość do salda
Początkowy portfel:
| GET /users/1/wallet{“id”: 1,”saldo”: 100,00} |
Żądanie PATCHA:
| PATCH /users/1/wallet{„przyrost”: 50,00} |
To żądanie PATCH zwiększy saldo portfela o 50 $. Jeśli wyślesz to żądanie PATCH kilka razy, saldo będzie rosło z każdym PATCHem, co za każdym razem doprowadzi do innego wyniku. Nie jest to idempotentne, ponieważ wielokrotne zastosowanie tego samego PATCH-a spowoduje inny wynik.
Wynik (po pierwszym żądaniu PATCH):
| {„id”: 1, „saldo”: 150,00} |
Wynik (po drugim żądaniu PATCH):
| {„id”: 1, „saldo”: 200,00} |
W tym przypadku PATCH nie jest idempotentny, ponieważ powtarzane żądania z tymi samymi danymi dają różne wyniki.
Podsumowanie: Kluczowe różnice między PUT a PATCH w interfejsach API REST
Kluczową różnicą między PUT a PATCH w REST API jest sposób, w jaki obsługują aktualizacje. PUT zastępuje cały zasób, więc wszelkie brakujące pola są usuwane, co może prowadzić do utraty danych. Właśnie dlatego programiści tworzą poprawki dla częściowych aktualizacji — aby uniknąć nadpisania niezmienionych pól i zachować integralność danych.
Dzięki temu PATCH jest bardziej wydajny w przypadku częściowych aktualizacji. Przykład API PATCH jest taki, że jeśli chcesz zaktualizować tylko adres e-mail użytkownika, utworzenie łatek spowoduje wysłanie tylko pola e-mail, w przeciwieństwie do żądania PUT, które wymagałoby całych danych użytkownika.
W przypadku PUT wymagany jest pełny ładunek danych. Oznacza to, że każde pole musi zostać wysłane, a wszelkie brakujące pola zostaną usunięte. PATCH wysyła jednak tylko te pola, które wymagają aktualizacji, dzięki czemu jest bardziej wydajny, szczególnie w przypadku dużych zasobów przy minimalnych zmianach. Metoda PATCH w REST API pozwala na bardziej skoncentrowane i mniejsze żądania, redukując transfer danych.
Zarówno PUT, jak i PATCH są idempotentne. Oznacza to, że powtórzenie tego samego żądania zakończy się tym samym rezultatem. Jednak PUT jest bardziej przewidywalny, ponieważ zastępuje cały zasób. PATCH, używany do modyfikowania tylko określonych pól, może prowadzić do różnych wyników w zależności od sposobu obsługi aktualizacji przez serwer.
Na przykład, jeśli PATCH zwiększa licznik, powtarzające się żądania mogą prowadzić do różnych wyników. Niemniej jednak operacje API PATCH można zaprojektować tak, aby były również idempotentne.
Podsumowując, różnica PUT i PATCH w REST API sprowadza się do charakteru aktualizacji: PATCH służy do częściowych zmian, podczas gdy PUT służy do całkowitej wymiany zasobów. Oba są idempotentne, ale PATCH może być bardziej złożony.
Ostatnie przemyślenia
Zarówno PUT, jak i PATCH są podstawowymi metodami HTTP w projektowaniu interfejsu API REST, ale służą różnym celom i na tym polega różnica między PUT i PATCH w interfejsie API REST. Możesz znacznie poprawić wydajność, przejrzystość i funkcjonalność swojego interfejsu API, rozumiejąc różnicę między PUT i PATCH na podstawie przykładów omówionych wcześniej w tym artykule. Wybierając właściwą metodę (PATCH vs aktualizacja REST) w zależności od przypadku użycia, możesz uczynić swój interfejs API bardziej wydajnym, łatwiejszym w utrzymaniu i przyjaznym dla użytkownika. Zawsze bierz pod uwagę charakter aktualizacji – pełną czy częściową – wraz z wpływem na wydajność i integralność danych, a następnie wybierz metodę, która najlepiej odpowiada Twoim potrzebom.