Mengelola validasi sisi klien dan sisi server di satu tempat

17

Saya 100% di papan dengan kasus yang satu harus pasti menggunakan kedua sisi klien dan validasi data server-side.

Namun, dalam kerangka dan lingkungan tempat saya bekerja, pendekatan yang saya lihat tidak pernah KERING. Sebagian besar waktu tidak ada rencana atau pola - validasi ditulis dalam spesifikasi model, dan validasi ditulis dalam bentuk pada tampilan. (Catatan: Sebagian besar pengalaman tangan pertama saya adalah dengan Rails, Sinatra, dan PHP dengan jQuery)

Memikirkan hal itu, sepertinya tidak akan sulit untuk membuat generator yang, mengingat serangkaian validasi (misalnya nama model, bidang, kondisi), dapat menghasilkan materi sisi klien dan sisi server yang diperlukan. Sebagai alternatif, alat tersebut dapat mengambil validasi sisi-server (seperti validateskode dalam model ActiveRecord) dan menghasilkan validasi sisi-klien (seperti plugin jQuery, yang kemudian akan diterapkan ke formulir.

Jelas, di atas hanyalah "hei aku punya ide" merenung, dan bukan proposal formal. Hal semacam ini tentunya lebih sulit daripada yang terlihat ketika ide itu mengenai saya.

Itu membawa saya ke pertanyaan: Bagaimana pendekatan Anda merancang teknik "tulis sekali, jalankan di server dan klien" untuk validasi data?

Subtopik terkait: Apakah alat seperti itu ada untuk kerangka kerja tertentu atau teknologi client-server? Apa tantangan atau tantangan utama dengan mencoba mempertahankan hanya satu set validasi?

asfallows
sumber

Jawaban:

6

Dalam pengalaman saya yang terbatas, poin di mana validasi diperlukan adalah

  1. Tingkat presentasi menggunakan HTML,
  2. di tingkat pasca-presentasi (yaitu, validasi Javascript),
  3. pada tingkat kombinasi di mana interaksi antara berbagai bidang harus divalidasi bersama,
  4. di tingkat logika bisnis dan
  5. di tingkat basis data.

Masing-masing dari mereka memiliki bahasa, pengaturan waktu, dan pemicu yang berbeda. Misalnya, tidak masuk akal untuk memvalidasi bidang sebelum seluruh catatan dalam keadaan konsisten, kecuali jika Anda ingin memvalidasi hanya satu bagian. Kendala pada tingkat database harus dapat diterapkan hanya pada akhir sebelum komit, dan tidak dapat dengan mudah dilakukan sepotong demi sepotong.

Konsep terkait adalah bahwa merepresentasikan data bervariasi antara masing-masing level. Contoh sederhana adalah browser web mewakili sepotong teks sebagai, mungkin, CP1290, sementara database merepresentasikannya dalam UTF-8; panjang dari dua string berbeda sehingga menegakkan batasan panjang menjadi canggung.

BobDalgleish
sumber
ya, bahasa dan kerangka kerja yang berbeda membuat ini tidak praktis. Bukan "undoable" karena dengan sumber daya yang cukup bisa dilakukan tetapi mengirimkan konverter otomatis ke dan antar bahasa adalah tugas yang BESAR. Melakukannya dalam jangka waktu yang masuk akal dan kemudian mempertahankannya seiring perubahan teknologi yang relevan akan banyak pekerjaan.
Michael Durrant
Memang benar bahwa banyak validasi sisi server (mis. Keunikan bidang) tidak dapat dilakukan di browser. Namun, juga benar bahwa validasi sisi klien perlu diulang di server, karena Anda tidak dapat mempercayai klien. Di situlah saya melihat KERING menjadi sangat berguna. Sebagai contoh, saya dapat melihat permata yang memperluas Rails ' form_foruntuk secara otomatis memberikan kode validasi sisi klien yang sangat berguna.
Dan
5

Satu pertimbangan yang sering membatasi solusi adalah perjalanan pulang-pergi jaringan. Klien seharusnya memvalidasi data pengguna tanpa mengirim pesan melalui jaringan. Dengan kata lain, ketika pengguna menekan tombol kirim, klien seharusnya memvalidasi data secara lokal.

Pertama, mari kita asumsikan bahwa kita tidak memiliki batasan ini. Kami dapat berkomunikasi dengan titik akhir jaringan yang bagus dalam mengartikulasikan masalah validasi. Misalnya, ketika Anda mengirimkan catatan Pengguna baru Anda ke sana, daripada merespons dengan kode kesalahan HTTP vanilla, itu bisa mengembalikan respons JSON terperinci yang merinci masalah dan klien akan dengan cerdas memperbarui tampilan untuk mencerminkan masalah yang ditemui. Titik akhir memainkan peran gateway validasi.

KERING tetapi tidak tanpa kekurangan. Pertama, itu tergantung pada jaringan pulang pergi mengenakan pajak server kami dengan validasi yang bisa ditangani pihak klien. Kedua, desain mengantisipasi bahwa semua operasi CRUD akan terjadi melalui titik akhir kami, tetapi bagaimana dengan saat pengembang dan proses memotong lapisan akses data kami dengan langsung terhadap basis data ?

Mari kita kembali solusi kami untuk mengatasi kekurangan ini. Alih-alih, mari simpan dan komunikasikan validasi kami sebagai metadata:

{field: 'username', type: 'required'}
{field: 'username', type: 'unique'} //requires a network roundtrip
{field: 'password', type: 'length', min: 10, max: 50}
{field: 'password', type: 'contains', characters: ['upper', 'special', 'letter', 'number']}

Baik klien dan server akan memiliki beberapa mekanisme (misalnya mesin) untuk menafsirkan dan menerapkan data ini. (Ada yang menyebut ini monad gratis karena memisahkan bagian deklaratif dari penerjemahnya.) Dalam JavaScript kita bisa memetakan setiap informasi untuk fungsi yang berfungsi. Untuk mem-boot, kita dapat mengajarkan semua lapisan arsitektur kita, termasuk basis data kita, untuk menegakkan validasi secara konsisten.

Mario T. Lanza
sumber
Bagaimana Anda menggambarkan suatu bidang ketika suatu bidang direpresentasikan secara berbeda di browser web, transportasi, bahasa implementasi, dan basis data? Misalnya, jumlah byte yang diperlukan untuk mewakili bidang string bervariasi saat menggunakan CP1290 (IE), UTF-8 (JSON), UTF-8 (C #), atau UCS-16 (Oracle). Apa arti batasan panjang? Lebih penting untuk browser, ketika representasi karakter tergantung pada browser dan sistem operasi?
BobDalgleish
Kendala ini ditujukan sebagai model mental pada manusia. Tugas Anda sebagai seorang programmer adalah mengabstraksi perbedaan-perbedaan pada mesin sehingga orang tersebut tidak perlu peduli dengan perbedaan teknis apa pun.
Mario T. Lanza
Anda benar-benar melewatkan intinya. Sejauh ini, tidak ada yang menyajikan abstraksi yang memungkinkan validasi dari ujung ke ujung, dengan satu spesifikasi. Dari OP, "menulis sekali" menyiratkan bahwa memiliki klausa yang berbeda yang membahas tahapan yang berbeda tidak memenuhi syarat. Demikian pula, saya tidak melihat apa pun dalam validasi yang diajukan yang membahas validasi antar-bidang atau antar-objek.
BobDalgleish
Validasi antar bidang / objek tidak banyak peregangan. Metadata hanya mewakili hubungan. Write sekali menyiratkan bahwa saya menulis validasi tunggal sekali dan memilikinya diberlakukan di beberapa situs, yang ini tidak. Anda menambahkan metadata ke tabel. Metadata itu diterima oleh situs mana pun dan kelas / utilitas / mesin sederhana memberlakukan batasan tersebut.
Mario T. Lanza
1
Bahasa validasi seperti itu akan sangat berguna. Itu bisa menggantikan mungkin sepertiga dari kode yang terlibat dengan aplikasi web intensif UI.
BobDalgleish
2

Salah satu caranya adalah dengan menggunakan bahasa / kerangka kerja yang sama di sisi server dan klien.

Misalnya

Node.js :: Klien / Server dalam JavaScript GET :: Klien / Server di Jawa

Dalam hal ini, sebagian besar kode "Objek Domain" akan menjadi umum, yang akan mencakup validasi. Kerangka kerja akan meminta kode seperti yang diperlukan. Misalnya kode yang sama akan dipanggil di browser sebelum "kirim" dan pada layanan web sisi server.

EDIT (Juni / 2014): Dengan Java 8, sekarang juga mudah untuk mengintegrasikan kode validasi JS di Aplikasi Java. Java 8 memiliki mesin eksekusi JS baru yang lebih permanen (Misalnya: menggunakan invokeDynamic).

Shamit Verma
sumber
Ketika datang ke database SQL tidak yakin bagaimana ini akan berhasil.
Michael Durrant
Itu juga tidak memecahkan masalah bahwa browser dan sistem operasi mempengaruhi domain input.
BobDalgleish
@Micheal Durrant, Untuk validasi Database diimplementasikan sebagai batasan DB (seperti kunci asing, unik, dll). BobDalgleish, 1. Masalah kompatibilitas browser / OS dapat dikurangi dengan menggunakan Perpustakaan yang mengubah runtime menurut Browser (seperti Sencha) 2. Kompatibilitas browser secara sually tidak berdampak pada bagian kode "logis" seperti validasi, masalah kompatibilitas biasanya sekitar DOM / UI Rendering.
Shamit Verma
0

Saya hanya memikirkan masalah yang sama. Saya sedang berpikir untuk menggunakan ANTLR untuk mendapatkan pohon sintaksis abstrak di C # dan javascript. Dari sana Anda menggunakan walker pohon untuk menerapkan tindakan yang ditentukan dalam bahasa ke objek yang akan divalidasi.

Jadi, Anda bisa menyimpan deskripsi validasi yang diperlukan di mana pun Anda suka - mungkin dalam database.

Inilah cara saya mendekati masalah.

Marcus
sumber