Di mana saya harus meletakkan permintaan API di MVC?

25

Saya sedang membangun aplikasi web menggunakan pola MVC. Mengikuti jenis arsitektur ini kita dapat melihat bahwa semua metode yang digunakan untuk berinteraksi dengan basis data diimplementasikan dalam model .

Tetapi apa yang terjadi jika saya harus memanggil layanan yang diekspos oleh orang lain di web? Misalnya, saya ingin mengakses API Facebook untuk mendapatkan semua pengikut halaman saya, jadi, di mana saya meletakkan metode ini?

Jelas tampilan bukan ide yang baik karena modul ini didedikasikan untuk presentasi, controller tidak boleh digunakan untuk mengambil data tetapi model ini biasanya hanya didedikasikan untuk interaksi dengan database.

Jadi, bisakah Anda memberi saya beberapa petunjuk tentang itu? Dan tolong, bisakah Anda memberi tahu saya jika saya membuat beberapa kesalahan tentang arsitektur MVC?

Ema.jar
sumber
2
Saya pikir orang-orang akan dapat memberikan jawaban yang lebih baik jika Anda mendaftar beberapa perpustakaan dan kerangka kerja yang Anda gunakan untuk mendukung aplikasi MVC Anda. Sementara pola MVC adalah teknologi agnostik, tidak semua kerangka kerja mengikutinya secara eksplisit. Selain itu, sebagian besar kerangka kerja yang matang sudah memiliki dokumentasi yang luar biasa dan mengetahui mana yang Anda gunakan akan membuatnya lebih mudah untuk mengarahkan Anda ke penjelasan yang sudah ada sebelumnya yang mengikuti garis pemikiran Anda.
CLW
2
Basis data? Sumber data? Itu hanya data.
2
Ada begitu banyak pendapat tentang "MVC" yang seharusnya, sehingga pertanyaan ini terlalu abstrak untuk dijawab.
RemcoGerlich
2
Juga, pertimbangkan untuk memanggil API dari kode Javascript frontend Anda, dan tidak menyentuhnya menyentuh hal-hal "MVC" backend Anda sama sekali.
RemcoGerlich
@Remcogerlich itu sebabnya saya mengusulkan penambahan implementasi aktual yang dia lihat. Dia bisa berurusan dengan backend dan implementasi frontend dari MVC. Kita dapat memiliki pola lain yang juga menjelaskan perbedaan-perbedaan ini dengan lebih baik.
CLW

Jawaban:

37

Model tidak terbatas pada interaksi dengan database, model bertanggung jawab untuk mendapatkan dan memanipulasi data.

Jadi, untuk tampilan dan pengontrol Anda, seharusnya tidak ada bedanya, jika data berasal dari database atau dari layanan web atau bahkan benar-benar acak, oleh karena itu Anda harus melakukannya dalam model.

MVC adalah pola presentasi, yang hanya memisahkan lapisan representasi yang berbeda.

Itu tidak berarti, bahwa model harus berantakan seragam kode spaghetti. Model Anda sendiri dapat berlapis juga, tetapi controller tidak harus tahu, dari mana data berasal.

Metode publik dalam model Anda dapat disusun seperti ini (Pseudo-code), yang dapat dipanggil oleh controller Anda:

public MyDataClass getData(int id) {
    WebServiceData wsData = WebService->getData(id);
    DatabaseData dbData = ORM->getData(id);
    return new MyDataClass(wsData, dbData);
}

WebServicedan ORMmungkin harus berupa instance dari antarmuka yang dapat diganti dengan mengejek melalui injeksi dependensi, tetapi pengontrol dan tampilan Anda tidak harus berubah untuk tujuan pengujian.

Residuum
sumber
8
Model tidak boleh memiliki logika apa pun dan karenanya tidak berinteraksi langsung dengan apa pun. Pola MVC dengan jelas meminta semua logika untuk ditempatkan ke dalam pengontrol. Pengontrol ini harus menghubungi DB, API, dll ... dan memperbarui model yang diperlukan. Ini membuat agnostik teknologi model Anda, dan memastikannya berfungsi tidak lebih dari mekanisme penyimpanan yang dapat diteruskan ke berbagai tampilan untuk presentasi dan pengontrol untuk manipulasi tambahan.
CLW
3
@ CLW: Model! = Model data. Rincian lebih lanjut dapat ditemukan di tempat lain, misalnya stackoverflow.com/a/14045514/124983
Residuum
2
@ CLW: logika bisnis tidak boleh dalam M, V, atau C. Model adalah abstraksi dari penyimpanan data, pandangan dan pengontrol adalah antarmuka pengguna Anda. Mereka adalah pinggiran dari aplikasi aktual yang Anda buat, yang seharusnya "hanya kode", yang tidak perlu tahu tentang hal-hal seperti database dan web.
RemcoGerlich
2
Bagian "model" ditafsirkan ratusan cara berbeda. Saya selalu diajari bahwa model adalah representasi. Kereta model adalah representasi dari kereta nyata, dengan sedikit bagian yang bergerak yang bergerak seperti yang asli. Demikian pula, model di aplikasi Anda adalah representasi dari sistem dan proses yang Anda sedang membangun untuk mengganti perangkat lunak Anda. Dengan demikian, model memiliki perilaku . Perilaku itu menggabungkan "logika bisnis" Anda. Jadi, ketika Anda mengabaikan akses data CRUD murni, UI, dan interop, yang tersisa mungkin adalah "model" Anda - kelas domain, aturan bisnis, dll.
anaximander
1
@RemcoGerlich Saya tidak mengatakan apapun tentang logika bisnis. Saya hanya menyatakan bahwa karena sebagian besar interpretasi panggilan MVC untuk model tidak lebih dari sebuah struct sederhana yang mewakili status aplikasi Anda, bahwa tanggung jawab menghubungi DB, API, dll ... tidak boleh ditempatkan dalam model karena harus logika gratis. Tugas berkomunikasi dengan database harus jatuh pada controller atau objek lain yang dikelola oleh controller.
CLW
12

Ada kesalahpahaman (disengaja?) Yang umum tentang apa itu M, V, dan C. Bukan tentang peran mereka ambil, tapi apa yang mereka.

Dalam definisi GUI desktop asli dari MVC, mereka adalah modul . Biasanya suatu aplikasi memiliki beberapa dari mereka, kadang-kadang bekerja dalam kembar tiga, kadang-kadang memiliki beragam pandangan dan model yang dapat dicampurkan dan disesuaikan oleh beberapa pengontrol.

Dalam kerangka kerja web, OTOH, mereka cenderung dilihat sebagai lapisan , di mana mereka hanya satu dari masing-masing dan sebagian besar berurusan pada mencakup beberapa tingkat abstraksi sub-pusat: "lapisan model mengabstraksi database", "lapisan tampilan mengimplementasikan presentasi", "controller melihat layer memproses input pengguna ".

Jadi, saya akan mengatakan bahwa Anda sudah memiliki sebuah model yang didedikasikan untuk interaksi dengan database, dan sekarang hanya perlu membuat lagi model untuk menangani sumber API Anda. Jika Anda membuat mereka semirip mungkin, maka sebagian besar controller dan kode tampilan dapat bekerja dengan baik dengan kedua model.

Javier
sumber
1
Setuju: Model selalu dianggap sebagai keseluruhan domain masalah. Dalam aplikasi yang rumit itu selalu seharusnya menjadi bagian terbesar dari kode. Mereka terdiri dari semua kode yang tidak akan berubah jika Anda mengubah Antarmuka Pengguna (misalnya, dari situs web ke GUI atau bahkan aplikasi baris perintah). Pikirkan kompiler. Hanya sebagian kecil dari kode yang akan berubah jika Anda beralih dari UI baris perintah ke GUI, atau bahkan UI web. Semua nyali dari aplikasi semacam itu adalah model.
Kevin Cathcart
1
Dalam penggunaan Smalltalk asli dari istilah ini, setiap kontrol UI di antarmuka memiliki model, tampilan, dan pengontrol sendiri.
RemcoGerlich
5

Bagian dari kesulitan dengan setiap diskusi tentang MVC adalah bahwa kelompok-kelompok yang berbeda telah mengkooptasi untuk memiliki arti yang berbeda. Implementasi MVC yang digunakan dalam, katakanlah, aplikasi Rails, akan hampir tidak dapat dikenali oleh seseorang yang menulis aplikasi Swing. Sejauh MVC masih merupakan hal yang terdefinisi dengan baik, ini lebih merupakan seperangkat prinsip panduan (pisahkan aplikasi inti dari representasi visualnya, berikan mekanisme yang fleksibel untuk memungkinkan keduanya untuk disatukan), yang dapat diimplementasikan dalam berbagai cara.

Memang, ada kecenderungan memberikan berbagai desain turunan MVC nama yang berbeda (lihat artikel ini oleh Martin Fowler untuk beberapa diskusi tentang ini), atau bahkan menyerah pada penamaan yang tepat - misalnya, AngularJS menggambarkan dirinya sebagai Model-View-Apapun kerangka.

Jadi, sulit untuk menjawab tanpa mengetahui versi "MVC" yang Anda gunakan. Namun, permintaan API biasanya akan menjadi bagian dari aplikasi inti (bagian yang tidak boleh berubah jika Anda memutuskan untuk menggunakan representasi visual yang berbeda), yang dalam banyak implementasi akan terkandung sepenuhnya dalam model.

James_pic
sumber
2

Di sini , model digambarkan seperti ini:

Model menyimpan data yang diambil ke controller dan ditampilkan dalam tampilan. Setiap kali ada perubahan pada data itu diperbarui oleh pengontrol.

Saya akan mengatakan bahwa controller baik termasuk logika memanggil layanan atau memanggil Serviceobjek terpisah . Jika layanan terpisah, Anda dapat lebih mudah membuat tes, katakanlah, jika tidak ada koneksi ke layanan melalui jaringan, beberapa TestServicedapat memberikan tanggapan dari Servicelokal.

Periksa juga jawaban ini yang menyarankan Pengontrol memanggil layanan.

batal
sumber
2

Model Anda tidak boleh mengandung kode aktual, dan harus dilihat sebagai lebih dari pesan atau struct yang digunakan untuk mengelola konten yang dimanipulasi oleh pengontrol dan ditampilkan oleh tampilan.

Pengontrol Anda harus bertanggung jawab untuk menghubungi API, basis data, layanan, dll ... yang meminta perubahan dan mengelola setiap pembaruan yang diperlukan untuk model.

Seluruh kekuatan pola MVC adalah bahwa ia memisahkan logika (pengontrol) dari tampilan dan keadaan (model). Dengan melakukan itu, Anda sekarang dijamin bahwa hanya kode dalam pengontrol yang dapat membuat efek samping karena tampilan dan model tidak diizinkan untuk melakukan perubahan.

Ini juga memungkinkan penggunaan kembali kode yang lebih baik karena model dapat dibagi antara berbagai pengontrol dan tampilan.

CLW
sumber
4
Saya pikir ketika Anda mengatakan "model" di sini, Anda merujuk ke "viewmodel", yang IMO adalah hal yang terpisah. Viewmodel mendapatkan data dari controller ke view, dan karena itu merupakan detail implementasi dari View, atau aspek komunikasi antara View dan Controller yang tidak benar-benar cocok dengan keduanya (tergantung bagaimana Anda melihatnya). "Model" dalam MVC mengacu pada model sistem - representasi dari sistem yang menggabungkan data, struktur, dan perilaku. Modelnya adalah keadaan dan logika; Pengontrol inilah yang menyebabkan logika dijalankan dan keadaan berubah ketika tampilan dimanipulasi.
anaximander
@anaximander Tidak, saya mengacu pada Model dalam interpretasi MVC yang cukup ketat (lihat Wikipedia, Microsoft MVC, pola Desain Kepala Pertama, dll ...) Dalam contoh tersebut Model tidak lebih dari sebuah struktur sederhana untuk meneruskan data sekitar dan tidak ada yang namanya viewmodel. Sementara implementasi Microsoft MVC memang menambahkan berbagai atribut ke model, ini lebih untuk kenyamanan daripada apa pun. Pada akhirnya tujuan dari pola MVC adalah untuk memfasilitasi praktik pemisahan kode yang baik dan membatasi efek samping.
CLW
1

Mungkin jauh di sini, tapi ini yang saya rasakan tentang WebApps dan bekerja dengan API kompleks [kompleks] dalam banyak kasus:

Saya akan menjadikannya kelas (yaitu, perpustakaan metode mitigasi data) alih-alih model (yaitu, tumpukan fungsi mitigasi data). Sepertinya itu akan bertindak lebih transparan, lebih logika / skema agnostik, dan Anda bisa menggunakannya di mana saja tanpa memuat-> memanggil model / controller itu sendiri setiap kali Anda ingin menggunakannya. Logikanya masih terpisah, datapoint masih fleksibel, dan tampaknya lebih terbuka untuk interoperabilitas dalam kasus-kasus aneh seperti menumpuk clientAJAX-> appJSON-> appLIB-> remoteAPI-> remoteJSON dll untuk polling titik akhir secara tidak langsung.

dhaupin
sumber