ToolHub
View All Posts

คู่มือ JSON Schema: ตรวจสอบโครงสร้างข้อมูลของคุณ

ทุกแอปพลิเคชันที่รับข้อมูลจากแหล่งภายนอกต้องเผชิญกับคำถามพื้นฐานเดียวกัน: ฉันเชื่อถือข้อมูลนี้ได้หรือไม่? ไม่ว่าจะเป็น body คำขอ API ไฟล์กำหนดค่า ข้อความคิว หรือการนำเข้าข้อมูล ข้อมูลที่ไม่น่าเชื่อถือต้องได้รับการตรวจสอบก่อนเข้าสู่ระบบ JSON Schema มอบวิธีที่เป็นมาตรฐานและไม่ขึ้นกับภาษาในการกำหนดว่าข้อมูลที่ถูกต้องควรมีลักษณะอย่างไร และตรวจสอบว่าข้อมูลขาเข้าสอดคล้องกับคำจำกัดความนั้นหรือไม่ คู่มือนี้ครอบคลุมทุกอย่างตั้งแต่การเขียน Schema แรกไปจนถึงรูปแบบขั้นสูงสำหรับการตรวจสอบที่ซับซ้อน พร้อมตัวอย่างที่ใช้งานได้จริงที่คุณสามารถนำไปใช้ได้ทันที

JSON Schema คืออะไร?

JSON Schema คือเอกสาร JSON ที่อธิบายโครงสร้างและข้อจำกัดของเอกสาร JSON อื่นๆ เป็นคำศัพท์ที่ช่วยให้คุณกำหนดคำอธิบายประกอบและตรวจสอบข้อมูล JSON ซึ่งกำหนดมาตรฐานโดย IETF (Internet Engineering Task Force) JSON Schema กำหนดกฎเกี่ยวกับฟิลด์ที่ต้องมี ประเภทที่ต้องเป็น ค่าที่ยอมรับได้ และโครงสร้างของออบเจ็กต์และอาร์เรย์

ลองนึกภาพ JSON Schema เป็นสัญญาข้อมูลของคุณ เช่นเดียวกับ Schema ฐานข้อมูลที่กำหนดคอลัมน์ ประเภท และข้อจำกัดของตาราง JSON Schema กำหนดคุณสมบัติ ประเภท และข้อจำกัดของเอกสาร JSON ข้อมูล JSON ใดๆ ที่ตรงตามข้อจำกัดทั้งหมดใน Schema เรียกว่าอินสแตนซ์ที่ถูกต้อง ในขณะที่ข้อมูลที่ละเมิดข้อจำกัดใดๆ จะไม่ถูกต้อง

สิ่งที่ JSON Schema ไม่ใช่

เวอร์ชัน JSON Schema

JSON Schema ได้พัฒนาผ่านหลายร่าง แต่ละร่างเพิ่มฟีเจอร์และปรับปรุงคำศัพท์ การเข้าใจเวอร์ชันเหล่านี้ช่วยให้คุณเลือกเวอร์ชันที่เหมาะสมสำหรับโปรเจกต์ของคุณและหลีกเลี่ยงปัญหาความเข้ากันได้

เวอร์ชัน$schema URIสถานะฟีเจอร์หลัก
Draft 2020-12https://json-schema.org/draft/2020-12/schemaเวอร์ชันปัจจุบันprefixItems, dynamicRef, การรองรับคำศัพท์
Draft 2019-09https://json-schema.org/draft/2019-09/schemaเวอร์ชันเสถียรunevaluatedProperties, $recursiveRef
Draft 7http://json-schema.org/draft-07/schema#รองรับอย่างกว้างขวางif/then/else, contentEncoding
Draft 6http://json-schema.org/draft-06/schema#เวอร์ชันเก่าpropertyNames, contains
Draft 4http://json-schema.org/draft-04/schema#เลิกใช้แล้วเวอร์ชันที่นำมาใช้อย่างกว้างขวางครั้งแรก
คำแนะนำ: ใช้ Draft 2020-12 สำหรับโปรเจกต์ใหม่ เป็นเวอร์ชันเสถียรล่าสุด มีฟีเจอร์มากที่สุด และรองรับโดยไลบรารีตรวจสอบหลัก หากต้องการความเข้ากันได้สูงสุดกับเครื่องมือที่มีอยู่ Draft 7 เป็นตัวเลือกที่ปลอดภัย หลีกเลี่ยง Draft 4 และเวอร์ชันก่อนหน้า

เขียน Schema แรกของคุณ

มาเริ่มด้วยตัวอย่างง่ายๆ: Schema สำหรับออบเจ็กต์ผู้ใช้ที่มีชื่อ อีเมล และอายุ

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://example.com/schemas/user.json",
    "title": "User",
    "description": "A user account in the system",
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "The user's full name"
        },
        "email": {
            "type": "string",
            "format": "email",
            "description": "The user's email address"
        },
        "age": {
            "type": "integer",
            "minimum": 0,
            "maximum": 150,
            "description": "The user's age in years"
        }
    },
    "required": ["name", "email"],
    "additionalProperties": false
}

Schema นี้ประกาศว่าผู้ใช้ที่ถูกต้องต้องเป็นออบเจ็กต์ โดยที่ name และ email เป็นคุณสมบัติสตริงที่จำเป็น คุณสมบัติ age เป็นทางเลือก แต่ถ้ามีต้องเป็นจำนวนเต็มระหว่าง 0 ถึง 150 ข้อจำกัด additionalProperties: false ป้องกันคุณสมบัติใดๆ ที่ไม่ได้กำหนดใน Schema ซึ่งช่วยจับการสะกดผิดและฟิลด์ที่ไม่คาดคิด

ข้อมูลอ้างอิงคีย์เวิร์ดหลัก

JSON Schema มีคำศัพท์คีย์เวิร์ดที่หลากหลายสำหรับการกำหนดข้อจำกัด นี่คือคีย์เวิร์ดที่สำคัญที่สุด จัดตามหมวดหมู่

คีย์เวิร์ดประเภท

คีย์เวิร์ดคำอธิบายตัวอย่าง
typeประเภทข้อมูลที่คาดหวัง"type": "string" หรือ "type": ["string", "null"]
enumรายการค่าที่อนุญาต"enum": ["active", "inactive", "pending"]
constต้องเท่ากับค่านี้อย่างแม่นยำ"const": "v2"

ข้อจำกัดตัวเลข

คีย์เวิร์ดคำอธิบายตัวอย่าง
minimumค่าต่ำสุด (รวม)"minimum": 0
exclusiveMinimumค่าต่ำสุด (ไม่รวม)"exclusiveMinimum": 0
maximumค่าสูงสุด (รวม)"maximum": 100
exclusiveMaximumค่าสูงสุด (ไม่รวม)"exclusiveMaximum": 100
multipleOfต้องเป็นตัวคูณของค่านี้"multipleOf": 0.01

ข้อจำกัดสตริง

คีย์เวิร์ดคำอธิบายตัวอย่าง
minLengthความยาวสตริงขั้นต่ำ"minLength": 1
maxLengthความยาวสตริงสูงสุด"maxLength": 255
patternregex ที่สตริงต้องตรงกัน"pattern": "^[A-Z]{2}\\d{4}$"
formatรูปแบบความหมาย (email, uri, date-time ฯลฯ)"format": "email"

ข้อจำกัดออบเจ็กต์

คีย์เวิร์ดคำอธิบายตัวอย่าง
propertiesSchema สำหรับแต่ละคุณสมบัติที่รู้จัก"properties": {"name": {"type": "string"}}
requiredรายการคุณสมบัติที่จำเป็น"required": ["name", "email"]
additionalPropertiesอนุญาตคุณสมบัติเพิ่มเติมหรือไม่"additionalProperties": false
minPropertiesจำนวนคุณสมบัติขั้นต่ำ"minProperties": 1
maxPropertiesจำนวนคุณสมบัติสูงสุด"maxProperties": 10
patternPropertiesSchema สำหรับคุณสมบัติที่ตรงกับ regex"patternProperties": {"^S_": {"type": "string"}}

ข้อจำกัดอาร์เรย์

คีย์เวิร์ดคำอธิบายตัวอย่าง
itemsSchema สำหรับรายการอาร์เรย์ทั้งหมด"items": {"type": "string"}
prefixItemsSchema สำหรับรายการตามตำแหน่ง (Draft 2020-12)"prefixItems": [{"type": "string"}, {"type": "number"}]
minItemsจำนวนรายการขั้นต่ำ"minItems": 1
maxItemsจำนวนรายการสูงสุด"maxItems": 100
uniqueItemsรายการทั้งหมดต้องไม่ซ้ำกัน"uniqueItems": true

รูปแบบ Schema ทั่วไป

Schema ในโลกความเป็นจริงมักต้องการรูปแบบที่นอกเหนือจากการตรวจสอบประเภทอย่างง่าย นี่คือรูปแบบที่ใช้บ่อยที่สุด

การตรวจสอบแบบมีเงื่อนไขด้วย if/then/else

ใช้ตรรกะเงื่อนไขเพื่อใช้ข้อจำกัดที่แตกต่างกันตามค่าคุณสมบัติ ตัวอย่างเช่น ออบเจ็กต์การชำระเงินต้องการฟิลด์ที่แตกต่างกันตามวิธีการชำระเงิน

{
    "type": "object",
    "properties": {
        "method": { "enum": ["credit_card", "bank_transfer"] },
        "card_number": { "type": "string" },
        "routing_number": { "type": "string" }
    },
    "required": ["method"],
    "if": {
        "properties": { "method": { "const": "credit_card" } }
    },
    "then": {
        "required": ["card_number"]
    },
    "else": {
        "required": ["routing_number"]
    }
}

การรวมด้วย allOf, anyOf, oneOf

คีย์เวิร์ดการรวมช่วยให้คุณรวม Schema ในรูปแบบที่ทรงพลัง:

{
    "oneOf": [
        {
            "type": "object",
            "properties": {
                "type": { "const": "email" },
                "address": { "type": "string", "format": "email" }
            },
            "required": ["type", "address"]
        },
        {
            "type": "object",
            "properties": {
                "type": { "const": "phone" },
                "number": { "type": "string", "pattern": "^\\+?[1-9]\\d{1,14}$" }
            },
            "required": ["type", "number"]
        }
    ]
}

การใช้ $ref เพื่อนำ Schema กลับมาใช้ใหม่

คีย์เวิร์ด $ref ช่วยให้คุณอ้างอิงและนำ Schema กลับมาใช้ใหม่ กำจัดการซ้ำซ้อนและรักษาความสามารถในการบำรุงรักษาของ Schema คุณสามารถอ้างอิง Schema ภายในเอกสารเดียวกันหรือในไฟล์ภายนอก

{
    "$id": "https://example.com/schemas/order.json",
    "type": "object",
    "properties": {
        "customer": { "$ref": "#/$defs/address" },
        "shipping": { "$ref": "#/$defs/address" },
        "billing": { "$ref": "#/$defs/address" },
        "items": {
            "type": "array",
            "items": { "$ref": "#/$defs/lineItem" },
            "minItems": 1
        }
    },
    "required": ["customer", "items"],
    "$defs": {
        "address": {
            "type": "object",
            "properties": {
                "street": { "type": "string" },
                "city": { "type": "string" },
                "zip": { "type": "string", "pattern": "^\\d{5}(-\\d{4})?$" },
                "country": { "type": "string", "minLength": 2, "maxLength": 2 }
            },
            "required": ["street", "city", "zip", "country"]
        },
        "lineItem": {
            "type": "object",
            "properties": {
                "product": { "type": "string" },
                "quantity": { "type": "integer", "minimum": 1 },
                "price": { "type": "number", "exclusiveMinimum": 0 }
            },
            "required": ["product", "quantity", "price"]
        }
    }
}

ประเภทที่ nullable

ใน JSON Schema Draft 2020-12 ประเภทที่ nullable แสดงโดยใช้อาร์เรย์ประเภทที่มี "null":

{
    "type": ["string", "null"],
    "description": "An optional display name, or null if not set"
}

ในร่างก่อนหน้านี้ ข้อกำหนด OpenAPI ใช้คีย์เวิร์ด nullable: true สำหรับ JSON Schema มาตรฐาน ให้ใช้วิธีการอาร์เรย์ประเภทเสมอ

การตรวจสอบรูปแบบ

คีย์เวิร์ด format ให้การตรวจสอบความหมายที่นอกเหนือจากการตรวจสอบโครงสร้าง มันระบุว่าสตริงต้องสอดคล้องกับรูปแบบที่รู้จักกันดี รูปแบบที่รองรับทั่วไปรวมถึง:

รูปแบบคำอธิบายตัวอย่าง
emailที่อยู่อีเมลuser@example.com
uriURI ที่ถูกต้องhttps://example.com/path
uri-referenceURI หรือการอ้างอิงสัมพัทธ์/path/to/resource
date-timeวันที่เวลา ISO 86012026-05-19T14:30:00Z
dateวันที่ ISO 86012026-05-19
timeเวลา ISO 860114:30:00Z
ipv4ที่อยู่ IPv4192.168.1.1
ipv6ที่อยู่ IPv6::1
uuidUUID550e8400-e29b-41d4-a716-446655440000
hostnameชื่อโฮสต์อินเทอร์เน็ตwww.example.com
หมายเหตุสำคัญ: โดยค่าเริ่มต้น คีย์เวิร์ด format เป็นคำอธิบายประกอบ ไม่ใช่ข้อจำกัด ตัวตรวจสอบอาจละเว้นมัน เว้นแต่คุณจะเปิดใช้งานการตรวจสอบรูปแบบอย่างชัดเจน ใน Ajv ส่ง { strict: true } หรือ { validateFormats: true } เพื่อบังคับการตรวจสอบรูปแบบ ตรวจสอบเสมอว่าตัวตรวจสอบของคุณบังคับใช้ข้อจำกัดรูปแบบหรือไม่

ตรวจสอบข้อมูล JSON ด้วยโปรแกรม

การตรวจสอบ Schema มีประโยชน์มากที่สุดเมื่อรวมเข้ากับโค้ดแอปพลิเคชัน นี่คือตัวอย่างการใช้ไลบรารียอดนิยมในภาษาต่างๆ

JavaScript ด้วย Ajv

Ajv เป็นตัวตรวจสอบ JSON Schema ที่ใช้กันอย่างแพร่หลายที่สุดใน JavaScript รองรับเวอร์ชันร่างทั้งหมด และให้ประสิทธิภาพที่ยอดเยี่ยมผ่านการคอมไพล์ JIT ของ Schema

import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv();
addFormats(ajv);

const schema = {
    type: 'object',
    properties: {
        name: { type: 'string', minLength: 1 },
        email: { type: 'string', format: 'email' },
        age: { type: 'integer', minimum: 0 }
    },
    required: ['name', 'email'],
    additionalProperties: false
};

const validate = ajv.compile(schema);
const valid = validate({ name: 'Alice', email: 'alice@example.com', age: 30 });

if (!valid) {
    console.log(validate.errors);
    // [{ keyword: 'required', params: { missingProperty: 'email' }, ... }]
}

Python ด้วย jsonschema

from jsonschema import validate, ValidationError

schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string", "minLength": 1},
        "email": {"type": "string", "format": "email"},
        "age": {"type": "integer", "minimum": 0}
    },
    "required": ["name", "email"],
    "additionalProperties": False
}

try:
    validate(instance={"name": "Alice", "email": "alice@example.com"}, schema=schema)
except ValidationError as e:
    print(f"Validation failed: {e.message}")

การตรวจสอบข้อมูล API ด้วย JSON Schema

หนึ่งในแอปพลิเคชันที่มีค่าที่สุดของ JSON Schema คือการตรวจสอบข้อมูลคำขอและการตอบสนอง API สิ่งนี้ทำให้มั่นใจว่า API ของคุณรับอินพุตที่มีรูปแบบดีและส่งคืนข้อมูลในรูปแบบที่คาดหวัง จับข้อผิดพลาดได้ตั้งแต่เนิ่นๆ และให้ข้อความแสดงข้อผิดพลาดที่ชัดเจนแก่ไคลเอ็นต์

มิดเดิลแวร์ Express.js

import Ajv from 'ajv';

const ajv = new Ajv({ allErrors: true });

function validateBody(schema) {
    const validate = ajv.compile(schema);
    return (req, res, next) => {
        if (!validate(req.body)) {
            return res.status(400).json({
                error: 'Validation failed',
                details: validate.errors
            });
        }
        next();
    };
}

app.post('/api/users',
    validateBody({
        type: 'object',
        properties: {
            name: { type: 'string', minLength: 1, maxLength: 100 },
            email: { type: 'string', format: 'email' },
            role: { enum: ['admin', 'editor', 'viewer'] }
        },
        required: ['name', 'email'],
        additionalProperties: false
    }),
    (req, res) => {
        // req.body is guaranteed valid here
        createUser(req.body);
    }
);

OpenAPI กับ JSON Schema

OpenAPI (เดิมชื่อ Swagger) ใช้เซตย่อยของ JSON Schema เพื่อกำหนด Schema คำขอและการตอบสนอง API หากคุณใช้ OpenAPI อยู่แล้ว คุณสามารถแยก Schema จากข้อกำหนด API และใช้สำหรับการตรวจสอบรันไทม์ เครื่องมือเช่น openapi-schema-validator และ express-openapi-validator สามารถทำให้กระบวนการนี้เป็นอัตโนมัติ ทำให้มั่นใจว่าเอกสาร API และตรรกะการตรวจสอบของคุณสอดคล้องกันเสมอ

แนวปฏิบัติที่ดีที่สุด

ต้องการตรวจสอบข้อมูล JSON กับ Schema? ลองใช้ตัวตรวจสอบ JSON Schema ออนไลน์ฟรีของเรา วาง Schema และข้อมูลของคุณ แล้วรับผลการตรวจสอบทันทีพร้อมข้อความแสดงข้อผิดพลาดโดยละเอียด

ตัวตรวจสอบ JSON Schemaเครื่องมือจัดรูปแบบ JSON

คำถามที่พบบ่อย

JSON Schema คืออะไร?

JSON Schema คือเอกสาร JSON ที่อธิบายโครงสร้างและข้อจำกัดของเอกสาร JSON อื่นๆ ช่วยให้คุณกำหนดฟิลด์ที่จำเป็น ประเภทข้อมูลที่คาดหวัง ช่วงค่า รูปแบบสตริง และโครงสร้างออบเจ็กต์ที่ซ้อนกัน คุณสามารถใช้เพื่อตรวจสอบข้อมูลขาเข้า สร้างเอกสาร และสร้างอินเทอร์เฟซฟอร์มโดยอัตโนมัติ

ฉันควรใช้ JSON Schema เวอร์ชันไหน?

สำหรับโปรเจกต์ใหม่ ใช้ JSON Schema Draft 2020-12 นี่คือเวอร์ชันเสถียรล่าสุดที่รองรับโดยไลบรารีตรวจสอบหลักเช่น Ajv หากต้องการความเข้ากันได้กับเครื่องมือเก่า Draft 7 ก็ได้รับการสนับสนุนอย่างกว้างขวาง หลีกเลี่ยง Draft 4 และเวอร์ชันก่อนหน้าเนื่องจากใช้คีย์เวิร์ดที่ล้าสมัยและขาดฟีเจอร์สมัยใหม่

JSON Schema แตกต่างจาก TypeScript interface อย่างไร?

TypeScript interface ให้การตรวจสอบประเภทในเวลาคอมไพล์เฉพาะในโค้ด TypeScript เท่านั้น JSON Schema ให้การตรวจสอบรันไทม์ข้ามภาษาโปรแกรม สามารถตรวจสอบข้อมูลจากแหล่งใดๆ (คำขอ API, ไฟล์, ฐานข้อมูล) ใช้ TypeScript เพื่อความปลอดภัยในเวลาพัฒนา และใช้ JSON Schema สำหรับการตรวจสอบข้อมูลรันไทม์ที่ขอบเขตของระบบ

JSON Schema สามารถตรวจสอบ body คำขอ API ได้หรือไม่?

ใช่ JSON Schema ถูกใช้อย่างกว้างขวางสำหรับการตรวจสอบคำขอและการตอบสนอง API เฟรมเวิร์กเช่น Express (พร้อม express-json-validator), FastAPI และ Spring Boot รองรับการตรวจสอบ JSON Schema โดยตรงหรือผ่านมิดเดิลแวร์ การตรวจสอบ body คำขอกับ Schema ทำให้มั่นใจว่าข้อมูลขาเข้ามีโครงสร้างที่ถูกต้องก่อนที่แอปพลิเคชันจะประมวลผล

คีย์เวิร์ด JSON Schema ที่สำคัญที่สุดมีอะไรบ้าง?

คีย์เวิร์ดที่สำคัญที่สุดคือ: type (ประเภทข้อมูล), properties (ฟิลด์ออบเจ็กต์), required (ฟิลด์ที่จำเป็น), items (Schema องค์ประกอบอาร์เรย์), minimum/maximum (ขอบเขตตัวเลข), minLength/maxLength (ขอบเขตสตริง), pattern (regex สตริง), enum (ค่าที่อนุญาต) และ $ref (การอ้างอิงเพื่อนำ Schema กลับมาใช้ใหม่) คีย์เวิร์ดเหล่านี้ครอบคลุมความต้องการการตรวจสอบส่วนใหญ่