Konversi Entitas Ke DTO untuk Spring REST API

REST Top

Saya baru saja mengumumkan kursus Learn Spring baru , yang berfokus pada dasar-dasar Spring 5 dan Spring Boot 2:

>> LIHAT KURSUSnya

1. Ikhtisar

Dalam tutorial ini, kita akan menangani konversi yang perlu terjadi antara entitas internal aplikasi Spring dan DTO eksternal (Objek Transfer Data) yang dipublikasikan kembali ke klien.

2. Pemeta Model

Mari kita mulai dengan memperkenalkan pustaka utama yang akan kita gunakan untuk melakukan konversi entitas-DTO ini - ModelMapper .

Kami akan membutuhkan ketergantungan ini di pom.xml :

 org.modelmapper modelmapper 2.3.5 

Untuk memeriksa apakah ada versi terbaru dari perpustakaan ini, buka di sini.

Kami kemudian akan mendefinisikan kacang ModelMapper dalam konfigurasi Spring kami:

@Bean public ModelMapper modelMapper() { return new ModelMapper(); }

3. DTO

Selanjutnya, mari kita perkenalkan sisi DTO dari masalah dua sisi ini - Posting DTO:

public class PostDto { private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); private Long id; private String title; private String url; private String date; private UserDto user; public Date getSubmissionDateConverted(String timezone) throws ParseException { dateFormat.setTimeZone(TimeZone.getTimeZone(timezone)); return dateFormat.parse(this.date); } public void setSubmissionDate(Date date, String timezone) { dateFormat.setTimeZone(TimeZone.getTimeZone(timezone)); this.date = dateFormat.format(date); } // standard getters and setters } 

Perhatikan bahwa dua metode terkait tanggal kustom menangani konversi tanggal bolak-balik antara klien dan server:

  • Metode getSubmissionDateConverted () mengonversi String tanggal menjadi Tanggal di zona waktu server untuk digunakan di entitas Post yang ada
  • setSubmissionDate () metode adalah untuk mengatur tanggal DTO untuk Posting 's Tanggal di pengguna zona waktu saat ini.

4. Lapisan Layanan

Sekarang mari kita lihat operasi tingkat layanan - yang jelas akan bekerja dengan Entitas (bukan DTO):

public List getPostsList( int page, int size, String sortDir, String sort) { PageRequest pageReq = PageRequest.of(page, size, Sort.Direction.fromString(sortDir), sort); Page posts = postRepository .findByUser(userService.getCurrentUser(), pageReq); return posts.getContent(); }

Kita akan melihat layanan di atas lapisan berikutnya - lapisan pengontrol. Di sinilah konversi akan benar-benar terjadi juga.

5. Lapisan Pengontrol

Sekarang mari kita lihat implementasi pengontrol standar, yang memperlihatkan REST API sederhana untuk sumber daya Post .

Kami akan menunjukkan di sini beberapa operasi CRUD sederhana: buat, perbarui, dapatkan satu, dan dapatkan semua. Dan mengingat operasinya cukup mudah, kami sangat tertarik pada aspek konversi Entity-DTO :

@Controller class PostRestController { @Autowired private IPostService postService; @Autowired private IUserService userService; @Autowired private ModelMapper modelMapper; @GetMapping @ResponseBody public List getPosts(...) { //... List posts = postService.getPostsList(page, size, sortDir, sort); return posts.stream() .map(this::convertToDto) .collect(Collectors.toList()); } @PostMapping @ResponseStatus(HttpStatus.CREATED) @ResponseBody public PostDto createPost(@RequestBody PostDto postDto) { Post post = convertToEntity(postDto); Post postCreated = postService.createPost(post)); return convertToDto(postCreated); } @GetMapping(value = "/{id}") @ResponseBody public PostDto getPost(@PathVariable("id") Long id) { return convertToDto(postService.getPostById(id)); } @PutMapping(value = "/{id}") @ResponseStatus(HttpStatus.OK) public void updatePost(@RequestBody PostDto postDto) { Post post = convertToEntity(postDto); postService.updatePost(post); } }

Dan inilah konversi kami dari entitas Post ke PostDto :

private PostDto convertToDto(Post post) { PostDto postDto = modelMapper.map(post, PostDto.class); postDto.setSubmissionDate(post.getSubmissionDate(), userService.getCurrentUser().getPreference().getTimezone()); return postDto; }

Dan inilah konversi dari DTO menjadi entitas :

private Post convertToEntity(PostDto postDto) throws ParseException { Post post = modelMapper.map(postDto, Post.class); post.setSubmissionDate(postDto.getSubmissionDateConverted( userService.getCurrentUser().getPreference().getTimezone())); if (postDto.getId() != null) { Post oldPost = postService.getPostById(postDto.getId()); post.setRedditID(oldPost.getRedditID()); post.setSent(oldPost.isSent()); } return post; }

Jadi, seperti yang Anda lihat, dengan bantuan pemeta model, logika konversinya cepat dan sederhana - kami menggunakan API peta dari mapper dan mendapatkan data dikonversi tanpa menulis satu baris pun logika konversi.

6. Pengujian Unit

Terakhir, mari lakukan pengujian yang sangat sederhana untuk memastikan konversi antara entitas dan DTO berfungsi dengan baik:

public class PostDtoUnitTest { private ModelMapper modelMapper = new ModelMapper(); @Test public void whenConvertPostEntityToPostDto_thenCorrect() { Post post = new Post(); post.setId(1L); post.setTitle(randomAlphabetic(6)); post.setUrl("www.test.com"); PostDto postDto = modelMapper.map(post, PostDto.class); assertEquals(post.getId(), postDto.getId()); assertEquals(post.getTitle(), postDto.getTitle()); assertEquals(post.getUrl(), postDto.getUrl()); } @Test public void whenConvertPostDtoToPostEntity_thenCorrect() { PostDto postDto = new PostDto(); postDto.setId(1L); postDto.setTitle(randomAlphabetic(6)); postDto.setUrl("www.test.com"); Post post = modelMapper.map(postDto, Post.class); assertEquals(postDto.getId(), post.getId()); assertEquals(postDto.getTitle(), post.getTitle()); assertEquals(postDto.getUrl(), post.getUrl()); } }

7. Kesimpulan

Ini adalah artikel tentang menyederhanakan konversi dari Entitas ke DTO dan dari DTO ke Entitas di Spring REST API , dengan menggunakan perpustakaan model mapper alih-alih menulis konversi ini dengan tangan.

Kode sumber lengkap untuk contoh tersedia di proyek GitHub.

REST bawah

Saya baru saja mengumumkan kursus Learn Spring baru , yang berfokus pada dasar-dasar Spring 5 dan Spring Boot 2:

>> LIHAT KURSUSnya