/ / Vyhnúť sa dvom odlišným doménovým modelom s Spring Boot a Jacksonom - json, hibernate, jpa, spring-boot, jackson

Vyhýbanie sa dvom odlišným modelom domén s Spring Boot a Jackson - json, hibernate, jpa, spring-boot, jackson

Ja navrhujem rozhranie API Spring Boot REST, ktoré bude podporované MySQL.Poznalo sa mi, že chcem efektívne dva samostatné modely pre všetky moje doménové objekty:

  • Model 1: Používa sa medzi vonkajším svetom (klientmi REST) ​​a mojimi regulátormi Spring REST; a
  • Model 2: Entity použité interne medzi aplikáciou Spring Boot a databázou MySQL

Napríklad by som mohol mať contacts tabuľka pre zadanie osobných / kontaktných údajov:

CREATE TABLE contacts (
contact_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
contact_ref_id VARCHAR(36) NOT NULL,
contact_first_name VARCHAR(100) NOT NULL,
...many more fields
);

a príslušné jarné / JPA / hibernácie entity by mohli vyzerať takto:

// Groovy pseudo-code!
@Entity
class Contact {
@Id
@Column(name = "contact_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id

@Column(name = "contact_ref_id")
UUID refId

@Column(name = "contact_first_name")
String firstName

// ...etc.
}

Keby som mal len model paradigmy jediný, potom, keď Jackson ide serializovať a Contact (možno stiahnuté z DB) do JSON a poslať ho späť klientovi, oni videli JSON, ktorý vyzerá takto:

{
"id" : 45,
"refId" : "067e6162-3b6f-4ae2-a171-2470b63dff00",
"firstName" : "smeeb",
...
}

Nič ako vystavovanie primárnych kľúčov vonkajšiemu svetu! Namiesto toho by som rád serializoval JSON vynechať id pole (rovnako ako ostatné). Ďalším príkladom môže byť vyhľadávacia / referenčná tabuľka Colors:

# Perhaps has 7 different color records for ROYGBIV
CREATE TABLE colors (
color_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
color_name VARCHAR(20) NOT NULL,
color_label VARCHAR(20) NOT NULL,
color_hexcode VARCHAR(20) NOT NULL,

# other stuff here
);

Ak zodpovedajúce Color subjekt vyzeral takto:

@Entity
class Color {
@Id
@Column(name = "color_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id

@Column(name = "color_name")
String name

@Column(name = "color_label")
String label

@Column(name = "color_hexcode")
String hexcode

// ...etc.
}

Potom len s jedným modelom by sa serializoval do JSON takto:

{
"id" : 958,
"name" : "Red",
"label" : "RED",
"hexcode" : "ff0000"
}

Ale možno chcem, aby sa vrátila ako jednoduchá hodnota reťazca:

{
"color" : "RED"
}

Zdá sa mi, že budem potrebovať dve oddelenémodely (a mapové triedy, ktoré mapujú medzi nimi), alebo potrebujem spôsob, ako anotovať svoje entity alebo nakonfigurovať buď Spring, Jackson alebo dokonca aj Hibernate, aby som aplikoval určité transformácie na moje entity v správny čas. Poskytujú tieto rámce čokoľvek, čo mi môže pomôcť, alebo budem musieť ísť s dvoma odlišnými doménami?

odpovede:

1 pre odpoveď č. 1

Môžete to skutočne dosiahnuť iba jednoumodel a myslím, že je to najjednoduchší spôsob, ak hľadáte skryté polia, vlastné formátovanie, jednoduchú transformáciu atribútov atď. Keďže dva modely vyžadujú transformáciu z jedného modelu na druhý a naopak, čo je bolesť. Jackson poskytuje veľa užitočných poznámok, ktoré možno použiť na prispôsobenie výstupu. Niektoré z poznámok, ktoré vám môžu byť užitočné, sú uvedené nižšie

@JsonIgnore ignorovať pole / atribút. Pomocou tejto anotácie môžete skryť svoje ID pole.

@JsonInclude - Môže sa použiť na určenie, kedy má byť pole prítomné na výstupe. Napríklad: Či má byť pole na výstupe, ak je nulové

@JsonSerialize - Môžete zadať vlastný serializátor pre atribút. Napríklad: Máte atribút "heslo" a chcete vygenerovať heslo ako "****".

@JsonFormat - Do poľa môžete použiť vlastný formát. Toto je veľmi užitočné, ak máte polia dátumu a času

@JsonProperty - Ak chcete vo svojom výstupe uviesť iný názov vášho poľa. Napríklad: V tvare modelu máte "meno" a chcete ho na výstupe zobraziť ako "userName".