Latar belakang
Setelah bertemu di banyak tempat dalam pengembangan Javascript dengan situasi di mana perlu untuk memvalidasi nilai, menjadi jelas bahwa perlu untuk entah bagaimana menyelesaikan masalah ini. Untuk tujuan ini, tugas berikut telah ditetapkan:
Kembangkan perpustakaan yang akan memungkinkan:
- memvalidasi tipe data ;
- atur nilai default sebagai ganti bidang atau elemen yang tidak valid;
- hapus bagian yang tidak valid dari suatu objek atau array;
- Terima pesan kesalahan
Dasarnya adalah:
- Mudah dipelajari
- Keterbacaan kode yang diterima.
- Kemudahan modifikasi kode
Untuk mencapai tujuan ini, perpustakaan validasi kuartet telah dikembangkan.
Batu bata validasi dasar
Inti dari sebagian besar sistem yang dirancang agar dapat diterapkan dalam berbagai tugas adalah elemen paling sederhana: tindakan, data, dan algoritma. Serta metode komposisi mereka - untuk mengumpulkan sesuatu yang lebih rumit dari elemen sederhana untuk menyelesaikan masalah yang lebih kompleks.
Validator
Pustaka kuartet didasarkan pada konsep validator . Validator di perpustakaan ini adalah fungsi dari formulir berikut
function validator( value: any, { key: string|int, parent: any }, { key: string|int, parent: any }, ... ): boolean
Ada beberapa hal dalam definisi ini yang harus dijelaskan secara lebih rinci:
function(...): boolean
- mengatakan bahwa validator - menghitung hasil validasi, dan hasil validasi adalah nilai boolean - benar atau salah , masing-masing valid atau tidak valid
value: any
- menunjukkan bahwa validator - menghitung hasil validasi nilai , yang bisa berupa nilai javascript apa pun. Validator baik menetapkan nilai yang divalidasi menjadi valid atau tidak valid.
{ key: string|int, parent: any }, ...
- menunjukkan bahwa nilai yang divalidasi dapat berada dalam konteks yang berbeda tergantung pada level apa dari nesting nilainya. Mari kita tunjukkan dengan contoh
Nilai contoh tanpa konteks apa pun
const value = 4;
Nilai contoh dalam konteks array
Nilai contoh dalam konteks objek
const obj = { a: 1, b: 2, c: value, d: 8 }
Karena struktur dalam suatu objek dapat memiliki sarang yang lebih besar, masuk akal untuk berbicara tentang berbagai konteks
const arrOfObj = [{ a: 1, b: 2, c: value, d: 8 },
Dan sebagainya.
Tentang kesamaan dengan metode arrayDefinisi validator ini harus mengingatkan Anda tentang definisi fungsi yang dilewatkan sebagai argumen ke metode array, seperti: peta, filter, beberapa, setiap , dll.
- Argumen pertama untuk fungsi-fungsi ini adalah elemen array.
- Argumen kedua adalah indeks elemen.
- Argumen ketiga adalah array itu sendiri.
Validator dalam hal ini adalah fungsi yang lebih umum - ia mengambil tidak hanya indeks elemen dalam array dan array, tetapi juga indeks array - dalam induk dan induknya, dan seterusnya.
Apa yang harus kita bangun rumah?
Batu bata yang dijelaskan di atas tidak menonjol di antara "solusi batu" lainnya yang tergeletak di "pantai" kruk javascript. Karena itu, mari kita membangun dari mereka, sesuatu yang lebih koheren dan menarik. Untuk ini kami memiliki komposisi .
Bagaimana cara membangun validasi gedung pencakar langit?
Setuju, akan lebih mudah untuk memvalidasi objek sedemikian rupa sehingga deskripsi validasi cocok dengan deskripsi objek. Untuk ini kita akan menggunakan komposisi objek validator . Ini terlihat seperti ini:
Seperti yang Anda lihat, dari batu bata validator berbeda yang ditentukan untuk bidang tertentu, kita dapat mengumpulkan validator objek - beberapa "bangunan kecil", yang masih cukup ramai - tetapi lebih baik daripada tanpa itu. Untuk ini, kami menggunakan komposer validator v
. Setiap kali, bertemu objek literal v
di tempat validator, itu akan menganggapnya sebagai komposisi objek, mengubahnya menjadi validator objek di bidangnya.
Terkadang kami tidak dapat menjelaskan semua bidang . Misalnya, ketika suatu objek adalah kamus data:
const quartet = require('quartet') const v = quartet() const isStringValidator = name => typeof name === 'string' const keyValueValidator = (value, { key }) => value.length === 1 && key.length === 1 const dictionarySchema= { dictionaryName: isStringValidator, ...v.rest(keyValueValidator) } const compositeObjValidator = v(dictionarySchema) const obj = { dictionaryName: 'next letter', b: 'c', c: 'd' } const isObjValid = compositeObjValidator(obj) console.log(isObjValid)
Bagaimana cara menggunakan kembali solusi konstruksi?
Seperti yang kita lihat di atas, ada kebutuhan untuk menggunakan kembali validator sederhana. Dalam contoh ini, kami sudah harus menggunakan "validator tipe string" sudah dua kali.
Untuk mempersingkat catatan dan meningkatkan keterbacaannya, pustaka kuartet menggunakan sinonim string validator. Setiap kali komposer validator menemukan string di tempat validator seharusnya, itu mencari kamus untuk validatornya dan menggunakannya .
Secara default, validator paling umum sudah ditentukan di perpustakaan.
Perhatikan contoh-contoh berikut:
v('number')(1)
dan banyak lainnya yang dijelaskan dalam dokumentasi .
Setiap lengkungan memiliki jenis batu bata sendiri?
Komposer validator (fungsi v
) juga merupakan pabrik validator. Dalam artian itu mengandung banyak metode berguna yang kembali
- validator fungsi
- nilai yang akan dirasakan oleh komposer sebagai skema untuk membuat validator
Sebagai contoh, mari kita lihat validasi array: paling sering terdiri dari memeriksa tipe array dan memeriksa semua elemennya. Kami akan menggunakan metode v.arrayOf(elementValidator)
untuk ini. Misalnya, ambil array poin dengan nama.
const a = [ {x: 1, y: 1, name: 'A'}, {x: 2, y: 1, name: 'B'}, {x: -1, y: 2, name: 'C'}, {x: 1, y: 3, name: 'D'}, ]
Karena array poin adalah array objek, masuk akal untuk menggunakan komposisi objek untuk memvalidasi elemen array.
const namedPointSchema = { x: 'number',
Sekarang, menggunakan metode pabrik v.arrayOf
, buat validator untuk seluruh array.
const isArrayValid = v.arrayOf({ x: 'number', y: 'number', name: 'string' })
Mari kita lihat bagaimana validator ini bekerja:
isArrayValid(0)
Ini hanyalah salah satu metode pabrik, yang masing-masing dijelaskan dalam dokumentasi.
Seperti yang Anda lihat di atas, v.rest
juga merupakan metode pabrik yang mengembalikan komposisi objek yang memeriksa semua bidang yang tidak ditentukan dalam komposisi objek. Itu berarti dapat tertanam dalam komposisi objek lain menggunakan spread-operator
.
Mari kita kutip sebagai contoh penggunaan beberapa di antaranya:
Menjadi, atau tidak menjadi?
Sering terjadi bahwa data yang valid mengambil berbagai bentuk, misalnya:
id
bisa berupa angka, atau bisa berupa string.- Objek
point
mungkin atau mungkin tidak mengandung beberapa koordinat, tergantung pada dimensi. - Dan banyak kasus lainnya.
Untuk mengatur validasi varian, disediakan jenis komposisi yang berbeda - komposisi varian. Ini diwakili oleh array validator dari opsi yang memungkinkan. Suatu objek dianggap valid ketika setidaknya satu validator melaporkan validitasnya.
Pertimbangkan contoh dengan validasi pengidentifikasi:
const isValidId = v([ v.and('not-empty', 'string'),
Contoh validasi poin:
const isPointValid = v([ {
Jadi, setiap kali seorang komposer melihat sebuah array, ia akan menganggapnya sebagai komposisi elemen validator dari array ini sedemikian rupa sehingga ketika salah satu dari mereka menganggap nilai valid, perhitungan validasi akan berhenti dan nilai tersebut akan diakui sebagai valid.
Seperti yang kita lihat, komposer menganggap tidak hanya fungsi validator sebagai validator, tetapi juga segala sesuatu yang dapat mengarah pada fungsi validator.
Jenis Validator | Contoh | Seperti yang dirasakan oleh komposer |
---|
fungsi validasi | x => typeof x === 'bigint' | hanya memanggil nilai-nilai yang diperlukan |
komposisi objek | { a: 'number' } | membuat fungsi validator untuk objek berdasarkan validator bidang yang ditentukan |
Komposisi varian | ['number', 'string'] | Membuat fungsi validator untuk memvalidasi nilai dengan setidaknya satu opsi |
Hasil Panggilan Metode Pabrik | v.enum('male', 'female') | Sebagian besar metode pabrik mengembalikan fungsi validasi (dengan pengecualian v.rest , yang mengembalikan komposisi objek), sehingga mereka diperlakukan seperti fungsi validasi biasa |
Semua opsi validator ini valid dan dapat digunakan di mana saja dalam skema di mana validator seharusnya berada.
Akibatnya, skema kerja selalu seperti ini: v(schema)
mengembalikan fungsi validasi. Selanjutnya, fungsi validasi ini dipanggil pada nilai-nilai spesifik:
v(schema)(value[, ...parents])
Pernahkah Anda mengalami kecelakaan di lokasi konstruksi?
- Belum, belum satu
- Mereka akan!
Kebetulan data tidak valid dan kami harus dapat menentukan penyebab tidak valid.
Untuk ini, perpustakaan kuartet menyediakan mekanisme penjelasan . Terdiri dari fakta bahwa dalam kasus ketika validator, baik internal maupun eksternal, mendeteksi validitas data yang diverifikasi, ia harus mengirim catatan penjelasan .
Untuk tujuan ini, argumen kedua komposer validator v
. Itu menambahkan efek samping dari mengirim catatan penjelasan ke array v.explanation
dalam kasus data tidak valid.
Contoh, mari kita memvalidasi array, dan ingin mencari tahu jumlah semua elemen yang tidak valid dan nilainya:
Seperti yang Anda lihat, pilihan penjelasan tergantung pada tugas. Kadang-kadang bahkan tidak perlu.
Terkadang kita perlu melakukan sesuatu dengan bidang yang tidak valid. Dalam kasus seperti itu, masuk akal untuk menggunakan nama bidang yang tidak valid sebagai penjelasan :
const objSchema = { a: v('number', 'a'), b: v('number', 'b'), c: v('string', 'c') } const isObjValid = v(objSchema) let invalidObj = { a: 1, b: '1', c: 3 } isObjValid(invalidObj)
Dengan mekanisme penjelasan ini, Anda dapat menerapkan perilaku apa pun yang terkait dengan hasil validasi.
Penjelasan bisa berupa apa saja:
- sebuah objek yang berisi informasi yang diperlukan;
- fungsi yang memperbaiki kesalahan. (
getExplanation => function(invalid): valid
); - nama bidang tidak valid, atau indeks elemen tidak valid;
- kode kesalahan
- dan semua itu sudah cukup untuk imajinasi Anda.
Apa yang harus dilakukan ketika segala sesuatu tidak dibangun?
Memperbaiki kesalahan validasi bukanlah tugas yang jarang. Untuk tujuan ini, perpustakaan menggunakan validator dengan efek samping yang mengingat tempat kesalahan dan cara memperbaikinya.
v.default(validator, value)
- mengembalikan validator yang mengingat nilai yang tidak valid, dan pada saat memanggil v.fix
- menetapkan nilai defaultv.filter(validator)
- mengembalikan validator yang mengingat nilai yang tidak valid, dan pada saat memanggil v.fix
- menghapus nilai ini dari induknyav.addFix(validator, fixFunc)
- mengembalikan validator yang mengingat nilai yang tidak valid, dan pada saat memanggil v.fix
- memanggil fixFunc dengan parameter (nilai, {key, parent}, ...). fixFunc
- harus bermutasi salah satu mitra - untuk mengubah nilai
const toPositive = (negativeValue, { key, parent }) => { parent[key] = -negativeValue } const objSchema = { a: v.default('number', 1), b: v.filter('string', ''), c: v.default('array', []), d: v.default('number', invalidValue => Number(invalidValue)),
Pekerjaan masih berguna
Ada juga metode utilitas untuk tindakan validasi di perpustakaan ini:
Metode | Hasil |
---|
v.throwError | Jika tidak valid, lempar TypeError dengan pesan yang diberikan. |
v.omitInvalidItems | Mengembalikan array baru (atau objek kamus) tanpa elemen (bidang) yang tidak valid. |
v.omitInvalidProps | Mengembalikan objek baru tanpa bidang yang tidak valid, sesuai dengan validator objek yang ditentukan. |
v.validOr | Mengembalikan nilai jika valid, jika tidak maka akan menggantinya dengan nilai default yang ditentukan. |
v.example | Cek apakah nilai yang diberikan sesuai dengan skema. Jika mereka tidak cocok, kesalahan dilemparkan. Berfungsi sebagai dokumentasi dan pengujian sirkuit |
Hasil
Tugas diselesaikan dengan cara-cara berikut:
Tantangan | Solusi |
---|
Validasi Jenis Data | Validator bernama default. |
Nilai default | v.default |
Menghapus bagian yang tidak valid | v.filter , v.omitInvalidItems dan v.omitInvalidProps . |
Mudah dipelajari | Validator sederhana, cara sederhana untuk menyusunnya menjadi validator yang kompleks. |
Keterbacaan kode | Salah satu tujuan perpustakaan adalah menyamakan skema validasi itu sendiri |
benda yang divalidasi. |
Kemudahan modifikasi | Setelah menguasai elemen komposisi dan menggunakan fungsi validasi Anda sendiri - mengubah kodenya cukup sederhana. |
Pesan kesalahan | Penjelasan dalam bentuk pesan kesalahan. Atau perhitungan kode kesalahan berdasarkan penjelasan. |
Kata penutup
Solusi ini dirancang untuk membuat fungsi validator dengan cepat dan mudah dengan kemampuan untuk menyematkan fungsi validasi khusus. Karena itu, jika ada, koreksi, kritik, dan opsi perbaikan dari mereka yang membaca artikel ini dipersilakan. Terima kasih atas perhatian anda