Validasi JSON Schema: Memvalidasi JSON di Node, Python, dan Browser (2026)
Singkatnya: JSON Schema adalah kontrak untuk data JSON. Anda mendeklarasikan tipe field, key wajib, dan batasan, lalu validator memeriksa apakah satu dokumen JSON mengikuti kontrak itu. Pakai Ajv di Node untuk validasi paling cepat, library jsonschema di Python untuk schema yang portabel, dan bundel Ajv di browser supaya form serta file konfigurasi memberi umpan balik seketika. Draft 2020-12 adalah pilihan default untuk proyek baru di 2026.
Halaman ini berisi contoh kerja paling kecil, pola end-to-end di ketiga runtime, dan jebakan nyata yang memunculkan bug “validasi lolos tapi production menolak data”.
Apa itu JSON Schema (dan apa yang bukan)
Definisi satu kalimat
JSON Schema adalah dokumen JSON yang menggambarkan bentuk dokumen JSON lain. Validator membaca schema dan datanya, lalu menyatakan dua hal cocok atau mengembalikan path yang gagal.
Contoh paling kecil yang sudah berguna:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": { "name": { "type": "string" } },
"required": ["name"]
}
{"name": "Alice"} lolos. {"age": 30} gagal karena name tidak ada. {"name": 42} gagal karena name bukan string. Sebatas itu model mentalnya.
JSON Schema vs validasi sintaks JSON
Dua masalah berbeda yang sering orang campur aduk.
| Dimensi | Pemeriksaan sintaks JSON | Validasi JSON Schema |
|---|---|---|
| Yang diperiksa | Apakah ini dokumen JSON yang sah? | Apakah JSON ini cocok dengan kontrak? |
| Menangkap | Koma hilang, kutip tunggal, komentar | Tipe salah, field wajib hilang, nilai di luar rentang |
| Tools | JSON.parse(), JSON Formatter | Ajv, jsonschema (Python), fastjsonschema |
| Kapan dipakai | Pertama, sebelum parsing | Tepat setelah parsing, sebelum business logic |
Anda biasanya melakukan keduanya: rapikan payload di JSON Formatter supaya yakin payload bisa di-parse, baru lewatkan ke schema supaya yakin payload cocok dengan kontrak.
JSON Schema vs JSONPath, JSON Patch, jq, dan TypeScript
Lima alat berbagi ruang masalah yang sama. Matriks pemilihannya:
| Alat | Pertanyaan yang dijawab | Pakai ketika |
|---|---|---|
| JSON Schema | Apakah JSON ini cocok dengan struktur yang diharapkan? | Validasi input API, file konfigurasi, payload form |
| JSONPath | Bagaimana cara meng-query nilai dari JSON ini? | Mengekstrak field bersarang, baca batch |
| JSON Patch (RFC 6902) | Bagaimana cara menggambarkan diff dari A ke B? | Editing kolaboratif, sinkronisasi inkremental |
| jq | Bagaimana cara memproses JSON di command line? | Skrip shell, pipeline log, pemeriksaan CI |
| Tipe TypeScript | Apakah kode saya menggunakan bentuk ini dengan benar? | Jaminan compile-time di dalam satu codebase |
Pemisah utamanya begini: JSON Schema memvalidasi data asing pada saat runtime, sementara TypeScript memvalidasi kode yang sudah Anda tulis pada saat compile. TypeScript tidak bisa apa-apa terhadap JSON dari webhook pihak ketiga atau hasil paste pengguna; di situlah JSON Schema masuk. Zod dan Pydantic menempati area tengah, yaitu tipe compile-time sekaligus validasi runtime, dan kita bahas di bawah.
JSON Schema vs OpenAPI
Salah kaprah yang umum adalah anggapan bahwa OpenAPI menggantikan JSON Schema. Tidak begitu. OpenAPI memakai JSON Schema secara internal untuk mendeskripsikan body request dan response, lalu menambahkan path, parameter, security scheme, dan URL server di atasnya. Schema adalah kontrak bentuk data; OpenAPI adalah kontrak API yang membungkusnya.
| Dimensi | JSON Schema | OpenAPI |
|---|---|---|
| Cakupan | Bentuk satu dokumen JSON | Bentuk seluruh HTTP API |
| Dependensi | Tidak ada (schema adalah JSON yang berdiri sendiri) | Mengimpor JSON Schema untuk definisi body |
| Pasangan versi | Draft 7 / Draft 2019-09 / Draft 2020-12 | OpenAPI 3.0 memakai subset Draft 4; OpenAPI 3.1 memakai Draft 2020-12 secara native |
| Penggunaan tipikal | File konfigurasi, envelope pesan, validasi form, kontrak payload tunggal | Desain REST API, generasi SDK, mock server, contract testing |
| Code generation | Terbatas (beberapa tools sekelas quicktype) | Ekosistem matang (openapi-generator, oapi-codegen, SDK vendor) |
| Manajemen kontrak | Satu file per bentuk, tanpa routing | Path, operation, alur auth, endpoint berversi dalam satu dokumen |
Pakai JSON Schema murni ketika artefak yang Anda urus adalah satu dokumen tunggal: payload webhook, file konfigurasi, pesan antrian, atau form. Tidak ada permukaan HTTP yang perlu dideskripsikan, jadi OpenAPI cuma menambah beban.
Pakai OpenAPI ketika Anda menerbitkan HTTP API dan ingin satu dokumen menggerakkan dokumentasi, generasi SDK, mock server, dan contract test. Definisikan schema Anda dulu sebagai file JSON Schema yang berdiri sendiri di direktori schemas/, lalu $ref dari dokumen OpenAPI. Pendekatan ini membuat schema tetap bisa dipakai ulang di luar konteks API.
Pasangan versi sering menjebak tim. OpenAPI 3.0 memakai subset Draft 4, jadi Anda tidak bisa memakai keyword Draft 2020-12 seperti prefixItems atau unevaluatedProperties di dalam dokumen 3.0; generator akan mengabaikannya tanpa peringatan. OpenAPI 3.1 adalah superset dari Draft 2020-12, jadi apa pun yang sah di 2020-12 sah di 3.1. Kalau Anda punya pilihan, targetkan OpenAPI 3.1 dan tulis schema Draft 2020-12 di mana-mana.
JSON Schema pertama Anda (5 menit)
Keyword yang paling dulu Anda butuhkan
Anda sudah menempuh 80% perjalanan dengan keyword berikut:
{
"type": "object",
"properties": {
"id": { "type": "integer", "minimum": 1 },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0, "maximum": 150 },
"tags": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
"role": { "enum": ["admin", "editor", "viewer"] },
"metadata": { "type": "object", "additionalProperties": true }
},
"required": ["id", "email"],
"additionalProperties": false
}
Kosakatanya:
type:string,number,integer,boolean,null,array,objectproperties+required: mendeklarasikan field dan menandai mana yang harus adaenum/const: membatasi ke set tetap atau ke satu literalminimum/maximum/multipleOf: batas numerikminLength/maxLength/pattern: panjang string dan regexminItems/maxItems/uniqueItems: bentuk arrayadditionalProperties: false: menolak key yang tidak Anda deklarasikan, dan kontrak input wajib selalu memasangnya
Contoh JSON Schema berdasarkan use case
Keyword di atas muncul dalam kombinasi yang berbeda tergantung apa yang Anda validasi. Beberapa bentuk representatif:
Body request API — endpoint signup yang menerima email dan password:
{
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" },
"password": { "type": "string", "minLength": 8, "maxLength": 128 }
},
"required": ["email", "password"],
"additionalProperties": false
}
File konfigurasi — config logger yang mengunci level ke set tetap:
{
"type": "object",
"properties": {
"level": { "enum": ["debug", "info", "warn", "error"] },
"output": { "type": "string", "default": "stdout" }
},
"required": ["level"],
"additionalProperties": false
}
Payload form dengan aturan kondisional — ketika accountType bernilai "business", taxId jadi wajib:
{
"type": "object",
"properties": {
"accountType": { "enum": ["personal", "business"] },
"taxId": { "type": "string" }
},
"if": { "properties": { "accountType": { "const": "business" } } },
"then": { "required": ["taxId"] }
}
Record JSON satu baris CSV — satu baris dari tabel order yang diekspor:
{
"type": "object",
"properties": {
"orderId": { "type": "string", "pattern": "^ORD-[0-9]{6}$" },
"orderedOn": { "type": "string", "format": "date" },
"totalUsd": { "type": "number", "minimum": 0 }
},
"required": ["orderId", "orderedOn", "totalUsd"]
}
Envelope event webhook — oneOf mendiskriminasi berdasarkan literal type, jadi setiap varian event punya bentuk payload sendiri:
{
"oneOf": [
{ "properties": { "type": { "const": "order.created" }, "data": { "$ref": "#/$defs/order" } } },
{ "properties": { "type": { "const": "order.refunded" }, "data": { "$ref": "#/$defs/refund" } } }
]
}
Lima contoh ini mencakup mayoritas dari yang ditulis tim dalam praktik. Salin yang paling cocok dan sesuaikan nama field-nya — kosakata keyword-nya tetap sama.
Validasi tanpa instal apa pun
Tempel schema dan payload Anda ke playground ajv.js.org atau jsonschemavalidator.net supaya dapat verdict seketika. Kalau JSON-nya sendiri terlihat mencurigakan, mampir dulu ke JSON Formatter.
Validasi di Node.js dengan Ajv
Instalasi dan contoh 12 baris
Ajv mengompilasi schema Anda menjadi function yang dioptimalkan pada panggilan compile pertama, lalu memakai ulang function itu.
npm install ajv
import Ajv from "ajv";
const ajv = new Ajv();
const schema = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "integer", minimum: 0 }
},
required: ["name"]
};
const validate = ajv.compile(schema);
const data = { name: "Alice", age: 30 };
if (!validate(data)) console.log(validate.errors);
else console.log("OK");
Beralih ke Draft 2020-12
Constructor Ajv default masih nempel ke Draft 7 demi kompatibilitas mundur. Pilih 2020-12 secara eksplisit:
import Ajv2020 from "ajv/dist/2020";
const ajv = new Ajv2020({ strict: true, allErrors: true });
Sekarang prefixItems, unevaluatedProperties, dan $dynamicRef siap dipakai. Lihat bagian Draft 2020-12 di bawah untuk fungsi masing-masing.
Mengaktifkan validasi format
Hal satu ini menjebak lebih banyak developer dibanding kekhasan Ajv mana pun: format: "email" secara default tidak melakukan apa-apa. Spesifikasi memperlakukan format sebagai advisory, jadi Anda harus mendaftarkan modul format-nya secara terpisah:
npm install ajv-formats
import addFormats from "ajv-formats";
addFormats(ajv); // sekarang "format": "email" benar-benar memvalidasi
Tanpa langkah ini, {"email": "not-an-email"} lolos dari schema yang minta format: "email". Untuk production, selalu pasang ajv-formats.
Middleware Express di lapangan
Satu validator per route, kompilasi saat boot:
import express from "express";
import Ajv2020 from "ajv/dist/2020";
import addFormats from "ajv-formats";
const ajv = new Ajv2020({ allErrors: true });
addFormats(ajv);
const validateUser = ajv.compile({
type: "object",
properties: {
email: { type: "string", format: "email" },
age: { type: "integer", minimum: 13 }
},
required: ["email"],
additionalProperties: false
});
const app = express();
app.use(express.json());
app.post("/users", (req, res) => {
if (!validateUser(req.body)) {
return res.status(400).json({ errors: validateUser.errors });
}
// ... business logic
res.status(201).json({ ok: true });
});
Kesalahan paling mahal yang sering muncul: memanggil ajv.compile(schema) di dalam request handler. Kompilasi sekali di scope modul, lalu pakai ulang function yang dia kembalikan. Kompilasi ulang per request menurunkan throughput 50 kali lipat atau lebih.
Validasi di Python dengan jsonschema
Instalasi dan penggunaan dasar
pip install jsonschema
from jsonschema import validate, ValidationError
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer", "minimum": 0}
},
"required": ["name"]
}
try:
validate(instance={"name": "Alice", "age": 30}, schema=schema)
print("OK")
except ValidationError as e:
print("FAIL:", e.message, "at", list(e.absolute_path))
Mengumpulkan semua error dengan Draft202012Validator
validate() melempar saat ketemu error pertama. Kalau Anda mau mendaftar semua masalah sekaligus, misalnya untuk response form, pakai iter_errors:
from jsonschema import Draft202012Validator
validator = Draft202012Validator(schema)
errors = sorted(validator.iter_errors(instance), key=lambda e: e.path)
for err in errors:
print(f" - {'/'.join(map(str, err.absolute_path))}: {err.message}")
Pengguna jadi bisa membenahi semuanya dalam satu kali, bukan bolak-balik per round trip.
jsonschema vs Pydantic: kapan pilih yang mana
Dua library Python yang sama-sama kuat, untuk dua masalah yang berbeda.
| Dimensi | jsonschema | Pydantic v2 |
|---|---|---|
| Format schema | Dict JSON (schema adalah data) | Class Python dengan type hints |
| Performa | Interpreted, ~10–100× lebih lambat dari Pydantic | Inti Rust, tercepat di ekosistemnya |
| Portabilitas lintas bahasa | Ya (schema sama berfungsi di JS, Go, Rust) | Tidak (hanya Python) |
| Integrasi FastAPI / model native | Konversi manual | Built-in |
Keyword Draft 2020-12 lengkap ($dynamicRef, dst.) | Lengkap | Sebagian |
Aturan yang lulus di production: pakai jsonschema untuk kontrak lintas bahasa seperti OpenAPI, API publik, dan webhook; pakai Pydantic untuk service Python internal. Banyak tim menjalankan keduanya, yaitu jsonschema di gateway untuk menegakkan kontrak dan Pydantic di lapisan aplikasi untuk business logic yang bertipe. Schema-nya adalah artefak portabel, persis sama dengan yang akan Anda umpankan ke Ajv.
Validasi di browser
Kenapa validasi di sisi klien
Ada tiga alasan, dari yang paling penting:
- UX. Umpan balik seketika saat pengguna mengetik mengalahkan round trip ke server.
- Bandwidth. Kesalahan yang sudah jelas tidak perlu sampai keluar dari browser.
- Higiene keamanan. Volume sampah ke backend berkurang, walaupun ini bukan pengganti validasi server.
Jangan pernah percaya cuma pada validasi sisi klien. Validasi lagi di server.
Membundel Ajv untuk browser
npm install ajv ajv-formats
import Ajv2020 from "ajv/dist/2020";
import addFormats from "ajv-formats";
const ajv = new Ajv2020({ allErrors: true });
addFormats(ajv);
export const validateForm = ajv.compile({
type: "object",
properties: {
email: { type: "string", format: "email" },
password: { type: "string", minLength: 8 }
},
required: ["email", "password"]
});
Bundle ini menambah sekitar 30 KB gzipped, jumlah yang lumayan tapi belum bencana. Tim biasanya memilih Ajv ketika mereka mau satu definisi schema yang sama dipakai di server dan di klien.
Alternatif yang lebih ringan: Zod dan Valibot
Kalau Anda tidak butuh ekosistem JSON Schema dan sudah berdiri di TypeScript, validator native TS memberi Anda bundle yang lebih kecil dan inferensi tipe yang lebih ketat:
import { z } from "zod";
const UserSchema = z.object({
email: z.string().email(),
password: z.string().min(8)
});
const result = UserSchema.safeParse(data);
if (!result.success) console.log(result.error.issues);
Valibot dikemas sekitar 3 KB gzipped dengan API yang mirip. Pilih opsi ini ketika ukuran bundle yang menentukan. Catatannya satu hal: tidak ada library di sini yang menghasilkan JSON Schema. Kalau Anda butuh satu sumber kebenaran yang dipakai bersama backend, klien pihak ketiga, atau generator OpenAPI, tetap di Ajv. Kalau semuanya TypeScript milik Anda sendiri, Zod dan Valibot lebih enak dipakai.
Yang ditambahkan Draft 2020-12
prefixItems untuk validasi tuple
Draft 7 mengungkapkan tuple lewat items: [] plus additionalItems. Draft 2020-12 memisahkannya dengan lebih rapi:
{
"type": "array",
"prefixItems": [
{ "type": "string" },
{ "type": "number" }
],
"items": false
}
["x", 42] lolos. ["x", 42, "extra"] gagal. Schema-nya berbunyi persis seperti perilakunya.
unevaluatedProperties untuk schema komposit
Bug kecil yang sering memakan tim pengguna allOf atau oneOf: additionalProperties: false cuma memeriksa pada level yang sama dengan tempat dia ditulis. Subschema sibling di dalam allOf bebas mendeklarasikan properti apa pun. Perbaikan ala 2020-12 adalah unevaluatedProperties: false:
{
"allOf": [
{ "$ref": "#/$defs/base" }
],
"unevaluatedProperties": false
}
Aturan ini menolak setiap properti yang tidak dievaluasi cabang mana pun, dan inilah perilaku yang sebenarnya diharapkan kebanyakan developer dari additionalProperties: false.
$dynamicRef untuk schema rekursif
Siapa pun yang pernah berusaha mendeklarasikan schema tree rekursif di Draft 7 tahu betapa rumitnya. $dynamicRef plus $dynamicAnchor merapikan itu:
{
"$dynamicAnchor": "node",
"type": "object",
"properties": {
"value": { "type": "string" },
"children": { "type": "array", "items": { "$dynamicRef": "#node" } }
}
}
Rekursinya jadi deklaratif, dan turunan boleh meng-override tanpa harus menulis ulang $id.
Draft 7 vs 2020-12: pilih yang mana
- Proyek baru, toolchain modern: Draft 2020-12.
- Membangun atau mengkonsumsi OpenAPI 3.1: 2020-12 adalah dialek nativenya.
- Bekerja dengan OpenAPI 3.0 atau service yang lebih lama: Draft 4 (OpenAPI 3.0 memakai subset Draft 4; jangan dicampur dialeknya).
- Butuh kompatibilitas validator yang luas, misalnya Postman atau tools CI lama: Draft 7 masih format pertukaran paling aman.
Hari ini, semua validator modern, mulai dari Ajv, Python jsonschema, jsonschema-rs, sampai networknt/json-schema-validator di Java, sudah mendukung 2020-12.
Pola di lapangan
Validasi input API
Middleware Express di atas adalah bentuk production-nya. Dua praktik tambahan: taruh semua schema di direktori schemas/ di root repo, dan tambahkan langkah CI yang menjalankan ajv test (atau ekuivalen Python-nya) untuk memvalidasi schema-nya sendiri terhadap meta-schema JSON Schema.
File konfigurasi
Visual Studio Code datang dengan integrasi SchemaStore yang memberi Anda autocomplete dan validasi inline untuk package.json, tsconfig.json, dan puluhan file lain. Tambahkan field $schema ke konfigurasi Anda sendiri, dan pengguna editor langsung dapat perlakuan yang sama.
Test fixture CI
Test fixture suka basi. Seseorang memperbarui satu model, fixture-nya tetap di bentuk lama, dan test tetap lolos karena assertion-nya tidak menyentuh field yang berubah. Tangkap kasus ini dengan pemeriksaan schema sebelum assertion berjalan:
import { glob } from "glob";
const files = await glob("__tests__/fixtures/*.json");
for (const f of files) {
const data = JSON.parse(await fs.readFile(f, "utf8"));
if (!validate(data)) throw new Error(`${f}: ${ajv.errorsText(validate.errors)}`);
}
Begitu pemeriksaan schema mulai bersuara, langkah selanjutnya biasanya adalah diff struktural. Tarik fixture-nya ke Bandingkan JSON Online terhadap sample production yang segar untuk melihat apa yang melenceng. Kalau timestamp dan ID mendominasi diff, terapkan pola path-ignore snapshot dari panduan JSON diff supaya sinyalnya bersih dari noise.
Payload webhook (Stripe, GitHub)
Webhook pihak ketiga adalah salah satu tempat paling berharga untuk memasang JSON Schema. Webhook itu kontrak, provider bisa mengubahnya, dan Anda ingin tahu kapan itu terjadi. Stripe dan GitHub menerbitkan deskripsi OpenAPI yang bisa Anda jadikan sumber JSON Schema. Validasi event yang masuk, dan upgrade yang merusak kompatibilitas akan menyalakan monitoring Anda, bukan diam-diam merusak state.
Validasi form berbasis schema
React Hook Form punya adapter @hookform/resolvers/ajv, dan VeeValidate di Vue punya plugin Ajv yang setara. Keduanya menggerakkan rendering form, pesan error, sampai validasi submission dari satu JSON Schema. Schema-nya jadi satu sumber kebenaran, dan UI ikut aturannya.
Pesan error yang ramah
Kenapa pesan default-nya kasar
Bawaan dari kotaknya, Ajv menghasilkan error seperti #/properties/email format must match "email". Cocok untuk engineer yang men-debug 400. Tidak berguna untuk pengguna yang mengisi form checkout.
ajv-errors untuk pesan kustom
npm install ajv-errors
import ajvErrors from "ajv-errors";
ajvErrors(ajv);
const schema = {
type: "object",
properties: { email: { type: "string", format: "email" } },
required: ["email"],
errorMessage: {
properties: { email: "Please enter a valid email address" },
required: { email: "Email is required" }
}
};
Keyword errorMessage tetap berada di dalam schema, jadi aturan validasi dan copy yang dilihat pengguna jalan berdampingan.
ajv-i18n untuk error yang diterjemahkan
ajv-i18n membawa terjemahan pesan default dalam 30 bahasa lebih. Cukup satu baris saat startup, dan validator Anda sudah berbicara Spanyol, Prancis, Jepang, atau locale apa pun yang Anda layani. Berguna sebagai fallback ketika override errorMessage Anda belum menutup semua batasan.
Memetakan path schema ke field form
Setiap error Ajv membawa instancePath seperti /users/0/email. Kebanyakan library form mengharapkan dotted path seperti users[0].email. Cukup satu baris:
const fieldPath = error.instancePath.replace(/^\//, "").replace(/\//g, ".");
Di jsonschema Python, ekuivalennya ada di error.absolute_path. Sambungkan dengan . untuk efek yang sama.
Lima jebakan yang lolos validasi tapi crash di production
1. format itu advisory secara default
Tanpa ajv-formats plus addFormats(ajv), setiap keyword format jadi no-op. {"format": "email"} rela menerima "not-an-email". Selalu pasang paket format di production.
2. additionalProperties default ke true
Tanpa additionalProperties: false, schema Anda menerima setiap field yang belum Anda deklarasikan. Klien bisa mengirim field tambahan yang melewati validasi mentah-mentah. Jadikan additionalProperties: false sebagai default pada kontrak input, lalu longgarkan secara sengaja kalau memang perlu.
3. additionalProperties tidak komposisi
Di dalam allOf, oneOf, atau anyOf, additionalProperties: false cuma memeriksa properti pada level dia sendiri. Subschema sibling tetap lolos. Perbaikan dari Draft 2020-12 adalah unevaluatedProperties: false.
4. $ref remote itu risiko production
$ref: "https://example.com/schema.json" memaksa Ajv menarik schema lewat jaringan pada compile pertama. Konsekuensinya: latensi, paparan DoS kalau host remote-nya macet, dan permukaan serangan MITM. Inline-kan semua target $ref atau muat dari disk saat build time.
5. Schema generated melenceng dari data nyata
Tools seperti quicktype dan typescript-json-schema menghasilkan schema dari tipe yang sudah ada. Output-nya biasanya terlalu longgar; setiap field opsional, additionalProperties terbuka. Perlakukan schema generated sebagai draft, perketat manual, dan jalankan CI yang memvalidasi sample production yang nyata terhadap schema (dan sebaliknya) supaya melencengnya ketahuan cepat.
Performa: angka dan aturan praktis
- Ajv (Node.js): validator yang sudah dikompilasi menuntaskan satu pemeriksaan jauh di bawah satu mikrodetik. Inilah validator JS production-grade paling cepat yang tersedia.
jsonschema(Python): interpreted, 10 sampai 100 kali lebih lambat dari Pydantic. Ganti kefastjsonschemakalau angka itu mulai menyiksa; ia menghasilkan kode Python dan kecepatannya mendekati Ajv.- Rust dan Go:
jsonschema-rsdanxeipuuv/gojsonschemamemberi Anda 2 sampai 5 kali kecepatan Ajv di tier gateway. - Kemenangan tunggal terbesar: precompile.
ajv.compile(schema)sekali saat module load, lalu pakai ulang validator-nya pada setiap request. Kompilasi ulang per request membunuh throughput sampai 50 kali lipat atau lebih.
Pertanyaan yang sering diajukan
Apa itu validasi JSON Schema dalam bahasa sederhana?
Validasi JSON Schema memeriksa apakah dokumen JSON mengikuti suatu kontrak. Kontraknya, yaitu schema-nya, sendiri berbentuk JSON dan mendeklarasikan tipe, field wajib, dan batasan. Validator membaca schema beserta datanya lalu melapor “lolos” atau menunjuk path yang gagal beserta alasannya.
Bagaimana cara memvalidasi JSON terhadap schema secara online?
Tempel schema dan datanya ke playground ajv.js.org atau jsonschemavalidator.net untuk verdict seketika. Kalau JSON-nya kelihatan malformed, bersihkan dulu di JSON Formatter Online Gratis; semuanya berjalan di browser, tanpa upload.
Validator JSON Schema mana yang paling cepat di 2026?
Di Node, Ajv dengan validator yang sudah dikompilasi menuntaskan satu pemeriksaan di bawah satu mikrodetik. Di Python, fastjsonschema menghasilkan kode dan mencapai throughput sekelas Ajv. Di tier gateway, jsonschema-rs (Rust) dan gojsonschema (Go) 2 sampai 5 kali kecepatan Ajv. Pilih yang mana pun, precompile sekali, lalu pakai ulang.
Apa beda JSON Schema dan tipe TypeScript?
TypeScript memeriksa kode yang Anda tulis pada saat compile. JSON Schema memeriksa JSON asing pada saat runtime. TypeScript tidak bisa melihat JSON yang datang dari respons HTTP, file, atau hasil paste pengguna; di situlah JSON Schema bekerja.
Pakai Draft 2020-12 atau Draft 7?
Untuk proyek baru di 2026, pilih Draft 2020-12. prefixItems, unevaluatedProperties, dan $dynamicRef benar-benar memecahkan masalah nyata. OpenAPI 3.1 memakai 2020-12 secara native. Tetap di Draft 7 cuma kalau Anda butuh kompatibilitas Postman atau service lama. OpenAPI 3.0 memakai subset Draft 4; jangan campur dialeknya.
Bagaimana cara menghasilkan JSON Schema dari JSON yang sudah ada?
Ada tiga opsi: tempel sample ke quicktype.io atau jsonschema.net, jalankan npx genson-js atau pip install genson && genson sample.json di command line, atau tulis sendiri. Schema yang dihasilkan otomatis biasanya terlalu longgar (setiap field opsional, additionalProperties: true), jadi selalu perketat dulu sebelum dia diperlakukan sebagai kontrak.
Apakah JSON Schema bisa menggantikan OpenAPI?
Tidak. OpenAPI memakai JSON Schema secara internal untuk mendeskripsikan body request dan response, lalu menambahkan path, security scheme, parameter, dan URL server. Keduanya berkomposisi: tulis schema Anda, referensikan dari dokumen OpenAPI, dan Anda dapat kontrak API yang lengkap.
Apakah JSON Schema sama dengan JSONPath atau jq?
Masalahnya berbeda. JSON Schema memvalidasi struktur (“apakah JSON ini cocok dengan kontrak?”). JSONPath dan Cheat Sheet jq mengekstrak nilai (“semua nama pod yang berada di fase Running”). Validasi pakai schema, query pakai JSONPath atau jq.
Kenapa validasi Ajv saya lolos tapi production menolak datanya?
Tiga penyebab mencakup hampir semua kasus: Anda lupa ajv-formats sehingga format: "email" tidak pernah memvalidasi, Anda menghilangkan additionalProperties: false sehingga field klien tambahan menyelinap masuk, atau Anda memakai additionalProperties: false di dalam allOf atau oneOf lalu sadar dia tidak berkomposisi. Beralih ke unevaluatedProperties: false.
Apakah saya bisa menyesuaikan pesan error JSON Schema untuk pengguna akhir?
Bisa. Di Node, pasang ajv-errors supaya errorMessage tertanam di dalam schema, dan ajv-i18n untuk terjemahan di 30 locale lebih. Di Python, jsonschema membuka konteks validasi penuh pada setiap objek error, sehingga Anda bisa memetakan tipe error plus path ke copy apa pun yang dipakai design system Anda.