pola untuk berbagi objek antara API dan aplikasi

9

Saya memiliki keraguan serius tentang desain untuk aplikasi Web saya.

Saya ingin memisahkan logika bisnis dari antarmuka jadi saya membuat Web API yang menangani semua permintaan ke database.

Ini adalah ASP.NET Web API dengan kerangka kerja Entity dan unit kerja serta pola repositori umum. Sejauh ini semuanya baik-baik saja.

MASALAH

Di mana saya perlu bantuan adalah saya tidak dapat menemukan cara berbagi objek yang efisien antara API dan aplikasi.

Saya tidak ingin membuat cerita bersambung langsung objek entitas, saya pikir ini akan menjadi praktik yang buruk karena jika model entitas berubah, saya bisa berakhir dengan membuat serial objek besar tanpa alasan.

Bagaimana ini diterapkan sekarang

Karena antarmuka saya adalah aplikasi Web ASP.NET di C # dan API saya di C #, saya membuat perpustakaan umum dengan definisi semua kelas yang ingin saya bagikan di antara mereka.

Saya tahu bahwa solusi tidak akan berfungsi ketika saya akan mengembangkan aplikasi android, saya harus membuat kelas saya lagi di Jawa tapi itu bukan masalah terbesar saya.

Masalahnya adalah saya merasa seperti saya selalu mengubah objek saya.

CONTOH

Inilah contoh alur pekerjaan saya:

Saya mulai dengan model dengan semua objek dan anotasi data untuk formulir saya kemudian pengguna akan POST model itu ke controller.

Dalam controller saya harus mengubah model ini ke kelas di perpustakaan umum saya kemudian mengirim objek itu ke API saya.

Kemudian pengontrol di API saya menangkap panggilan dan mengonversi objek itu ke objek entitas untuk memperbarui database.

Jadi saya punya 3 kelas

  1. Model untuk tampilan dengan semua anotasi data untuk validasi (Klien)
  2. Kelas-kelas perpustakaan umum untuk berbagi objek (DLL)
  3. Kelas Entitas (API)

Saya merasa bahwa saya melakukan sesuatu yang sangat salah. Apakah ada sesuatu yang lebih elegan? Saya ingin memastikan bahwa saya memiliki solusi yang baik untuk masalah ini sebelum proyek menjadi terlalu besar.

Marc
sumber
Jika pertanyaan saya tidak jelas, jangan ragu untuk bertanya.
Marc
Bagi saya tidak jelas arsitektur apa yang Anda terapkan (mungkin itu. Net kata yang membingungkan saya) - apakah itu arsitektur 3 tingkat: klien, server, db?
Andy
Ya saya punya aplikasi web yang menggunakan API Web. API adalah logika bisnis dengan database.
Marc

Jawaban:

12

Saya tahu ini mungkin tampak seperti Anda mengubah objek bolak-balik sepanjang waktu antara objek database Anda, objek transfer data Anda, objek klien Anda dengan logika validasi dan sebagainya, tetapi saya akan mengatakan bahwa tidak, Anda tidak melakukan kesalahan apa pun .

Setiap objek ini dapat mewakili unit informasi yang sama, tetapi mereka memiliki tanggung jawab yang sangat berbeda. Objek basis data adalah antarmuka komunikasi Anda dengan basis data dan harus disimpan dalam lapisan basis data karena mungkin atau mungkin tidak memiliki anotasi metadata basis data yang berbeda dan / atau detail yang tidak perlu tentang implementasi basis data di dalamnya.

Objek transfer data Anda adalah antarmuka komunikasi dengan konsumen API Anda. Ini harus sebersih mungkin untuk memfasilitasi konsumsi yang mudah dari berbagai bahasa / platform. Ini mungkin memberlakukan batasan tertentu pada bagaimana ini terlihat dan berperilaku tergantung pada apa yang konsumen API ingin Anda dukung.

Objek klien Anda dengan logika validasi sebenarnya bukan bagian dari proyek API Anda, mereka adalah bagian dari proyek konsumen Anda. Ini tidak bisa sama dengan objek transfer data dalam kasus ini karena Anda menambahkan logika khusus klien tambahan (dalam hal ini atribut validasi) pada mereka yang server tidak tahu apa-apa tentang (dan seharusnya tidak tahu apa-apa!) Anda tidak boleh hitung objek ini sebagai bagian dari API Anda, karena sebenarnya tidak. Mereka sangat spesifik untuk aplikasi konsumen dan beberapa aplikasi yang menggunakan API Anda mungkin sebenarnya tidak perlu membuat objek ini dan dapat bertahan hidup hanya pada objek transfer data Anda. Misalnya, jika Anda tidak memerlukan validasi, Anda tidak perlu lapisan tambahan objek yang benar-benar identik dengan objek transfer data Anda.

Bagi saya, sepertinya masing-masing dari tiga tipe objek memetakan dengan sangat baik untuk satu tanggung jawab yang bersih coding dan praktik yang baik. Sayangnya, kode bersih dan praktik yang baik kadang-kadang berarti Anda menulis banyak kode tambahan dan melompati lingkaran tambahan "hanya karena". Dan ketika melakukan pengkodean, mungkin sulit untuk menghargai nilai yang diberikan ini kepada Anda - tetapi begitu Anda merilis aplikasi Anda dan mulai mendukungnya atau menambahkan fitur baru untuk versi berikutnya maka Anda mungkin akan mulai menghargai bahwa Anda meluangkan waktu untuk pisahkan masalah ini dengan benar sejak awal. (Belum lagi Anda

Saya juga benci menulis kode konversi antara berbagai jenis objek seperti ini, tetapi solusi saya biasanya salah satu dari yang berikut:

  • Gunakan pustaka yang melakukan sebagian besar konversi objek untuk Anda - misalnya, jika Anda menggunakan C # Anda dapat menggunakan pustaka AutoMapper yang fantastis ( http://automapper.org/ ). Saya percaya bahwa ada beberapa perpustakaan lain seperti ini, tetapi AutoMapper adalah yang paling kuat yang pernah saya lihat sejauh ini.
  • Jika Anda tidak dapat menemukan pustaka yang membantu Anda dengan konversi objek, tulis satu set metode utilitas untuk mengonversi di antaranya. Ini mungkin payah, tetapi dalam jangka panjang, layaklah menulis metode konversi saat pertama kali Anda perlu mengonversi sesuatu - jangan menunggu.
wasatz
sumber
Terima kasih atas penjelasan Anda tetapi saya masih kesulitan memahami sesuatu. Saya tidak mengerti mengapa lapisan untuk transfer data tidak memiliki validasi apa pun? Bagaimana jika saya lupa beberapa validasi untuk aplikasi seluler saya selanjutnya? Setidaknya itu tidak akan divalidasi ketika saya memanggil API alih-alih melakukan pengecualian dalam model database saya. Saya tidak yakin saya mengerti.
Marc
1
Saya tidak mengatakan bahwa Anda tidak harus memvalidasi di tingkat API. Sejujurnya, itulah satu-satunya tempat paling penting untuk divalidasi. Memvalidasi dalam aplikasi Anda hanyalah "fitur bagus" untuk membantu pengguna Anda agar tidak membuat kesalahan, memvalidasi objek transfer data Anda adalah untuk menjaga data yang berbahaya dan salah. Karena ini adalah kasus penggunaan yang berbeda, Anda mungkin perlu menggunakan kerangka kerja validasi yang berbeda (Anda akan menggunakan kerangka kerja validasi yang berbeda jika aplikasi dan api Anda tidak ditulis dalam bahasa yang sama) dan Anda dapat memvalidasi hal-hal yang sedikit berbeda di setiap level (Lanjutan . dalam komentar berikutnya)
wasatz
1
Jadi, Anda harus memvalidasi objek transfer data Anda. Tetapi Anda juga harus memastikan bahwa cara Anda memvalidasinya tidak secara tidak sengaja menyebabkan ketergantungan pada kerangka kerja lainnya . Dan tentu saja, seperti yang saya katakan sebelumnya, Anda benar-benar tidak dapat memastikan bahwa objek transfer data Anda telah divalidasi sama sekali atau bahwa mereka telah divalidasi oleh kerangka kerja yang sama - jadi Anda harus "memvalidasi dua kali".
wasatz
2
Terutama, Anda harus mencoba melihat aplikasi dan API Anda sebagai dua aplikasi yang sepenuhnya berbeda dan terpisah. Anda mungkin devloping mereka pada saat yang sama, dan mereka mungkin berada di proyek solusi / gerhana studio visual yang sama. Tetapi mereka benar-benar dua program yang sepenuhnya terpisah. Ketika Anda bekerja di aplikasi Anda, cobalah untuk "lupa" bahwa Anda adalah orang yang telah membuat API dan menggunakannya seperti yang Anda lakukan dengan API pihak ke-3 yang normal. Dengan begitu Anda akan memiliki peluang yang lebih baik untuk melihat bagaimana perasaan orang lain saat menggunakan API Anda dan memperbaiki bagian terburuk sejak dini.
wasatz
1
Dan hal yang sama tentu saja benar ketika bekerja pada proyek API Anda, coba bayangkan bahwa Anda sedang menulis layanan yang akan digunakan oleh banyak pengembang pihak ke-3. Usahakan untuk tidak terlalu memikirkan aplikasi Anda saat ini, tetapi lebih untuk tetap berpikir tentang "layanan apa yang saya berikan" dan dengan asumsi bahwa setiap orang yang menggunakan API Anda (termasuk Anda) adalah orang jahat yang mencoba untuk membunuh server Anda dan membuat Anda menghapus seluruh basis data Anda.
wasatz