Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. JSON
Code

Memvalidasi Data dengan JSON-skema, Bagian 2

by
Difficulty:AdvancedLength:LongLanguages:
This post is part of a series called Validating Data With JSON-Schema.
Validating Data With JSON-Schema, Part 1

Indonesian (Bahasa Indonesia) translation by Fajar Bahri (you can also view the original English article)

Dalam bagian pertama dari tutorial ini, Anda belajar bagaimana untuk membuat skema lanjutan yang menggunakan semua kata kunci validasi yang tersedia. Banyak contoh real-wordl JSON data lebih kompleks daripada contoh penggunaan kami. Upaya untuk menempatkan semua persyaratan untuk data tersebut dalam satu file dapat mengakibatkan skema yang sangat besar juga mungkin memiliki banyak duplikasi.

Penataan skema Anda

JSON-skema standar memungkinkan Anda untuk memecahkan skema menjadi beberapa bagian. Mari kita lihat contoh data untuk navigasi situs berita:

Struktur navigasi di atas agak mirip dengan salah satu yang dapat Anda lihat di situs web http://dailymail.co.uk. Anda dapat melihat contoh yang lebih lengkap dalam repositori GitHub.

Struktur data kompleks dan rekursif, tetapi skema menggambarkan data ini cukup sederhana:

navigation.json:

pate.json:

defs.JSON:

Silahkan lihat skema di atas dan data navigasi yang mereka menggambarkan (itu valid menurut skema navigation.json). Hal utama yang harus perhatikan adalah bahwa skema navigation.json referensi ke skema page.json yang pada gilirannya referensi yang pertama.

Kode JavaScript untuk memvalidasi reocrd pengguna terhadap skema bisa menjadi:

Semua kode sampel tersedia dalam repositori GitHub.

Ajv, validator yang digunakan dalam contoh, adalah validator JSON-skema tercepat untuk JavaScript. Saya membuat itu, jadi saya akan menggunakannya dalam tutorial ini. Kita akan melihat bagaimana membandingkan dengan validator lain pada akhirnya sehingga Anda dapat memilih mana yang tepat untuk Anda.

Tugas

Lihat bagian 1 dari tutorial untuk petunjuk tentang cara untuk menginstal repositori dengan tugas dan untuk menguji jawaban Anda.

Referensi antara skema dengan kata kunci "$ref"

JSON-skema standar memungkinkan Anda untuk menggunakan kembali berulang-ulang bagian skema menggunakan referensi dengan kata kunci "$ref". Seperti yang Anda lihat dari contoh navigasi, Anda dapat referensi skema yang terletak di:

  • dalam file lain: menggunakan skema URI yang didefinisikan dalam properti "id"
  • dalam setiap bagian dari file lain: menambahkan JSON pointer ke referensi skema
  • dalam setiap bagian dari skema saat ini: menambahkan JSON pointer ke "#"

Anda juga dapat merujuk ke skema seluruh saat ini menggunakan "$ref" sama dengan "#"-memungkinkan Anda untuk membuat skema rekursif merujuk kepada diri mereka sendiri.

Jadi, dalam contoh kita, skema navigation.json merujuk kepada:

  • skema page.json
  • definitions dalam skema defs.json
  • positiveIntOrNull definisi dalam skema yang sama

Skema di page.json merujuk ke:

  • kembali ke skema navigation.json
  • juga untuk definitions dalam file defs.json

Standar memerlukan bahwa "$ref" harus menjadi satu-satunya properti di objek, jadi jika Anda ingin menerapkan skema yang direferensikan selain lain skema, Anda harus menggunakan kata kunci "allOf".

Tugas 1

Refactor schema pengguna dari bagian 1 dari tutorial menggunakan referensi. pisahkan skema dalam di dua file yang terpisah: user.json dan connection.json.

Tempatkan skema Anda dalam file part2/task1/user.json dan part2/task1/connection.json dan jalankan node part2/task1/validate untuk memeriksa jika skemanya benar.

JSON-Pointer

JSON-pointer adalah standar yang menentukan path ke bagian file JSON. Standar ini dijelaskan dalam RFC6901.

path ini terdiri dari segmen (bisa dapat string apapun) terhubung dengan karakter "/". Jika segmen berisi karakter "~" atau "/", mereka harus diganti dengan "~ 0" dan "~1". Masing-masing segmen berarti properti atau index di JSON data.

Jika Anda melihat contoh navigasi, "$ref" yang mendefinisikan properti color adalah "defs.json#/definitions/color", yang dimana "defs.json#" adalah skema URI dan "/definitions/color" JSON pointer. Ini menunjuk kepada color properti dalam definitions properti.

Konvensi adalah untuk menempatkan semua bagian dari skema yang digunakan dalam refs dalam properti definitions skema (seperti yang Anda lihat dalam contoh). Meskipun standar JSON-skema definitions kata kunci untuk tujuan ini, itu tidak diperlukan untuk menempatkan subschemas Anda di sana. JSON-pointer memungkinkan Anda untuk merujuk pada setiap bagian dari JSON file.

Ketika pointer JSON yang digunakan dalam URI, semua karakter yang tidak valid dalam URI harus di escape (dalam JavaScript encodeURIComponent fungsi global dapat digunakan).

JSON-pointer dapat digunakan tidak hanya di JSON-skema. Mereka dapat digunakan untuk mewakili path di JSON data untuk setiap properti atau item. Anda dapat menggunakan perpustakaan json-pointer ke untuk mengakses objek dengan JSON-pointer.

Tugas 2

File JSON di bawah menggambarkan struktur folder dan file (nama folder dimulai dengan "/"):

Apa adalah petunjuk JSON yang mengarah ke:

  • ukuran aplikasi "Word",
  • ukuran "my_story ~ .rtf" dokumen,
  • nama aplikasi kedua yang dapat membuka "my_story ~ .rtf" dokumen?

Letakkan jawaban Anda dalam part2/task2/json_pointers.json dan menjalankan node part2/task2/validate untuk memeriksanya.

Skema id

Skema ini biasanya memiliki properti top-level "id" yang memiliki skema URI. Ketika "$ref" yang digunakan dalam skema, nilainya diperlakukan sebagai URI yang diselesaikan relatif untuk skema "id".

Resolusi bekerja dalam cara yang sama seperti browser menyelesaikan URI yang tidak mutlak-mereka teratasi relatif untuk skema URI yang berada di properti "id". Jika "$ref" adalah nama file, akan menggantikan nama di "id". Dalam contoh navigasi, id skema navigasi adalah "http://mynet.com/schemas/navigation.json#", sehingga ketika referensi "page.json#" diselesaikan, URI lengkap dari halaman skema menjadi "http://mynet.com/schemas/page.json#" (itu adalah "id" dari skema page.json).

Jika "$ref" halaman skema dimana pathnya, misalnya "/page.json", kemudian itu akan telah diselesaikan sebagai "http://mynet.com/page.json#". Dan "/folder/page.json" akan diselesaikan sebagai "http://mynet.com/folder/page.json#".

Jika "$ref" dimulai dari karakter "#", itu dianggap sebagai sebuah fragmen hash dan ditambahkan ke path di "id" (menggantikan hash fragmen di dalamnya). Dalam contoh navigasi, rujukan "defs.json#/definitions/color" diselesaikan sebagai "http://mynet.com/schemas/defs.json#/definitions/color" dimana "http://mynet.com/schemas/defs.json#" ID dari definisi skema dan "/definitions/color" diperlakukan sebagai pointer JSON di dalamnya.

Jika "$ref" URI lengkap dengan nama domain yang berbeda, dalam cara yang sama link bekerja di browser, itu telah diselesaikan sebagai full URI yang sama .

Skema internal id

JSON-skema standar memungkinkan Anda untuk menggunakan "id" dalam skema untuk mengidentifikasi subschemas ini dan juga untuk mengubah URI dasar relatif didalam referensi akan diselesaikan — itu disebut "changing resolution scope". Itu mungkin adalah salah satu bagian paling membingungkan dari standar, dan itulah sebabnya mengapa tidak sangat umum digunakan.

Saya tidak akan merekomendasikan banyak over menggunakan ID internal, dengan satu pengecualian di bawah ini, untuk dua alasan:

  • Sangat sedikit validator konsisten mengikuti standar dan benar menyelesaikan referensi ketika internal id yang digunakan (Ajv sepenuhnya mengikuti standar di sini).
  • Skema menjadi lebih sulit untuk dipamahami.

Kami masih akan melihat cara kerjanya karena Anda mungkin mengalami skema yang menggunakan ID internal dan ada kasus ketika menggunakan mereka membantu dengan penataan skema Anda.

Pertama, mari kita lihat contoh navigasi. Sebagian besar referensi dalam objek definitions dan membuat referensi menjadi cukup panjang. Ada cara untuk mempersingkat mereka dengan menambahkan id untuk definisi. Ini adalah skema defs.json yang diperbarui:

Sekarang daripada referensi "defs.json#/definitions/positiveInteger" dan "defs.json#/definitions/color" yang digunakan dalam navigasi dan halaman skema, Anda dapat menggunakan referensi pendek: "defs.json#positiveInteger" dan "defs.json#color". Itu adalah sangat umum penggunaan internal id karena memungkinkan Anda untuk membuat referensi Anda lebih pendek dan lebih mudah dibaca. Harap dicatat bahwa sementara kasus sederhana ini akan ditangani dengan benar oleh kebanyakan JSON-skema validator, beberapa dari mereka mungkin tidak mendukung itu.

Mari kita lihat contoh yang lebih rumit dengan id. Berikut adalah contoh JSON skema:

Pada baris yang sangat sedikit, menjadi sangat membingungkan. Lihatlah contoh dan mencoba untuk mencari tahu mana properti harus string dan mana yang integer.

Skema mendefinisikan sebuah objek dengan prppoerti bar, baz dan bax. properti bar harus menjadi sebuah obyek yang valid menurut subschema, yang mengharuskan agar foo properti yang valid menurut referensi "bar". Karena subschema memiliki "id" sendiri, URI lengkap untuk referensi akan menjadi "http://somewhere.else/completely.json#bar", Jadi seharusnya integer.

Sekarang perhatikan properti baz dan bax. Referensi untuk mereka ditulis dalam cara yang berbeda, tetapi mereka menunjukkan ke referensi sama "http://somewhere.else/completely.json#bar" dan mereka berdua harus bilangan bulat. Meskipun properti baz menunjuk secara langsung kepada skema {"$ref": "#bar"}, masih harus diselesaikan relatif terhadap ID dari subschema karena di dalamnya. Jadi obyek dibawah valid menurut skema ini:

Banyak JSON skema validator tidak akan menangani dengan benar, dan itu sebabnya id yang mengubah cakupan resolusi harus digunakan dengan hati-hati.

Tugas 3

Memecahkan teka-teki ini akan membantu Anda lebih memahami bagaimana referensi dan mengubah resolusi lingkup pekerjaan. Skema adalah:

Menciptakan suatu objek yang valid menurut skema ini.

Letakkan jawaban Anda dalam part2/task3/valid_data.json dan menjalankan node part2/task3/validate untuk memeriksanya.

Memuat referensi skema

Sampai sekarang kita sedang melihat merujuk kepada ke skema yang berbeda satu sama lain tanpa memperhatikan bagaimana dimuat ke validator skema yang berbeda.

Satu pendekatan adalah untuk memiliki semua skema terhubung dimuat seperti kita memiliki contoh navigasi di atas. Tapi ada situasi ketika baik tidak praktis atau mungkin-misalnya, jika Anda perlu menggunakan skema yang disediakan oleh aplikasi lain, atau jika Anda tidak tahu di muka semua skema mungkin yang mungkin diperlukan.

Dalam kasus tersebut, validator dapat memuat skema yang direferensikan pada saat Kapan data di divalidasi. Tapi itu akan membuat proses validasi menjadi lambat. Ajv memungkinkan Anda untuk menyusun skema ke dalam fungsi valiasi asynchronously memuat referensi skema dalam proses Validasi itu sendiri akan tetap synchronous dan cepat.

Misalnya, jika skema navigasi yang tersedia untuk men-download dari URI di id mereka, kode untuk memvalidasi data terhadap skema navigasi ini dapat:

Kode yang mendefinisikan fungsi validateNavigation yang memuat skema dan mengkompilasi fungsi validasi ketika dipanggil pertama kalinya dan selalu mengembalikan hasil validasi melalui callback. Ada berbagai cara untuk memperbaikinya, dari preloading dan menyusun skema secara terpisah, sebelum digunakan pertama kali, akuntansi untuk fakta bahwa fungsi dapat disebut beberapa kali sebelum itu berhasil cache schema (ajv.compileAsync sudah memastikan bahwa skema selalu diminta hanya sekali).

Sekarang kita akan melihat kata kunci baru yang diusulkan untuk versi 5 JSON-skema standar.

JSON-skema versi 5 proposal

Meskipun proposal tersebut belum dirampungkan sebagai draft standar, mereka dapat digunakan hari ini — Ajv validator menerapkan mereka. Mereka secara substansial memperluas apa yang Anda dapat validasi menggunakan JSON-skema, jadi patuh dicoba.

Untuk menggunakan kata kunci dengan Ajv, Anda perlu menggunakan opsi v5: true.

Kata kunci "constant" dan "contains"

Kata kunci ini ditambahkan untuk kenyamanan.

Kata kunci "constant" memerlukan data setara dengan nilai kata kunci. Tanpa kata kunci ini, itu bisa dicapai dengan kata kunci "enum" dengan satu item dalam array elemen.

Skema ini memerlukan data sama dengan 1:

Kata kunci "contains" mensyaratkan bahwa beberapa elemen array sesuai skema kata kunci ini. Kata kunci ini berlaku untuk array jenis data lainnya akan berlaku hal itu. Sedikit lebih sulit untuk mengekspresikan persyaratan ini menggunakan hanya kata kunci dari versi 4, tapi mungkin.

Skema ini memerlukan jika data adalah sebuah array maka setidaknya salah satu item adalah integer:

Hal ini setara dengan satu ini:

Untuk skema ini berlaku, baik data tidak harus array atau tidak seharusnya semua item haris non-integer (yaitu beberapa item harus integer).

Harap dicatat bahwa kata kunci "contains" dan skema yang setara di atas akan gagal jika data array kosong.

Kata kunci "patternGroups"

Kata kunci ini diusulkan sebagai pengganti untuk "patternProperties". Hal ini memungkinkan Anda untuk membatasi jumlah properti yang cocok dengan pola yang harus ada dalam objek. Ajv mendukung keduanya "patternGroups" dan "patternProperties" dalam v5 mode karena yang pertama lebih verbose, dan jika Anda tidak ingin membatasi jumlah properti Anda mungkin lebih suka menggunakan yang kedua.

Misalnya skema:

sama dengan skema ini:

Mereka keduanya memerlukan objek hanya memiliki properti dengan kunci yang hanya terdiri dari lowercase huruf dengan nilai-nilai tipe string dan dengan kunci yang terdiri dari angka dengan nilai-nilai dari nomor tipe. Mereka tidak memerlukan sejumlah properti tersebut, atau apakah mereka membatasi jumlah maksimum. Itulah apa yang dapat Anda lakukan dengan "patternGroups":

Skema di atas memiliki persyaratan tambahan: harus ada setidaknya satu properti yang cocok pola masing-masing dan tidak lebih dari tiga properti kunci yang mengandung hanya huruf.

Anda tidak dapat mencapai yang sama dengan "patternProperties".

Kata kunci untuk membatasi nilai yang diformat "formatMaximum" / "formatMaximum"

Kata kunci tersebut bersama-sama dengan "exclusiveFormatMaximum" / "exclusiveFormatMinimum" memungkinkan Anda untuk mengatur batas waktu, tanggal dan berpotensi lain nilai string yang memiliki format yang diperlukan dengan kata kunci "format".

Skema ini memerlukan bahwa datanya tanggal dan lebih besar dari atau sama dengan 1 Januari 2016:

Ajv mendukung perbandingan data yang diformat untuk format "tanggal", "waktu" dan "tanggal-waktu", dan Anda dapat menentukan format kustom yang akan mendukung batas dengan "formatMaximum" / "formatMaximum" kata kunci.

Kata kunci "switch"

Sementara semua kata kunci yang sebelumnya memungkinkan Anda untuk lebih baik apa itu mungkin tanpa mereka atau sedikit memperluas kemungkinan, mereka tidak mengubah sifat deklaratif dan statis schema. Kata kunci ini memungkinkan Anda untuk membuat validasi dinamis dan bergantung pada data. Ini berisi beberapa if-then kasus.

Lebih mudah untuk menjelaskan dengan sebuah contoh:

Skema diatas secara berurutan memvalidasi data melawan subschemas di "if" kata kunci sampai salah satu dari mereka sukses memvalidasi. Ketika itu terjadi, itu memvalidasi skema "then" kata kunci dalam objek yang sama — yang akan menjadi hasil dari validasi seluurh skema. Jika nilai "then" false, validasi segera gagal.

Dengan cara ini, skema di atas memerlukan bahwa nilai adalah:

  • lebih besar dari atau sama dengan 50 dan perkalian 5
  • atau antara 10 dan 49 dan perkalian dari 2
  • atau antara 5 dan 9

Set persyaratan tertentu dapat dinyatakan tanpa kata kunci switch, tetapi ada kasus-kasus yang lebih kompleks ketika hal ini tidak mungkin.

Tugas 4

Membuat schema sama dengan contoh terakhir di atas tanpa menggunakan kata kunci switch.

Letakkan jawaban Anda dalam part2/task4/no_switch_schema.json dan menjalankan node part2/task4/validate untuk memeriksanya.

Kasus-kasus kata kunci "switch" juga dapat berisi kata kunci "continue" dengan nilai boolean. Jika nilai ini true, validasi akan berlanjut setelah sukses "if" skema sesuai dengan sukses "then" skema validasi. Itu serupa dengan fall-through ke kasus selanjutnya dalam JavaScript switch pernyataan, meskipun dalam JavaScript fall-throught perilaku default dan kata kunci "switch" memerlukan instruksi eksplisit "continue". Ini adalah contoh sederhana lain dengan instruksi "continue":

Jika "if" yang pertama kondisinya puas dan persyaratan "then" bertemu, validasi akan terus memeriksa kondisi kedua.

referensi "$data"

"$data" kata kunci lebih meluas apa yang mungkin dengan JSON-skema dan membuat validasi lebih dinamis dan bergantung pada data. Hal ini memungkinkan Anda untuk menempatkan nilai-nilai dari beberapa data properti, item, atau key ke kata kunci skema tertentu.

Sebagai contoh, skema ini mendefinisikan sebuah objek dengan dua properti yang mana jika keduanya didefinisikan, "larger" harus lebih besar dari atau sama dengan "smaller"-nilai dalam "smaller" digunakan sebagai minimum untuk "larger":

Ajv menerapkan referensi "$data" untuk kebanyakan kunci, nilai-nilai yang tidak skema. Validasi gagal jika "$data" referensi menunjuk ke jenis yang tidak sesuai dan berhasil jika ia menunjuk kepada nilai undefined (atau jika path tidak ada dalam objek).

Jadi apa nilai string dalam rujukan "$data"? Kelihatannya mirip dengan JSON-pointer tapi itu tidak persis. Hal ini relatif JSON-pointer yang didefinisikan oleh rancangan standar ini.

Ini terdiri dari nomor integer yang mendefinisikan berapa kali lookup harus melintasi atas objek (1 dalam contoh di atas berarti direnct parent) diikuti oleh "#" atau JSON pointer.

Jika nomor diikuti oleh "#" maka nilai JSON-pointer ditetapkan ke nama properti atau index dari item objek. Dengan cara ini, "# 0" tempat "1/smaller" akan menyelesaikan ke string "larger", dan "1#" akan menjadi tidak valid karena seluruh data bukanlah anggota dari setiap objek atau array. Skema ini:

sama dengan satu ini:

karena {"$data": "0#"} diganti dengan nama properti.

Jika nomor di pointer diikuti oleh JSON-pointer, maka ini JSON-pointer diselesaikan mulai dari objek parent nomor ini merujuk kepada. Anda dapat melihat cara kerjanya dalam contoh pertama "smaller" / "larger".

Mari kita lihat lagi contoh navigasi. Salah satu persyaratan yang dapat Anda lihat dalam data adalah bahwa properti page_id dalam halaman objek selalu sama dengan properti parent_id dalam objek terkandung navigasi. Kita dapat mengungkapkan persyaratan ini dalam skema page.json yang menggunakan referensi "$data":

Kata kunci "switch" yang ditambahkan ke halaman skema memerlukan bahwa jika objek halaman memiliki properti navigation maka nilai properti page_id harus sama dengan nilai properti parent_id dalam objek navigasi. Yang sama dapat dicapai tanpa kata kunci "swtich", tapi kurang ekspresif dan berisi duplikasi:

Tugas 5

Contoh JSON-pointer relatif dapat membantu.

Menggunakan kata kunci v5, mendefinisikan skema untuk objek dengan dua prpoerti yang diperlukan list dan order. list harus menjadi sebuah array yang memiliki hingga lima angka. Semua item harus nomor dan mereka harus beurutan di ascending atau descending, sebagaimana ditentukan oleh order properti yang bisa jadi "asc" atau "desc".

Sebagai contoh, ini adalah sebuah objek yang berlaku:

dan ini tidak valid:

Letakkan jawaban Anda dalam part2/task5/schema.json dan menjalankan node part2/task5/validate untuk memeriksanya.

Bagaimana Anda akan membuat skema dengan kondisi yang sama tetapi untuk daftar yang berukuran tak terbatas?

Mendefinisikan kata kunci baru validasi

Kita telah melihat kata kunci baru yang diusulkan untuk versi 5 JSON-skema standar. Anda dapat menggunakan mereka hari ini, tapi kadang-kadang Anda mungkin ingin lebih. Jika Anda melakukan tugas 5, Anda mungkin telah memperhatikan bahwa beberapa persyaratan sulit untuk mengungkapkan dengan JSON-skema.

Beberapa validator, termasuk Ajv, memungkinkan Anda untuk menentukan kata kunci kustom. Kustom kata kunci:

  • memungkinkan Anda untuk membuat skenario validasi yang tidak dapat diungkapkan menggunakan JSON-skema
  • menyederhanakan skema Anda
  • membantu Anda untuk membawa bagian besar dari logika validasi skema Anda
  • membuat skema Anda lebih ekspresif, kurang verbose dan lebih dekat ke domain aplikasi

Salah satu pengembang yang menggunakan Ajv menulis pada GitHub:

"ajv dengan kata kunci kustom telah membantu kami banyak dengan validasi logika bisnis dalam backend kami. Kami konsolidasi sejumlah controller-level validasi ke JSON-skema dengan kata kunci kustom. Efek bersih jauh jauh lebih baik daripada menulis kode validasi individu."

kepentingan Anda harus menyadari ketika memperluas JSON-skema standar dengan kata kunci kustom adalah portabilitas dan pemahaman tentang skema Anda. Anda akan memiliki untuk mendukung kata kunci tersebut kustom pada platform lainnya dan didokumentasikan dengan baik oleh kata kunci tersebut sehingga semua orang dapat memahami mereka dalam skema Anda.

Pendekatan yang terbaik di sini adalah untuk menentukan meta-skema baru yang akan menjadi perpanjangan dari rancangan meta-skema 4 atau "v5 proposal" meta-skema yang akan mencakup validasi kedua kata kunci tambahan dan deskripsi mereka. Maka skema anda yang menggunakan kata kunci kustom tersebut akan harus mengatur $schema properti ke URI dari meta-skema yang baru.

Sekarang bahwa Anda sudah diperingatkan, kita akan menyelam dan menetapkan beberapa kata kunci kustom yang menggunakan Ajv.

Ajv menyediakan empat cara untuk menetapkan custom kata kunci yang dapat Anda lihat di dokumentasi. Kita akan melihat dua dari mereka:

  • menggunakan fungsi yang mengkompilasi skema fungsi validasi
  • menggunakan makro-fungsi yang mengambil skema dan kembali skema lain (dengan atau tanpa kata kunci kustom)

Mari kita mulai dengan contoh sederhana dari berbagai kata kunci. Berbagai adalah hanya kombinasi dari minimum dan maksimum kata kunci, tetapi jika Anda harus menentukan rentang banyak dalam skema, terutama jika mereka memiliki batas-batas yang eksklusif, mungkin ini dapat dengan mudah menjadi membosankan.

Itulah bagaimana skema harus terlihat:

di mana berbagai eksklusif opsional, tentu saja. Kode untuk menentukan kata kunci ini di bawah ini:

Dan hanya itu! Setelah kode ini Anda dapat menggunakan range kata kunci dalam skema Anda:

Objek yang dikirimkan ke addKeyword adalah definisi kata kunci. Opsional mengandung tipe (atau jenis sebagai array) kata kunci yang berlaku untuk. Fungsi kompilasi disebut dengan schema parameter dan parentSchema dan harus mengembalikan fungsi lain yang memvalidasi data. Yang membuatnya hampir sebagai efisien sebagai kata kunci asli, karena skema diteliti selama kompilasi, tapi ada biaya panggilan fungsi tambahan selama validasi.

Ajv memungkinkan Anda untuk menghindari overhead ini dengan kata kunci yang mengembalikan kode (sebagai string) yang akan dijadikan bagian dari fungsi validasi, tetapi sudah cukup kompleks sehingga kita tidak akan melihatnya di sini. Cara sederhana adalah dengan menggunakan kata kunci makro-Anda akan memiliki untuk mendefinisikan fungsi yang mengambil skema dan mengembalikan skema lain.

Berikut ini adalah implementasi berbagai kata kunci dengan fungsi makro:

Anda dapat melihat bahwa fungsi hanya mengembalikan skema baru yang setara dengan range kata kunci yang menggunakan kata kunci maximum dan minimum.

Mari kita juga melihat bagaimana kita dapat membuat meta-skema yang akan mencakup range kata kunci. Kita akan menggunakan rancangan 4 meta-skema sebagai titik awal kita:

Jika Anda ingin menggunakan referensi "$data" dengan range kata kunci, Anda akan untuk memperpanjang "v5 proposal" meta-skema yang termasuk dalam Ajv (Lihat link di atas) sehingga rujukan-rujukan ini dapat nilai-nilai range dan exclusiveRange. Dan sementara implementasi pertama kami tidak akan mendukung referensi "$data", yang kedua dengan makro-fungsi akan mendukung mereka.

Sekarang bahwa Anda memiliki meta-skema, Anda perlu untuk menambahkannya ke Ajv dan menggunakannya dalam skema menggunakan range kata kunci:

Kode di atas akan melemparkan exception jika nilai tidak valid kita akan memasukan kepada range atau exclusiveRange.

Tugas 6

Asumsikan bahwa Anda telah mendefinisikan jsonPointers kata kunci yang berlaku skema untuk prpoerti mendalam yang didefinisikan oleh JSON pointer yang mengarah ke data mulai dari satu saat ini. Kata kunci ini berguna dengan kata kunci switch karena memungkinkan Anda untuk menentukan persyaratan dalam properti dan item. Sebagai contoh, skema ini menggunakan kata kunci jsonPointers:

sama dengan:

Asumsikan bahwa Anda juga telah mendefinisikan requiredJsonPointers kata kunci yang bekerja mirip required tetapi dengan JSON-pointer bukan properti.

Jika Anda suka, Anda dapat menentukan kata kunci tersebut sendiri juga, atau Anda dapat melihat bagaimana mereka didefinisikan dalam file part2/task6/json_pointers.js.

Tugas Anda adalah: menggunakan kata kunci jsonPointers dan requiredJsonPointers, mendefinisikan select kata kunci yang mirip dengan JavaScript switch pernyataan dan memiliki sintaks berikut (othwerwise dan fallthrough adalah opsional):

Sintaks ini memungkinkan nilai-nilai dari jenis apa pun. Harap dicatat bahwa fallthrough berbeda dari continue dalam kata kunci switch. fallthrough menerapkan skema dari kasus selanjutnya pada data tanpa memeriksa bahwa selectpr sama dengan nilai dari kasus selanjutnya (seperti itu kemungkinan tidak sama).

Letakkan jawaban Anda dalam part2/task6/select_keyword.js dan part2/task6/v5-meta-with-select.json dan menjalankan node part2/task6/validate untuk memeriksa mereka.

Bonus 1: Meningkatkan implementasi Anda untuk mendukung sintaks ini:

Dapat digunakan jika semua nilai string yang berbeda dan  tidak ada fallthrough.

Bonus 2: memperpanjang "v5 proposal" meta-skema untuk memasukkan kata kunci ini.

Penggunaan JSON-skema lainnya

Selain memvalidasi data, JSON-skema dapat digunakan untuk:

  • generate UI
  • generate data
  • mengubah data

Anda dapat melihat perpustakaan yang generate UI dan data jika Anda tertarik. Kami tidak akan menjelajahi itu seperti berada di luar cakupan tutorial ini.

Kita akan menggunakan JSON-skema untuk memodifikasi data sementara itu divalidasi.

Menyaring Data

Salah satu tugas umum sementara memvalidasi data menghapus properti tambahan dari data. Hal ini memungkinkan Anda untuk membersihkan data sebelum memasukan ke logika pengolahan tanpa menggagalkan validasi skema:

Tanpa removeAdditional pilihan, validasi pasti gagal, karena ada bar properti tambahan yang tidak diperkenankan oleh skema. Dengan opsi ini, validasi akan sukses dan properti akan dihapus dari objek.

Ketika nilai pilihan removeAdditional true, properti tambahan akan dihapus hanya jika kata kunci additionalProperties false. Ajv juga memungkinkan Anda untuk menghapus semua properti tambahan, terlepas dari additionalProperties kata kunci, atau properti tambahan yang dapat menggagalkan validasi (jika kata kunci additionalProperties adalah skema). Silahkan lihat di dokumentasi Ajv untuk informasi lebih lanjut.

Menetapkan default ke properti dan item

Standar JSON-skema mendefinisikan kata kunci "default" yang berisi nilai data harus jika tidak didefinisikan dalam data yang divalidasi. Ajv memungkinkan Anda untuk menetapkan default tersebut dalam proses validasi:

Tanpa useDefaults pilihan, validasi pasti gagal, karena tidak ada bar diperlukan properti di objek yang divalidasi. Dengan opsi ini, validasi sukses dan properti dengan nilai default yang ditambahkan ke objek.

Coercing Tipe Data

"type" adalah salah satu kata kunci yang paling sering digunakan dalam JSON-skema. Ketika Anda adalah memvalidasi input pengguna, semua properti data Anda yang Anda dapatkan dari form yang biasanya string. Ajv memungkinkan Anda untuk memaksa data jenis yang ditentukan dalam skema, baik untuk mensukseskan validasi dan menggunakan data yang diketik dengan benar setelah itu:

Membandingkan JavaScript JSON-skema validator

Ada lebih dari sepuluh aktif didukung JavaScript validator yang tersedia. Mana yang harus Anda gunakan?

Anda dapat melihat tolok ukur kinerja dan dari betapa berbedanya validator yang sukses ke tes suite dari standar JSON-skema dalam proyek json-schema-benchmark.

Ada juga fitur unik yang memiliki beberapa validator yang dapat membuat mereka yang paling cocok untuk proyek Anda. Saya akan membandingkan beberapa dari mereka di bawah ini.

is-my-json-valid dan jsen

Dua Validator ini sangat cepat dan memiliki antarmuka yang sangat sederhana. Keduanya menyusun skema untuk fungsi JavaScript, seperti halnya Ajv.

Kelemahan mereka adalah bahwa mereka berdua memiliki terbatas dukungan dari referensi.

schemasaurus

Ini adalah one-of-a-kind Perpustakaan dimana JSON-skema validasi adalah hampir efek samping.

Hal ini dibangun sebagai generik dan mudah extensible JSON-skema prosesor/iterator yang dapat Anda gunakan untuk membangun segala macam tool yang menggunakan JSON-skema: UI Generator, template, dll.

Itu sudah memiliki relatif cepat validator JSON-skema yang disertakan.

Tidak mendukung referensi sama sekali, bagaimanapun.

themis

Paling lambat dalam kelompok cepat validator, memiliki seperangkat fitur, dengan dukungan terbatas dari referensi.

dimana itu benar-benar bersinar adalah implementasi kata kunci default. Sementara mayoritas validator memiliki dukungan ini kata kunci (Ajv bukanlah pengecualian) terbatas, Themis memiliki logika yang sangat kompleks menerapkan default dengan rollbacks dalam campuran Keyword seperti anyOf.

z-schema

Performa-cerdas, validator sangat matang ini terletak di perbatasan antara validator cepat dan lambat. Mungkin itu salah satu yang tercepat sebelum generasi baru dikompilasi validator muncul (semua hal di atas dan Ajv).

Melewati hampir semua tes dari JSON-skema uji suite untuk validator, dan memiliki cukup teliti pelaksanaan referensi.

Ini memiliki sejumlah pilihan yang memungkinkan Anda untuk men-tweak perilaku default banyak kata kunci JSON-skema (misalnya, tidak menerima array kosong sebagai array atau kosong set string) dan untuk memaksakan persyaratan tambahan pada JSON skema (misalnya, memerlukan kunci minLength untuk string).

Saya berpikir bahwa dalam kebanyakan kasus, memodifikasi perilaku skema maupun termasuk permintaan untuk layanan lainnya dalam JSON-skema adalah hal yang salah untuk dilakukan. Tapi ada kasus-kasus ketika kemampuan untuk melakukannya menyederhanakan banyak.

tv4

Ini adalah salah satu tertua (dan lambat) validator yang mendukung versi 4 standar. Dengan demikian hal ini sering pilihan default untuk banyak proyek.

Jika Anda menggunakan itu, sangat penting untuk memahami bagaimana ini laporan kesalahan dan referensi yang hilang dan untuk mengkonfigurasi dengan benar, jika tidak Anda akan mendapatkan banyak positif palsu (yaitu, validasi sukses dengan data tidak valid atau belum terselesaikannya remote referensi).

Format tidak disertakan secara default, tetapi mereka tersedia sebagai sebuah perpustakaan yang terpisah.

Ajv

Saya menulis Ajv karena semua validator yang ada cepat atau sesuai dengan standar (terutama mengenai mendukung referensi) tetapi tidak keduanya. Ajv mengisi kekosongan.

Pada saat itu adalah hanya validator yang:

  • melewati semua tes dan sepenuhnya mendukung referensi
  • mendukung validasi kunci diusulkan untuk versi 5 referensi standar dan $data
  • validasi asinkron mendukung format kustom dan kata kunci

Juga memiliki option untuk memodifikasi proses validasi dan untuk mengubah data yang di divalidasi (penyaringan, menetapkan default dan coercing jenis — Lihat contoh di atas).

Validator  apa yang akan digunakan?

Saya pikir pendekatan yang terbaik adalah untuk mencoba beberapa dan memilih salah satu yang terbaik bagi Anda.

Saya menulis json-schema-consolidate, yang memasok koleksi adapter yang menyatukan antarmuka dari 12 validator JSON-skema. Menggunakan tool ini Anda dapat menghabiskan waktu sedikit saat pindah antara validator. Saya merekomendasikan menghapus itu sekali Anda telah memutuskan validator yang digunakan, seperti menjaga itu akan berdampak negatif pada kinerja.

Hanya itu! Saya berharap tutorial ini berguna. Anda telah belajar tentang:

  • Penataan skema Anda
  • menggunakan referensi dan id
  • menggunakan kata kunci validasi dan $data referensi dari versi 5 proposal
  • loading remote skema asynchronously
  • mendefinisikan kata kunci kustom
  • memodifikasi data dalam proses validasi
  • keuntungan dan kerugian dari berbagai JSON-skema validator

Terima kasih sudah membaca!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.