الآخر

Cheat Sheet: الـ JSON Schema

type · required · additionalProperties · format · prefixItems · oneOf · if/then · unevaluatedProperties · $ref · 2020-12 · Ajv · Fastify · Zod · TypeBox · OpenAPI 3.1 · ReDoS
🎯 الهدف: تفتكر كل keyword وكل فخ وكل أداة في المذكرة بسرعة.
المشكلةJSON.parse بيقبل أي شكل، والـ TS types بتختفي وقت التشغيل، وas T مش validation
الحلJSON Schema = عقد مكتوب JSON، والـ validator (Ajv) يراجع عند كل trust boundary
الـ trust boundariesAPI bodies، webhooks، config، queues، ردود الـ LLM، localStorage، بيانات DB قديمة
الـ importajv = draft-07، وajv/dist/2020.js = 2020-12، ولازم يتفقوا مع $schema
الـ typesstring number integer boolean null object array، و5.0 integer
يقبل nulltype: ["string", "null"]، ومفيش nullable بره OpenAPI 3.0
حقل إجباريrequired: [...] في الـ object، مش جوه الحقل
حقول زيادةadditionalProperties: false للـ input، ومفتوح للبيانات اللي بتتطور
mapobject من غير properties + additionalProperties: { type }
قيمة ثابتةenum لقايمة، const لقيمة واحدة
الـ annotationstitle description default examples readOnly writeOnly deprecated $comment
الـ defaultannotation، Ajv بيحطه بس مع useDefaults: true
الـ stringsminLength maxLength بالـ code points، وpattern محتاج ^...$
الـ formatannotation في الـ spec، في Ajv محتاج ajv-formats، وtime محتاج timezone
الأرقامminimum شامل، exclusiveMinimum رقم مش boolean
الفلوسinteger بالقروش، وmultipleOf: 0.01 بيرفض 19.99
الـ tupleprefixItems + items: false + minItems
الـ arraysitems minItems maxItems uniqueItems (deep) contains minContains
الـ objectspatternProperties propertyNames minProperties maxProperties
حقل بيستدعي حقلdependentRequired للوجود، dependentSchemas لـ schema كاملة
التركيبallOf = و، anyOf = أو، oneOf = واحدة بس، not = لأ
فخ oneOfفروع بتتقاطع = invalid، فاستخدم anyOf أو const يفرق بينهم
الـ unionsconst في كل فرع + discriminator: true في Ajv = error واحد واضح
الـ if/thenحط required جوه الـ if وإلا {} هيروح then
كذا شرطكل if/then في عنصر منفصل جوه allOf
allOf + 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-12definitions ← $defs، items: [..] ← prefixItems، dependencies ← اتنين
الـ compileمرة واحدة وقت الـ startup، وجوه الـ handler = بطء + memory leak
الـ allErrorsكويس للـ forms، وخطر مع input ضخم أو regex وحشة
الـ strictسيبه شغال، بيلقط minLenght والـ formats الناقصة
الـ coerceTypesللـ query والـ env بس، مش للـ JSON body
بيعدّلوا الـ datacoerceTypes useDefaults removeAdditional
الـ removeAdditionalبيخبّي الـ typos، والرفض أوضح للـ APIs العامة
الـ errorsinstancePath keyword params message، والناقص في params.missingProperty
رسايل عربيajv-errors + errorMessage، أو ajv-i18n بـ localize.ar
standaloneكود متولد وقت الـ build، طلّعه .cjs، ومفيد للـ serverless والـ CSP
Expressexpress.json({ limit }) + middleware بـ getSchema + handler للـ parse errors
Fastifyschema.body/querystring/params/headers built-in، وschema.response بيمنع تسريب حقول
defaults بتاعة FastifycoerceTypes: "array" removeAdditional: true useDefaults: true وdraft-07
Type guardJSONSchemaType<T> + if (validate(x))، والـ optional محتاج nullable: true
schema ← typesjson-schema-to-typescript / json2ts
types ← schemats-json-schema-generator (بيطلّع draft-07)
TypeBoxType.Object = JSON Schema حقيقي + Static<typeof T>
Zod 4z.toJSONSchema، io: "input"، target، والـ refine بيضيع والـ Date/transform بيرموا
JSON Schema ولا Zodعقد بين لغات/أدوات = JSON Schema، كل حاجة TS + transforms = Zod
OpenAPI 3.1متوافقة مع 2020-12، type array بدل nullable، وexamples بدل example
autocomplete$schema في الـ JSON، comment yaml-language-server في الـ YAML، SchemaStore، json.schemas
الـ configvalidate وقت الـ startup وprocess.exit(1)، وسيب $schema كـ property
LLM strictكل الحقول required، additionalProperties: false، الاختياري = null، وراجع الرد برضه
MongoDB$jsonSchema + bsonType، من غير $ref ولا format
مش شغلتهامقارنة حقول، uniqueness، صلاحيات، حسابات، sanitization
تطوير الـ inputoptional جديد وتوسيع = آمن، required جديد وتضييق = breaking
متضيّقش بهدوءwarning الأول، expand / contract، version في الـ $id
ReDoSمتعملش (a+)+، و27 حرف = ثانية، وallErrors بيلغي حماية maxLength
الحجمlimit قبل الـ parse + maxLength maxItems maxProperties
schemas من برهمتعملهاش 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.