Should entity class be used as request body [closed]
Asked Answered
H

2

8

Suppose I have to save an entity, in this case, Book. I have the next code:

@RestController
@RequestMapping("books")
public class BookController {
    
    @Inject
    BookRepository bookRepository;
    
    @PostMapping
    public Book saveBook(@RequestBody Book book) {
        return bookRepository.save(book);
    }
}

My entity Book is a persistence entity:

@Entity(name = "BOOK")
public class Book{

    @Id
    @Column(name = "book_id")
    private Integer id;

    @Column(name = "title")
    private String title;

    (get/sets...)
}

The question is: is a bad practice use my persistence entity in @RequestBody of the controller layer? Or should I create a book DTO and map it to my persistence class in a service layer? What is better and why?

Hawserlaid answered 20/10, 2021 at 1:22 Comment(0)
H
7

You should create a DTO class and map it to persistence class. Refer this rule description for the same. Reason specified is

if a persistent object is used as an argument of a method annotated with @RequestMapping, it’s possible from a specially crafted user input, to change the content of unexpected fields into the database

Apart from this, using DTO we can omit some of the persistent object properties that we don't wish to be present/visible in presentation layer.

You can map DTO class to persistence entity in controller itself like below.

@RestController
@RequestMapping("books")
public class BookController {
    
    @Autowired
    BookRepository bookRepository;

    @Autowired
    ModelMapper modelMapper
    
    @PostMapping
    public Book saveBook(@RequestBody BookDTO modelBook) {
        Book book = this.modelMapper.map(modelBook, Book.class);
        return bookRepository.save(book);
    }
}

ModelMapper is a framework that does the DTO to Entity and vice versa mapping. Check ModelMapper website.

You may refer answer and comments for more information about the same.

Harl answered 20/10, 2021 at 3:7 Comment(1)
The description given on the Sonarqube site is lame. I'm typically using Spring Data repositories with the given entities which ensures type safety - I'm not just blindly saving with, say, a session without specifying the table I'm targeting.Insphere
F
7

Yes, it is a really bad idea.

An entity represents persistent data maintained in a database and encapsulates enterprise-wide business rules. On the other hand, DTO is a dumb object - it just holds properties and has getters and setters, but no other logic of any significance. DTOs are used only to transfer data from one subsystem of an application to another.

Imagine having a new requirement to add a new many to many relationship:

@Entity(name = "BOOK")
public class Book{

    @Id
    @Column(name = "book_id")
    private Integer id;

    @ManyToMany
    Set<Student> likes;

... 
} 

Such a change in database would also change the API.

Fag answered 20/10, 2021 at 3:26 Comment(1)
I'm not sure I see exactly how this changes the API.Insphere

© 2022 - 2024 — McMap. All rights reserved.