المشكلة
JSON.parse بيقبل أي شكل، والـ TS types بتختفي وقت التشغيل، وas T مش validationالحلJSON Schema = عقد مكتوب JSON، والـ validator (Ajv) يراجع عند كل trust boundary
الـ trust boundariesAPI bodies، webhooks، config، queues، ردود الـ LLM، localStorage، بيانات DB قديمة
الـ import
ajv = draft-07، وajv/dist/2020.js = 2020-12، ولازم يتفقوا مع $schemaالـ types
string number integer boolean null object array، و5.0 integerيقبل null
type: ["string", "null"]، ومفيش nullable بره OpenAPI 3.0حقل إجباري
required: [...] في الـ object، مش جوه الحقلحقول زيادة
additionalProperties: false للـ input، ومفتوح للبيانات اللي بتتطورmapobject من غير properties +
additionalProperties: { type }قيمة ثابتة
enum لقايمة، const لقيمة واحدةالـ annotations
title description default examples readOnly writeOnly deprecated $commentالـ defaultannotation، Ajv بيحطه بس مع
useDefaults: trueالـ strings
minLength maxLength بالـ code points، وpattern محتاج ^...$الـ formatannotation في الـ spec، في Ajv محتاج
ajv-formats، وtime محتاج timezoneالأرقام
minimum شامل، exclusiveMinimum رقم مش booleanالفلوسinteger بالقروش، و
multipleOf: 0.01 بيرفض 19.99الـ tuple
prefixItems + items: false + minItemsالـ arrays
items minItems maxItems uniqueItems (deep) contains minContainsالـ objects
patternProperties propertyNames minProperties maxPropertiesحقل بيستدعي حقل
dependentRequired للوجود، dependentSchemas لـ schema كاملةالتركيب
allOf = و، anyOf = أو، oneOf = واحدة بس، not = لأفخ oneOfفروع بتتقاطع = invalid، فاستخدم
anyOf أو const يفرق بينهمالـ unions
const في كل فرع + discriminator: true في Ajv = error واحد واضحالـ if/thenحط
required جوه الـ if وإلا {} هيروح thenكذا شرطكل
if/then في عنصر منفصل جوه allOfallOf + additionalPropertiesبيرفض حقول الـ base، فاستخدم
unevaluatedProperties: falseإعادة استخدام
$defs + $ref: "#/$defs/x"، والقديم definitionsملفات منفصلة
$id لكل ملف + addSchema + getSchema(id)الـ $ref لـ URLAjv مش بيحمّل، ومتحمّلش من النت وقت التشغيل
شجرة
$ref: "#" + maxItems + limit على الـ bodyالـ $anchor في Ajv 8.20strict رماه unknown، والحل
ajv.addKeyword("$anchor")draft-07 ← 2020-12
definitions ← $defs، items: [..] ← prefixItems، dependencies ← اتنينالـ compileمرة واحدة وقت الـ startup، وجوه الـ handler = بطء + memory leak
الـ allErrorsكويس للـ forms، وخطر مع input ضخم أو regex وحشة
الـ strictسيبه شغال، بيلقط
minLenght والـ formats الناقصةالـ coerceTypesللـ query والـ env بس، مش للـ JSON body
بيعدّلوا الـ data
coerceTypes useDefaults removeAdditionalالـ removeAdditionalبيخبّي الـ typos، والرفض أوضح للـ APIs العامة
الـ errors
instancePath keyword params message، والناقص في params.missingPropertyرسايل عربي
ajv-errors + errorMessage، أو ajv-i18n بـ localize.arstandaloneكود متولد وقت الـ build، طلّعه
.cjs، ومفيد للـ serverless والـ CSPExpress
express.json({ limit }) + middleware بـ getSchema + handler للـ parse errorsFastify
schema.body/querystring/params/headers built-in، وschema.response بيمنع تسريب حقولdefaults بتاعة Fastify
coerceTypes: "array" removeAdditional: true useDefaults: true وdraft-07Type guard
JSONSchemaType<T> + if (validate(x))، والـ optional محتاج nullable: trueschema ← types
json-schema-to-typescript / json2tstypes ← schema
ts-json-schema-generator (بيطلّع draft-07)TypeBox
Type.Object = JSON Schema حقيقي + Static<typeof T>Zod 4
z.toJSONSchema، io: "input"، target، والـ refine بيضيع والـ Date/transform بيرمواJSON Schema ولا Zodعقد بين لغات/أدوات = JSON Schema، كل حاجة TS + transforms = Zod
OpenAPI 3.1متوافقة مع 2020-12،
type array بدل nullable، وexamples بدل exampleautocomplete
$schema في الـ JSON، comment yaml-language-server في الـ YAML، SchemaStore، json.schemasالـ configvalidate وقت الـ startup و
process.exit(1)، وسيب $schema كـ propertyLLM strictكل الحقول required،
additionalProperties: false، الاختياري = null، وراجع الرد برضهMongoDB
$jsonSchema + bsonType، من غير $ref ولا formatمش شغلتهامقارنة حقول، uniqueness، صلاحيات، حسابات، sanitization
تطوير الـ inputoptional جديد وتوسيع = آمن، required جديد وتضييق = breaking
متضيّقش بهدوءwarning الأول، expand / contract، version في الـ
$idReDoSمتعملش
(a+)+، و27 حرف = ثانية، وallErrors بيلغي حماية maxLengthالحجمlimit قبل الـ parse +
maxLength maxItems maxPropertiesschemas من برهمتعملهاش compile أبدًا
خلّصت المذكرة لما
🧠 اختبر نفسك
١) webhook جاي من Stripe. تحط additionalProperties: false؟
لأ. هيضيفوا حقول في أي وقت. راجع الحقول اللي بتستخدمها بس، وسيب الباقي مفتوح.
٢) ليه API بـ Fastify قبل age: "30"؟
لأن Fastify شغّال بـ
coerceTypes: "array" by default.٣) عايز schema واحدة تشتغل في Node وPython وOpenAPI وVS Code. تكتبها بإيه؟
JSON Schema 2020-12 كملفات JSON، وتعمل validation بـ Ajv في Node و
jsonschema في Python.