Spring til indhold
dto.dk

DTO og entity

Fire slags objekter, der ligner hinanden

DTO'er bliver tit forvekslet med entities og value objects, fordi de alle sammen indeholder data. Forskellen ligger i, hvad de bruges til, og hvem der ejer dem.

TypeFormålIdentitetLogikLever
DTOFlytte data over en grænseNejIngenKort, under ét kald
EntityEn ting i domænet, fx en ordreJa, et idForretningsreglerLænge, ofte i en database
Value objectEn værdi, fx et beløb med valutaNej, kun værdienSmå regler om værdienSom en del af en entity
View modelData formet til én skærmNejVisningslogikKort, under visningen

Entity

En entity er noget med en identitet, der varer ved. En ordre er stadig den samme ordre, selv om der kommer en ny linje på. Entities indeholder forretningsreglerne, fx at en afsendt ordre ikke kan ændres, og de bliver typisk gemt i en database, ofte gennem en ORM.

Value object

Et value object er defineret af sin værdi og ikke af en identitet. To beløb på 100 kroner er det samme beløb. Value objects er uforanderlige og kan indeholde små regler, fx at et beløb ikke kan lægges sammen med et beløb i en anden valuta.

DTO

En DTO har hverken identitet eller regler. Den er en pakke med data, som kun findes for at blive sendt et sted hen. Den kan godt indeholde værdier fra både entities og value objects, men i en enkel form, der er let at serialisere.

View model

En view model er formet efter én bestemt skærm. Den kan fx indeholde en færdigformateret pris og en tekst til en knap. Den ligner en DTO, men den hører til i brugerfladen og ikke i API'et.

Hvorfor ikke bare sende entity'en?

Det er fristende at returnere sine entities direkte fra et API, og i et lille projekt kan det gå. Men det giver nogle velkendte problemer:

  • Du sender for meget. Felter som adgangskode-hash, interne noter eller rabatsatser kan slippe ud.
  • Klienten kan sætte for meget. Hvis den samme klasse bruges til at tage imod data, kan en klient måske sætte felter, den ikke burde, fx en rolle eller en pris. Det kaldes mass assignment eller over-posting.
  • API'et bliver bundet til databasen. Omdøber du en kolonne, ændrer du samtidig dit API og får klienterne til at fejle.
  • Serialisering kan gå galt. Relationer mellem entities kan give uendelige løkker eller hente store mængder data, når objektet bliver lavet om til JSON.

En DTO løser alle fire: den indeholder kun de felter, du vælger, i den form, du vælger.

Hvornår er en DTO for meget?

I et lille internt værktøj, hvor databasen og brugerfladen altid ændres sammen, kan ekstra DTO-klasser være spildt arbejde. Tommelfingerreglen er: jo flere klienter, og jo længere API'et skal leve, jo mere betaler en DTO sig.

Validering og mapping