Rumah  >  Artikel  >  Java  >  Apa yang boleh berlaku jika anda melangkau DTO

Apa yang boleh berlaku jika anda melangkau DTO

WBOY
WBOYasal
2024-07-30 09:46:01646semak imbas

What can happen if you skip the DTOs

Memang bagus kerana rangka kerja seperti SpringBoot boleh melakukan banyak perkara untuk anda.

Anda hanya memerlukan kelas entiti JPA serta antara muka repositori yang ringkas dan SpringData memberikan anda semua yang anda perlukan untuk operasi pangkalan data CRUD biasa.

Anda menulis kelas pengawal REST yang mudah dan anda mempunyai API REST yang sedang dijalankan, bukan?

Hei, tetapi anda terlupa untuk menulis DTO! Tetapi mengapa anda sebenarnya memerlukannya sedangkan apl anda boleh berfungsi tanpanya?

Sudah tentu terdapat beberapa sebab umum:

  • struktur berlapis (cth. seni bina heksagon atau port dan penyesuai): untuk kebolehselenggaraan adalah idea yang baik untuk memisahkan kod komunikasi luaran daripada teras (logik perniagaan)
  • keselamatan dan prestasi: jika anda mendedahkan struktur pangkalan data dalam API anda sebagaimana adanya, anda akan sampai ke tahap di mana anda mendedahkan lebih daripada yang diperlukan; yang boleh disalahgunakan oleh pelakon berniat jahat atau sumber pembaziran (CPU, memori dan lebar jalur rangkaian)
  • DTO, tidak seperti entiti JPA, boleh menjadi tidak berubah (anda boleh menggunakan rekod Java) dan ia bagus untuk gaya pengaturcaraan (berfungsi) dipacu data, ujian unit yang bagus, konkurensi yang lebih selamat, dll.

Tetapi perkara pelik lain juga boleh berlaku. Saya akan tunjukkan satu contoh pelik berdasarkan pengalaman saya.

Repo GitHub ini mengandungi aplikasi mudah yang berfungsi tanpa DTO. Terdapat entiti Pengguna, setiap Pengguna boleh mempunyai berbilang Transaksi. Kami juga mempunyai kacang Perkhidmatan antara repositori dan RestController, menangkap kemungkinan pengecualian akses pangkalan data.

Oleh kerana kami ingin membuat aplikasi sedia pengeluaran, kami tidak mahu Hibernate menjana DDL. Sebaliknya, kami mempunyai schema.sql yang mencipta jadual (kemudian kami boleh bertukar kepada Flyway atau Liquibase). Untuk contoh mudah kami, kami juga mempunyai data.sql supaya jadual kami tidak kosong.

Apabila kami menjalankan aplikasi dan memanggil titik akhir API di http://localhost:8080/users, kami mendapat JSON yang dijangkakan yang mengandungi pengguna dan transaksi mereka.

Sekarang mari kita perhatikan dua baris kod dalam kelas Transaksi, bertanda //!!

@JsonAbaikan //!!

Bau pertama ialah dalam kelas Transaksi kami perlu menambahkan anotasi @JsonIgnore pada rujukan Pengguna. Tanpa anotasi itu, siri JSON ranap kerana rekursi tak terhingga.

Sekarang mari bayangkan seseorang membuat kesilapan dengan menambahkan medan lain (huraian) pada entiti Transaksi, tetapi terlupa untuk melaraskan pernyataan SQL (atau menjalankan aplikasi terhadap persekitaran yang perubahan skema belum digunakan).

perihalan Rentetan peribadi;//!!

Sudah tentu, kini panggilan API gagal. Tetapi lihat pada pengendalian ralat! Klausa tangkapan di dalam UserService tidak berfungsi seperti yang diharapkan. Sebaliknya kita boleh melihat surih tindanan yang pelik dalam log:
GlobalExceptionHandler : Ralat tidak dijangka org.springframework.http.converter.HttpMessageNotWritableException: Tidak dapat menulis JSON:

Saya pernah melihat situasi ini (jelas, dengan aplikasi yang jauh lebih besar daripada contoh ini) dan saya mengambil masa yang agak lama untuk memahami mengapa pengecualian SQL melarikan diri daripada perkhidmatan dan mengapa saya mendapat HttpMessageNotWritableException. Nampak tak?

Apa yang berlaku ialah, kelas UserService (melalui UserRepository) hanya menanyakan jadual pangkalan data USERS. Entiti Transaksi bukan sebahagian daripada hasil kerana pemuatan malas Hibernate lalai. Hanya apabila penyahserialisasi Jackson cuba mencipta JSON daripada tika Pengguna, ia menggunakan kaedah getTransactionsnya yang menjadikan Hibernate mengambil entiti Transaksi.

Inilah sebabnya kami mendapat surih tindanan pelik yang menggabungkan bahan JSON dan SQL. Pengecualian ditangkap oleh GlobalExceptionHandler yang tidak tahu apa yang perlu dilakukan dengannya, inilah sebabnya mesej log ialah "Ralat tidak dijangka".

Saya harap latihan kecil ini akan membuatkan anda memahami dengan lebih mendalam betapa bahayanya membenarkan lapisan aplikasi anda bercampur. Melihat hanya senario "hari cerah" aplikasi anda semasa ia masih kecil boleh menyebabkan sesetengah pembangun terus melakukan perkara yang salah sehingga terlambat.

Anda tidak perlu menulis kod boilerplate yang memetakan medan antara DTO anda dan lapisan lain aplikasi anda. MapStruct boleh melakukannya untuk anda.

Atas ialah kandungan terperinci Apa yang boleh berlaku jika anda melangkau DTO. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn