Používanie opravy JSON na jar REST API

1. Úvod

Z rôznych dostupných metód HTTP hrá metóda HTTP PATCH jedinečnú rolu. Umožňuje nám to aplikovať čiastočné aktualizácie na zdroje HTTP.

V tomto tutoriáli sa pozrieme na to, ako používať metódu HTTP PATCH spolu s formátom dokumentu JSON Patch na použitie čiastočných aktualizácií na naše prostriedky RESTful.

2. Prípad použitia

Začnime uvažovaním o príklade protokolu HTTP Zákazník zdroj predstavovaný dokumentom JSON:

{"id": "1", "phone": "001-555-1234", "favourites": ["Milk", "Eggs"], "communicationPreferences": {"post": true, "email": pravda}}

Predpokladajme, že telefónne číslo tohto zákazníkasa zmenilo a že zákazník pridal novú položku do svojho zoznamu obľúbených produktov. To znamená, že musíme aktualizovať iba telefón a obľúbené položky polia Zákazník.

Ako by sme to urobili?

Najskôr príde na myseľ populárna metóda HTTP PUT. Pretože však PUT úplne nahradzuje zdroj, nie je vhodný spôsob na elegantné použitie čiastočných aktualizácií. Okrem toho musia klienti pred aplikáciou a uložením aktualizácií vykonať GET.

Tu sa hodí metóda HTTP PATCH.

Poďme pochopiť metódu HTTP PATCH a formáty JSON Patch.

3. Metóda HTTP PATCH a formát opravy JSON

Metóda HTTP PATCH ponúka pekný spôsob použitia čiastočných aktualizácií zdrojov. Výsledkom je, že klienti musia posielať iba rozdiely vo svojich požiadavkách.

Pozrime sa na jednoduchý príklad požiadavky HTTP PATCH:

PATCH / customers / 1234 HTTP / 1.1 Host: www.example.com Content-Type: application / example If-Match: "e0023aa4e" Content-Length: 100 [description of changes]

Telo žiadosti HTTP PATCH popisuje, ako by sa mal cieľový prostriedok upraviť, aby sa vytvorila nová verzia. Ďalej formát používaný na reprezentáciu [popis zmien] sa líši v závislosti od typu zdroja. Pre typy prostriedkov JSON sa na popis zmien používa formát JSON Patch.

Jednoducho povedané, formát JSON Patch používa „sériu operácií“ na opis toho, ako by sa mal cieľový zdroj upraviť. Dokument opravy JSON je pole objektov JSON. Každý objekt v poli predstavuje presne jednu operáciu opravy JSON.

Pozrime sa teraz na operácie opravy JSON spolu s niekoľkými príkladmi.

4. Patchové operácie JSON

Operáciu opravy JSON predstavuje jedna op objekt.

Napríklad tu definujeme operáciu opravy JSON na aktualizáciu telefónneho čísla zákazníka:

{"op": "replace", "path": "/ phone", "value": "001-555-5678"}

Každá operácia musí mať jednu cesta členom. Niektoré prevádzkové objekty musia tiež obsahovať a od členom tiež. Hodnota cesta a od members is a JSON Pointer. Vzťahuje sa na umiestnenie v cieľovom dokumente. Toto umiestnenie môže smerovať na konkrétny kľúč alebo prvok poľa v cieľovom objekte.

Poďme sa teraz v krátkosti pozrieť na dostupné operácie opravy JSON.

4.1. The pridať Prevádzka

Používame pridať operácia na pridanie nového člena k objektu. Môžeme ho tiež použiť na aktualizáciu existujúceho člena a na vloženie novej hodnoty do poľa pri zadanom indexe.

Napríklad pridáme „Chlieb“ k zákazníkovi obľúbené položky zoznam v indexe 0:

{"op": "add", "path": "/ favourites / 0", "value": "Bread"}

Upravené údaje o zákazníkovi po pridať operácia by bola:

{"id": "1", "telefón": "001-555-1234", "obľúbené": ["Chlieb", "Mlieko", "Vajcia"], "communicationPreferences": {"post": pravda, "email": true}}

4.2. The odstrániť Prevádzka

The odstrániť operácia odstráni hodnotu v cieľovom umiestnení. Okrem toho môže odstrániť prvok z poľa v zadanom indexe.

Napríklad, poďme odstrániť komunikáciaPreferencie pre nášho zákazníka:

{"op": "remove", "path": "/ communicationPreferences"}

Upravené údaje o zákazníkovi po odstrániť operácia by bola:

{"id": "1", "telefón": "001-555-1234", "obľúbené": ["Chlieb", "Mlieko", "Vajcia"], "communicationPreferences": null}

4.3. The vymeniť Prevádzka

The vymeniť operácia aktualizuje hodnotu v cieľovom umiestnení o novú hodnotu.

Ako príklad aktualizujme telefónne číslo nášho zákazníka:

{"op": "replace", "path": "/ phone", "value": "001-555-5678"}

Upravené údaje o zákazníkovi po vymeniť operácia by bola:

{"id": "1", "telefón": "001-555-5678", "obľúbené": ["Chlieb", "Mlieko", "Vajcia"], "communicationPreferences": null}

4.4. The pohnúť sa Prevádzka

The pohnúť sa operácia odstráni hodnotu na určenom mieste a pridá ju do cieľového umiestnenia.

Poďme napríklad presunúť slovo „Chlieb“ z vrchnej časti strany zákazníka obľúbené položky zoznam do dolnej časti zoznamu:

{"op": "move", "from": "/ oblíbené / 0", "cesta": "/ obľúbené / -"}

Upravené údaje o zákazníkovi po pohnúť sa operácia by bola:

{"id": "1", "telefón": "001-555-5678", "obľúbené": ["Mlieko", "Vajcia", "Chlieb"], "communicationPreferences": null} 

The / obľúbené / 0 a / obľúbené / - vo vyššie uvedenom príklade sú ukazovatele JSON na počiatočný a konečný index indexu obľúbené položky pole.

4.5. The kópia Prevádzka

The kópia operácia skopíruje hodnotu na určenom mieste do cieľového umiestnenia.

Napríklad duplikujme „Mlieko“ v obľúbené položky zoznam:

{"op": "copy", "from": "/ favourites / 0", "path": "/ favourites / -"}

Upravené údaje o zákazníkovi po kópia operácia by bola:

{"id": "1", "telefón": "001-555-5678", "obľúbené": ["Mlieko", "Vajcia", "Chlieb", "Mlieko"], "communicationPreferences": null}

4.6. The test Prevádzka

The test operačné testy, že hodnota na „ceste“ sa rovná „hodnote“. Pretože je operácia PATCH atómová, mala by sa PATCH zahodiť, ak niektorá z jej operácií zlyhá. The test operácia sa môže použiť na overenie splnenia predbežných podmienok a post-podmienok.

Vyskúšajme napríklad túto aktualizáciu na zákazníka telefón pole bolo úspešné:

{"op": "test", "path": "/ phone", "value": "001-555-5678"} 

Pozrime sa teraz, ako môžeme vyššie uvedené koncepty použiť v našom príklade.

5. HTTP PATCH Request pomocou formátu JSON Patch

Znovu sa vrátime k nášmu Zákazník prípad použitia.

Tu je požiadavka HTTP PATCH na vykonanie čiastočnej aktualizácie zákazníka telefón a obľúbené položky zoznam pomocou formátu JSON Patch:

curl -i -X ​​PATCH // localhost: 8080 / customers / 1 -H "Content-Type: application / json-patch + json" -d '[{"op": "replace", "path": "/ telefón "," value ":" + 1-555-56 "}, {" op ":" add "," path ":" / oblíbené / 0 "," value ":" Chlieb "}] ' 

Najdôležitejšie je, že Druh obsahu pre požiadavky JSON Patch je application / json-patch + json. Telo žiadosti je tiež radom prevádzkových objektov opravy JSON:

[{"op": "replace", "path": "/ phone", "value": "+ 1-555-56"}, {"op": "add", "path": "/ oblíbené / 0 "," value ":" Chlieb "}]

Ako by sme spracovali takúto požiadavku na strane servera?

Jedným zo spôsobov je napísanie vlastného rámca, ktorý postupne vyhodnocuje operácie a aplikuje ich na cieľový zdroj ako atómovú jednotku. Je zrejmé, že tento prístup znie komplikovane. Môže to tiež viesť k neštandardizovanému spôsobu spotreby opravných dokumentov.

Našťastie nemusíme ručne vyrábať spracovanie požiadaviek JSON Patch.

Rozhranie Java API pre spracovanie JSON 1.0 alebo JSON-P 1.0 definované pôvodne v JSR 353 zaviedlo podporu pre opravu JSON v JSR 374. Rozhranie JSON-P API poskytuje JsonPatch typu, ktorý predstavuje implementáciu opravy JSON.

JSON-P je však iba API. Aby sme mohli pracovať s API JSON-P, musíme použiť knižnicu, ktorá ho implementuje. Pre príklady v tomto článku použijeme jednu z týchto knižníc s názvom json-patch.

Poďme sa teraz pozrieť na to, ako môžeme zostaviť službu REST, ktorá spotrebúva požiadavky HTTP PATCH pomocou vyššie popísaného formátu opravy JSON.

6. Implementácia opravy JSON v aplikácii Spring Boot

6.1. Závislosti

Najnovšiu verziu json-patch nájdete v centrálnom úložisku Maven.

Na začiatok pridajme závislosti do pom.xml:

 com.github.java-json-tools json-patch 1.12 

Teraz definujme triedu schémy, ktorá predstavuje Zákazník Dokument JSON:

public class Customer {private String id; súkromný strunový telefón; obľúbené zoznamy v súkromnom zozname; súkromná mapová komunikáciaPreferencie; // štandardné getre a setre}

Ďalej sa pozrieme na našu metódu ovládača.

6.2. Metóda radiča REST

Potom môžeme implementovať HTTP PATCH pre náš prípad použitia zákazníkom:

@PatchMapping (path = "/ {id}", consumes = "application / json-patch + json") public ResponseEntity updateCustomer (@PathVariable String id, @RequestBody JsonPatch patch) {try {Customer customer = customerService.findCustomer (id) .orElseThrow (CustomerNotFoundException :: new); Customer customerPatched = applyPatchToCustomer (patch, customer); customerService.updateCustomer (customerPatched); návrat ResponseEntity.ok (customerPatched); } catch (JsonPatchException | JsonProcessingException e) {return ResponseEntity.status (HttpStatus.INTERNAL_SERVER_ERROR) .build (); } catch (CustomerNotFoundException e) {return ResponseEntity.status (HttpStatus.NOT_FOUND) .build (); }} 

Poďme teraz pochopiť, čo sa deje v tejto metóde:

  • Na začiatok používame @PatchMapping anotácia na označenie metódy ako metódy obsluhy PATCH
  • Keď sa požaduje oprava pomocou application / json-patch + json Prichádza „Content-Type“, Spring Boot používa predvolené nastavenie MappingJackson2HttpMessageConverter previesť užitočné zaťaženie žiadosti na a JsonPatch inštancia. Výsledkom bude, že naša metóda kontrolóra prijme telo žiadosti ako JsonPatch inštancia

V rámci metódy:

  1. Najprv hovoríme customerService.findCustomer (id) metóda na vyhľadanie záznamu zákazníka
  2. Následne, ak sa nájde záznam zákazníka, vyvoláme applyPatchToCustomer (oprava, zákazník) metóda. Toto platí pre JsonPatch zákazníkovi (viac o tom neskôr)
  3. Potom vyvoláme customerService.updateCustomer (customerPatched) pre uloženie záznamu zákazníka
  4. Nakoniec vrátime a 200 OK odpoveď klientovi s opravou Zákazník podrobnosti v odpovedi

Najdôležitejšie je, že skutočná mágia sa deje v applyPatchToCustomer (oprava, zákazník) metóda:

private Customer applyPatchToCustomer (JsonPatch patch, Customer targetCustomer) throws JsonPatchException, JsonProcessingException {JsonNode patched = patch.apply (objectMapper.convertValue (targetCustomer, JsonNode.class)); return objectMapper.treeToValue (opravený, Customer.class); } 
  1. Na začiatok máme svoje JsonPatch inštancia, ktorá obsahuje zoznam operácií, ktoré sa majú použiť na cieľ Zákazník
  2. Cieľ potom prevedieme Zákazník do inštancie com.fasterxml.jackson.databind.JsonNode a odovzdať ho JsonPatch.apply spôsob aplikácie náplasti. V zákulisí JsonPatch.apply sa zaoberá aplikáciou operácií na cieľ. Výsledkom opravy je tiež a com.fasterxml.jackson.databind.JsonNode inštancia
  3. Potom voláme objectMapper.treeToValue metóda, ktorá viaže dáta v opravenom com.fasterxml.jackson.databind.JsonNode do Zákazník typu. Toto je naša oprava Zákazník inštancia
  4. Nakoniec opravené vrátime Zákazník inštancia

Poďme teraz spustiť niekoľko testov proti nášmu API.

6.3. Testovanie

Na začiatok vytvorme zákazníka pomocou požiadavky POST na naše API:

curl -i -X ​​POST // localhost: 8080 / customers -H "Content-Type: application / json" -d '{"phone": "+ 1-555-12", "obľúbené": ["mlieko", "Eggs"], "communicationPreferences": {"post": true, "email": true}} ' 

Dostávame a 201 Vytvorené odpoveď:

HTTP / 1.1 201 Umiestnenie: // localhost: 8080 / customers / 1 

The Poloha hlavička odpovede je nastavená na umiestnenie nového prostriedku. Naznačuje to, že id nového Zákazník je 1.

Ďalej požiadame o čiastočnú aktualizáciu tohto zákazníka pomocou požiadavky PATCH:

curl -i -X ​​PATCH // localhost: 8080 / customers / 1 -H "Content-Type: application / json-patch + json" -d '[{"op": "replace", "path": "/ telefón "," value ":" + 1-555-56 "}, {" op ":" add "," path ":" / oblíbené / 0 "," value ":" Chlieb "}] '

Dostávame a 200Ok odpoveď s opravenými podrobnosťami zákazníka:

HTTP / 1.1 200 Content-Type: application / json Transfer-Encoding: chunked Dátum: Fri, 14 Feb 2020 21:23:14 GMT {"id": "1", "phone": "+ 1-555-56" , "favourites": ["Bread", "Milk", "Eggs"], "communicationPreferences": {"post": true, "email": true}}

7. Záver

V tomto článku sme sa pozreli na to, ako implementovať opravu JSON v API Spring REST.

Na úvod sme sa pozreli na metódu HTTP PATCH a jej schopnosť vykonávať čiastočné aktualizácie.

Potom sme sa pozreli na to, čo je JSON Patch, a pochopili sme rôzne operácie JSON Patch.

Nakoniec sme diskutovali o tom, ako spracovať požiadavku HTTP PATCH v aplikácii Spring Boot pomocou knižnice json-patch.

Zdrojový kód príkladov použitých v tomto článku je ako vždy k dispozícii na serveri GitHub.