A JSON javítás használata a Spring REST API-kban
1. Bemutatkozás
A rendelkezésre álló különféle HTTP módszerek közül a HTTP PATCH módszer egyedülálló szerepet játszik. Ez lehetővé teszi számunkra, hogy részleges frissítéseket alkalmazzunk a HTTP erőforrásokra.
Ebben az oktatóanyagban megvizsgáljuk, hogyan lehet a HTTP PATCH módszert a JSON Patch dokumentumformátummal együtt alkalmazni a RESTful erőforrásaink részleges frissítéseire.
2. A használati eset
Kezdjük egy HTTP példával Vevő a JSON dokumentum által képviselt erőforrás:
{"id": "1", "telefon": "001-555-1234", "kedvencek": ["Tej", "Tojás"], "communicationPreferences": {"post": true, "email": igaz}}
Tegyük fel, hogy ennek az ügyfélnek a telefonszámamegváltozott, és hogy az ügyfél új elemet adott hozzá a kedvenc termékek listájához. Ez azt jelenti, hogy csak a telefon és kedvencek mezői Vevő.
Hogyan tennénk ezt?
Először a népszerű HTTP PUT módszer jut eszembe. Mivel azonban a PUT teljesen helyettesíti az erőforrást, ez nem megfelelő módszer a részleges frissítések elegáns alkalmazására. Ezenkívül az ügyfeleknek GET-et kell végrehajtaniuk a frissítések alkalmazása és mentése előtt.
Itt jön jól a HTTP PATCH módszer.
Ismerjük meg a HTTP PATCH módszert és a JSON Patch formátumokat.
3. A HTTP PATCH módszer és a JSON javítás formátum
A HTTP PATCH módszer jó lehetőséget kínál az erőforrások részleges frissítéseinek alkalmazására. Ennek eredményeként az ügyfeleknek csak a különbségeket kell elküldeniük a kéréseikben.
Nézzünk meg egy egyszerű példát a HTTP PATCH kérelemre:
PATCH / customers / 1234 HTTP / 1.1 Host: www.example.com Tartalomtípus: alkalmazás / példa If-Match: "e0023aa4e" Tartalomhossz: 100 [a változások leírása]
A HTTP PATCH kérelem törzs leírja, hogyan kell módosítani a cél erőforrást egy új verzió előállításához. Ezenkívül a [a változások leírása] az erőforrás típusától függően változik. JSON erőforrástípusok esetében a változtatások leírására használt formátum a JSON javítás.
Egyszerűen fogalmazva: a JSON Patch formátum egy „műveletsorral” írja le, hogyan kell módosítani a cél erőforrást. A JSON javító dokumentum a JSON objektumok tömbje. A tömb minden objektuma pontosan egy JSON Patch műveletet képvisel.
Vizsgáljuk meg most a JSON javítás műveleteit, néhány példával együtt.
4. JSON javítóműveletek
A JSON Patch műveletet egyetlen kép képviseli op tárgy.
Például itt meghatározunk egy JSON patch műveletet az ügyfél telefonszámának frissítéséhez:
{"op": "csere", "elérési út": "/ telefon", "érték": "001-555-5678"}
Minden műveletnek rendelkeznie kell egyet pálya tag. Néhány műveleti objektumnak tartalmaznia kell a tól től tag is. A. Értéke pálya és tól től tagjai egy JSON-mutató. A céldokumentumon belüli helyre utal. Ez a hely egy adott kulcsra vagy tömb elemre mutathat a célobjektumban.
Nézzük meg röviden az elérhető JSON Patch műveleteket.
4.1. A hozzá Művelet
Használjuk a hozzá művelet új tag hozzáadásához egy objektumhoz. Ezenkívül felhasználhatjuk meglévő tag frissítésére és egy új érték beillesztésére a tömbbe a megadott indexnél.
Például tegyük hozzá a „Kenyér” szót az ügyfélhez kedvencek lista a 0. indexen:
{"op": "add", "path": "/ favourites / 0", "value": "Kenyér"}
A módosított ügyféladatok a hozzá művelet a következő lenne:
{"id": "1", "telefon": "001-555-1234", "kedvencek": ["Kenyér", "Tej", "Tojás"], "communicationPreferences": {"post": true, "email": igaz}}
4.2. A eltávolítani Művelet
A eltávolítani A művelet eltávolít egy értéket a célhelyen. Ezenkívül eltávolíthat egy elemet egy tömbből a megadott indexen.
Például távolítsuk el a kommunikációPreferenciák ügyfelünk számára:
{"op": "eltávolítás", "elérési út": "/ communicationPreferences"}
A módosított ügyféladatok a eltávolítani művelet a következő lenne:
{"id": "1", "telefon": "001-555-1234", "kedvencek": ["Kenyér", "Tej", "Tojás"], "communicationPreferences": null}
4.3. A cserélje ki Művelet
A cserélje ki A művelet új értékkel frissíti a célhelyen lévő értéket.
Példaként frissítsük ügyfelünk telefonszámát:
{"op": "csere", "elérési út": "/ telefon", "érték": "001-555-5678"}
A módosított ügyféladatok a cserélje ki művelet a következő lenne:
{"id": "1", "telefon": "001-555-5678", "kedvencek": ["Kenyér", "Tej", "Tojás"], "communicationPreferences": null}
4.4. A mozog Művelet
A mozog művelet eltávolítja az értéket a megadott helyen, és hozzáadja a célhelyhez.
Például vigyük át a „Kenyeret” az ügyfél tetejéről kedvencek lista a lista aljára:
{"op": "move", "from": "/ favourites / 0", "path": "/ favourites / -"}
A módosított ügyféladatok a mozog művelet a következő lenne:
{"id": "1", "telefon": "001-555-5678", "kedvencek": ["Tej", "Tojás", "Kenyér"], "communicationPreferences": null}
A / kedvencek / 0 és / kedvencek / - A fenti példában JSON-mutatók mutatják a kedvencek sor.
4.5. A másolat Művelet
A másolat művelet másolja az értéket a megadott helyen a célhelyre.
Például másoljuk a „Tejet” a kedvencek lista:
{"op": "copy", "from": "/ favourites / 0", "path": "/ favourites / -"}
A módosított ügyféladatok a másolat művelet a következő lenne:
{"id": "1", "telefon": "001-555-5678", "kedvencek": ["Tej", "Tojás", "Kenyér", "Tej"], "communicationPreferences": null}
4.6. A teszt Művelet
A teszt művelet teszteli, hogy az „útvonalon” lévő érték megegyezik-e az „értékkel”. Mivel a PATCH művelet atomi, a PATCH-ot el kell dobni, ha valamelyik művelete sikertelen. A teszt művelettel ellenőrizhető, hogy az előfeltételek és az utólagos feltételek teljesülnek-e.
Például teszteljük, hogy az ügyfél frissítése telefon mező sikeres volt:
{"op": "teszt", "elérési út": "/ telefon", "érték": "001-555-5678"}
Most nézzük meg, hogyan alkalmazhatjuk a fenti fogalmakat példánkra.
5. HTTP PATCH kérelem a JSON javító formátum használatával
Újra meglátogatjuk Vevő használati eset.
Itt található a HTTP PATCH kérés az ügyfél részleges frissítéséhez telefon és kedvencek lista a JSON Patch formátumot használva:
curl -i -X PATCH // localhost: 8080 / customers / 1 -H "Content-Type: application / json-patch + json" -d '[{"op": "csere", "elérési út": "/ telefon "," value ":" + 1-555-56 "}, {" op ":" add "," path ":" / favourites / 0 "," value ":" Kenyér "}] '
A legfontosabb, hogy Tartalom típus a JSON Patch kérésekhez application / json-patch + json. Ezenkívül a kérelem törzs egy JSON Patch művelet objektum tömbje:
[{"op": "csere", "elérési út": "/ telefon", "érték": "+ 1-555-56"}, {"op": "hozzáadás", "útvonal": "/ kedvencek / 0 "," value ":" Kenyér "}]
Hogyan dolgoznánk fel egy ilyen kérést a szerver oldalon?
Az egyik mód egy olyan egyedi keretrendszer megírása, amely egymás után értékeli a műveleteket és atomegységként alkalmazza a cél erőforrásra. Nyilvánvaló, hogy ez a megközelítés bonyolultnak hangzik. Ez a patch dokumentumok nem szabványosított felhasználásához is vezethet.
Szerencsére nem kell kézzel elkészítenünk a JSON Patch kérések feldolgozását.
A JSON Processing 1.0 Java API vagy JSON-P 1.0, amelyet eredetileg a JSR 353 definiált, bevezette a JSON Patch támogatását a JSR 374-ben. A JSON-P API biztosítja a JsonPatch típus a JSON Patch megvalósításának képviseletére.
A JSON-P azonban csak API. A JSON-P API használatához olyan könyvtárat kell használnunk, amely megvalósítja azt. A cikk példáihoz egy ilyen json-patch nevű könyvtárat fogunk használni.
Most nézzük meg, hogyan készíthetünk olyan REST szolgáltatást, amely HTTP PATCH kéréseket fogyaszt, a fent leírt JSON Patch formátummal.
6. A JSON Patch megvalósítása egy tavaszi rendszerindító alkalmazásban
6.1. Függőségek
A json-patch legújabb verziója megtalálható a Maven Central adattárban.
Először tegyük hozzá a függőségeket a pom.xml:
com.github.java-json-tools json-patch 1.12
Most definiáljunk egy sémaosztályt a Vevő JSON-dokumentum:
public class Ügyfél {private String id; saját String telefon; privát Lista kedvencek; privát térképi kommunikációPreferenciák; // szabványos mérőeszközök és beállítók}
Ezután megvizsgáljuk a vezérlő módszerünket.
6.2. A REST vezérlő módszer
Ezután implementálhatjuk a HTTP PATCH-ot az ügyfelek felhasználási eseteihez:
@PatchMapping (elérési út = "/ {id}", fogyaszt = "alkalmazás / json-patch + json") nyilvános ResponseEntity updateCustomer (@PathVariable karakterlánc, @RequestBody JsonPatch javítás) {try {Customer customer = customerService.findCustomer (id) .orElseThrow (CustomerNotFoundException :: new); Ügyfél customerPatched = ApplyPatchToCustomer (javítás, ügyfél); customerService.updateCustomer (customerPatched); return 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 (); }}
Most értsük meg, mi folyik ebben a módszerben:
- Először is a @PatchMapping annotáció a módszer PATCH kezelő módszerként történő megjelölésére
- Amikor javítást igényel a application / json-patch + json Megérkezik a „Content-Type”, a Spring Boot az alapértelmezettet használja MappingJackson2HttpMessageConverter a kérelem hasznos terhelésének a JsonPatch példa. Ennek eredményeként a kontroller módszerünk megkapja a kéréstestet a-ként JsonPatch példa
A módszeren belül:
- Először a customerService.findCustomer (id) módszer az ügyfélrekord megkeresésére
- Ezt követően, ha megtalálható az ügyfélrekord, akkor a ApplyPatchToCustomer (javítás, ügyfél) módszer. Ez vonatkozik a JsonPatch az ügyfélnek (erről később)
- Ezután meghívjuk a customerService.updateCustomer (customerPatched) az ügyfélrekord mentéséhez
- Végül visszatérünk a 200 OK válasz az ügyfélnek a javítással Vevő részleteket a válaszban
Ami a legfontosabb, hogy az igazi varázslat a ApplyPatchToCustomer (javítás, ügyfél) módszer:
privát Ügyfél ApplyPatchToCustomer (JsonPatch javítás, Ügyfél targetCustomer) dobja JsonPatchException, JsonProcessingException {JsonNode patched = patch.apply (objectMapper.convertValue (targetCustomer, JsonNode.class)); return objectMapper.treeToValue (javított, Ügyfél.osztály); }
- Először is megvan a miénk JsonPatch a célra alkalmazandó műveletek listáját tartalmazó példány Vevő
- Ezután átalakítjuk a célt Vevő példányába com.fasterxml.jackson.databind.JsonNode és adja át a JsonPatch.alkalmazzon módszer a tapasz felhelyezésére. A színfalak mögött a JsonPatch.alkalmazzon foglalkozik a műveletek célpontra való alkalmazásával. A tapasz eredménye szintén a com.fasterxml.jackson.databind.JsonNode példa
- Ezután felhívjuk a objectMapper.treeToValue módszer, amely leköti a javított adatokat com.fasterxml.jackson.databind.JsonNode hoz Vevő típus. Ez a mi javításunk Vevő példa
- Végül visszaküldjük a javítottat Vevő példa
Futtassunk most néhány tesztet az API-nkkal szemben.
6.3. Tesztelés
Először hozzunk létre egy ügyfelet az API-nkhoz tartozó POST-kérelem segítségével:
curl -i -X POST // localhost: 8080 / customers -H "Content-Type: application / json" -d '{"telefon": "+ 1-555-12", "kedvencek": ["Milk", "Tojás"], "communicationPreferences": {"post": true, "email": true}} '
Kapunk egy 201 Létrehozva válasz:
HTTP / 1.1 201 Hely: // localhost: 8080 / customers / 1
A Elhelyezkedés A válasz fejléc az új erőforrás helyére van beállítva. Azt jelzi, hogy a id az új Vevő az 1.
Ezután kérjünk részleges frissítést az ügyféltől egy PATCH kérelem használatával:
curl -i -X PATCH // localhost: 8080 / customers / 1 -H "Content-Type: application / json-patch + json" -d '[{"op": "csere", "elérési út": "/ telefon "," value ":" + 1-555-56 "}, {" op ":" add "," path ":" / favourites / 0 "," value ":" Kenyér "}] '
Kapunk egy 200rendben válasz a javított ügyféladatokkal:
HTTP / 1.1 200 Tartalomtípus: alkalmazás / json átviteli kódolás: darabos Dátum: Péntek, 2020. február 14., 21:23:14 GMT {"id": "1", "telefon": "+ 1-555-56" , "kedvencek": ["Kenyér", "Tej", "Tojás"], "communicationPreferences": {"post": true, "email": true}}
7. Következtetés
Ebben a cikkben megvizsgáltuk, hogyan lehet a JSON javítást megvalósítani a tavaszi REST API-kban.
Először is megvizsgáltuk a HTTP PATCH módszert és annak részleges frissítésekre való képességét.
Ezután megvizsgáltuk, mi a JSON Patch, és megértettük a különböző JSON Patch műveleteket.
Végül megbeszéltük, hogyan lehet kezelni a HTTP PATCH kérést egy Spring Boot alkalmazásban a json-patch könyvtár segítségével.
Mint mindig, a cikkben használt példák forráskódja elérhető a GitHubon.