HTTP PUT vs HTTP PATCH v REST API

Přehled

V tomto článku rychlý, díváme se na rozdíly mezi HTTP PUT a PATCH slovesa a na sémantice dvě operace.

použijeme Spring k implementaci dvou koncových bodů REST, které podporují tyto dva typy operací, a k lepšímu pochopení rozdílů a správného způsobu jejich použití.

kdy použít Put a kdy Patch?

začněme jednoduchým a mírně jednoduchým prohlášením.

když klient potřebuje zcela nahradit existující zdroj, může použít PUT. Když dělají částečnou aktualizaci, mohou použít opravu HTTP.

například při aktualizaci jednoho pole zdroje může být odeslání úplné reprezentace zdroje těžkopádné a využívá spoustu zbytečné šířky pásma. V takových případech má sémantika náplasti mnohem větší smysl.

dalším důležitým aspektem, který je třeba zvážit, je idempotence; PUT je idempotent; PATCH může být, ale není vyžadován. A tak – v závislosti na sémantice operace zavádíme, můžeme si také vybrat jeden nebo druhý na základě této charakteristiky.

Prováděcí DÁT a PATCH Logic

řekněme, že chceme k realizaci REST API pro aktualizaci HeavyResource s více polí:

public class HeavyResource { private Integer id; private String name; private String address; // ...

za Prvé, musíme vytvořit koncový bod, který zpracovává kompletní aktualizace zdroje s využitím DÁT:

@PutMapping("/heavyresource/{id}")public ResponseEntity<?> saveResource(@RequestBody HeavyResource heavyResource, @PathVariable("id") String id) { heavyResourceRepository.save(heavyResource, id); return ResponseEntity.ok("resource saved");}

Toto je standardní koncový bod pro aktualizaci zdrojů.

nyní řekněme, že adresní pole bude klient často aktualizován. V takovém případě nechceme poslat celý objekt HeavyResource se všemi poli,ale chceme mít možnost aktualizovat pouze pole adresy – pomocí metody opravy.

můžeme vytvořit HeavyResourceAddressOnly DTO představují částečné aktualizace pole adresa:

public class HeavyResourceAddressOnly { private Integer id; private String address; // ...}

Dále můžeme využít metodu PATCH poslat částečné aktualizace:

@PatchMapping("/heavyresource/{id}")public ResponseEntity<?> partialUpdateName( @RequestBody HeavyResourceAddressOnly partialUpdate, @PathVariable("id") String id) { heavyResourceRepository.save(partialUpdate, id); return ResponseEntity.ok("resource address updated");}

S tímto podrobnější DTO, můžeme odeslat pole potřebujeme aktualizovat pouze – bez režijních nákladů, odesílání celých HeavyResource.

Pokud máme velký počet těchto dílčích aktualizačních operací, můžeme také přeskočit vytvoření vlastní DTO pro každého – a používat pouze mapu:

@RequestMapping(value = "/heavyresource/{id}", method = RequestMethod.PATCH, consumes = MediaType.APPLICATION_JSON_VALUE)public ResponseEntity<?> partialUpdateGeneric( @RequestBody Map<String, Object> updates, @PathVariable("id") String id) { heavyResourceRepository.save(updates, id); return ResponseEntity.ok("resource updated");}

Toto řešení nám dá větší flexibilitu v implementaci API; nicméně, jsme se ztratit pár věcí – jako potvrzení.

testování PUT a PATCH

nakonec napíšeme testy pro obě metody HTTP. Nejprve chceme otestovat aktualizaci plného zdroje pomocí metody PUT:

mockMvc.perform(put("/heavyresource/1") .contentType(MediaType.APPLICATION_JSON_VALUE) .content(objectMapper.writeValueAsString( new HeavyResource(1, "Tom", "Jackson", 12, "heaven street"))) ).andExpect(status().isOk());

provedení částečné aktualizace je dosaženo použitím metody opravy:

mockMvc.perform(patch("/heavyrecource/1") .contentType(MediaType.APPLICATION_JSON_VALUE) .content(objectMapper.writeValueAsString( new HeavyResourceAddressOnly(1, "5th avenue"))) ).andExpect(status().isOk());

můžeme také napsat test pro obecnější přístup:

HashMap<String, Object> updates = new HashMap<>();updates.put("address", "5th avenue");mockMvc.perform(patch("/heavyresource/1") .contentType(MediaType.APPLICATION_JSON_VALUE) .content(objectMapper.writeValueAsString(updates)) ).andExpect(status().isOk());

Zpracování Dílčích Žádostí S Hodnotami Null

Když píšeme implementace pro metodu PATCH, musíme specifikovat smlouvu, jak zacházet s případy, kdy jsme dostali null jako hodnotu pro pole adresa v HeavyResourceAddressOnly.

Předpokládejme, že klient odešle následující žádost:

{ "id" : 1, "address" : null}

Pak jsme to mohli zvládnout, jako nastavení hodnoty pole adresa na hodnotu null, nebo jen ignorovat takové žádosti o léčbě je jako ne-změnu.

měli bychom vybrat jednu strategii pro zpracování null a držet se jí v každé implementaci metody opravy.

závěr

v tomto rychlém tutoriálu jsme se zaměřili na pochopení rozdílů mezi opravou HTTP a metodami PUT.

implementovali jsme jednoduchý řadič Spring REST pro aktualizaci zdroje pomocí metody PUT a částečnou aktualizaci pomocí opravy.

implementace všech těchto příkladů a úryvků kódu lze nalézt v projektu GitHub-jedná se o Projekt Maven – takže by mělo být snadné importovat a spustit tak, jak je.

začněte s Spring 5 a Spring Boot 2, prostřednictvím kurzu Learn Spring:

>> podívejte se na kurz

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.