JSON Schema 实战示例 - 从真实场景学习
3203 字
16 分钟
JSON Schema 实战示例 - 从真实场景学习
引言
学习 JSON Schema 最好的方式就是通过实际案例。本文提供了来自真实项目的完整 Schema 示例,涵盖 REST API、表单验证、配置文件、微服务通信等多个场景。
目录
REST API 响应 Schema {#rest-api}
示例 1:用户 API 完整 Schema
场景:电商平台的用户管理 API
{ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://api.example.com/schemas/user.json", "title": "用户 API 响应", "description": "描述用户相关的 API 响应结构", "type": "object", "definitions": { "address": { "type": "object", "properties": { "id": { "type": "integer", "description": "地址 ID", "minimum": 1 }, "label": { "type": "string", "description": "地址标签(如:家、公司)", "enum": ["home", "work", "other"], "default": "home" }, "country": { "type": "string", "description": "国家/地区", "minLength": 2, "maxLength": 2, "pattern": "^[A-Z]{2}$" }, "province": { "type": "string", "description": "省/州" }, "city": { "type": "string", "description": "城市" }, "district": { "type": "string", "description": "区/县" }, "street": { "type": "string", "description": "街道地址", "maxLength": 200 }, "postalCode": { "type": "string", "description": "邮政编码", "pattern": "^\\d{6}$" }, "isDefault": { "type": "boolean", "description": "是否为默认地址", "default": false } }, "required": ["country", "city", "street"] }, "user_profile": { "type": "object", "properties": { "avatar": { "type": "string", "format": "uri", "description": "头像 URL" }, "bio": { "type": "string", "description": "个人简介", "maxLength": 500 }, "website": { "type": "string", "format": "uri", "description": "个人网站" }, "company": { "type": "string", "description": "公司名称" }, "position": { "type": "string", "description": "职位" } } } }, "properties": { "status": { "type": "string", "enum": ["success", "error"], "description": "响应状态" }, "code": { "type": "integer", "description": "状态码", "minimum": 1000, "maximum": 9999 }, "data": { "type": "object", "properties": { "user": { "type": "object", "properties": { "id": { "type": "integer", "description": "用户 ID", "minimum": 1, "example": 10001 }, "username": { "type": "string", "description": "用户名", "minLength": 3, "maxLength": 30, "pattern": "^[a-zA-Z0-9_]+$", "example": "john_doe" }, "email": { "type": "string", "format": "email", "description": "邮箱地址", "example": "john@example.com" }, "phone": { "type": "string", "description": "手机号码", "pattern": "^\\+?[0-9\\-\\s]+$", "example": "+86-13800138000" }, "role": { "type": "string", "description": "用户角色", "enum": ["customer", "vip", "admin"], "default": "customer" }, "status": { "type": "string", "description": "账户状态", "enum": ["active", "inactive", "suspended", "deleted"], "default": "active" }, "profile": { "$ref": "#/definitions/user_profile" }, "addresses": { "type": "array", "description": "收货地址列表", "items": { "$ref": "#/definitions/address" }, "minItems": 0, "maxItems": 10 }, "preferences": { "type": "object", "description": "用户偏好设置", "properties": { "language": { "type": "string", "description": "语言", "pattern": "^[a-z]{2}(-[A-Z]{2})?$", "default": "zh-CN" }, "currency": { "type": "string", "description": "货币", "pattern": "^[A-Z]{3}$", "default": "CNY" }, "timezone": { "type": "string", "description": "时区", "default": "Asia/Shanghai" }, "notifications": { "type": "object", "properties": { "email": { "type": "boolean", "default": true }, "sms": { "type": "boolean", "default": false }, "push": { "type": "boolean", "default": true } } } } }, "statistics": { "type": "object", "description": "用户统计信息", "properties": { "totalOrders": { "type": "integer", "minimum": 0, "default": 0 }, "totalSpent": { "type": "number", "minimum": 0, "multipleOf": 0.01 }, "loyaltyPoints": { "type": "integer", "minimum": 0, "default": 0 }, "memberSince": { "type": "string", "format": "date-time" }, "lastLoginAt": { "type": ["string", "null"], "format": "date-time" } } }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } }, "required": ["id", "username", "email", "status", "createdAt"] } } }, "timestamp": { "type": "string", "format": "date-time", "description": "响应时间戳" }, "requestId": { "type": "string", "description": "请求 ID(用于追踪)", "pattern": "^[a-f0-9]{32}$" } }, "required": ["status", "code", "data", "timestamp"]}使用示例:
{ "status": "success", "code": 2000, "data": { "user": { "id": 10001, "username": "john_doe", "email": "john@example.com", "phone": "+86-13800138000", "role": "vip", "status": "active", "profile": { "avatar": "https://example.com/avatars/john.jpg", "bio": "Full-stack developer", "company": "Tech Corp" }, "addresses": [ { "id": 1, "label": "home", "country": "CN", "province": "Beijing", "city": "Beijing", "district": "Chaoyang", "street": "Building 1, Street 2", "postalCode": "100000", "isDefault": true } ], "preferences": { "language": "zh-CN", "currency": "CNY", "timezone": "Asia/Shanghai", "notifications": { "email": true, "sms": false, "push": true } }, "statistics": { "totalOrders": 25, "totalSpent": 12580.50, "loyaltyPoints": 1250, "memberSince": "2023-01-15T08:00:00Z", "lastLoginAt": "2024-01-20T14:30:00Z" }, "createdAt": "2023-01-15T08:00:00Z", "updatedAt": "2024-01-20T14:30:00Z" } }, "timestamp": "2024-01-20T15:00:00Z", "requestId": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"}示例 2:分页列表响应 Schema
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "分页列表响应", "type": "object", "definitions": { "pagination": { "type": "object", "properties": { "page": { "type": "integer", "minimum": 1, "default": 1 }, "pageSize": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 }, "totalItems": { "type": "integer", "minimum": 0 }, "totalPages": { "type": "integer", "minimum": 0 }, "hasNext": { "type": "boolean" }, "hasPrev": { "type": "boolean" } }, "required": ["page", "pageSize", "totalItems", "totalPages"] } }, "properties": { "status": { "type": "string", "enum": ["success", "error"] }, "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object" } }, "pagination": { "$ref": "#/definitions/pagination" } }, "required": ["items", "pagination"] } }, "required": ["status", "data"]}表单验证 Schema {#form-validation}
示例 3:用户注册表单 Schema
场景:网站用户注册表单验证
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "用户注册表单", "description": "验证用户注册提交的数据", "type": "object", "properties": { "username": { "type": "string", "title": "用户名", "description": "3-20 位字母、数字或下划线", "minLength": 3, "maxLength": 20, "pattern": "^[a-zA-Z0-9_]+$" }, "email": { "type": "string", "title": "邮箱地址", "format": "email", "description": "请输入有效的邮箱地址" }, "password": { "type": "string", "title": "密码", "description": "至少 8 位,包含大小写字母、数字和特殊字符", "minLength": 8, "maxLength": 32, "pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$" }, "confirmPassword": { "type": "string", "title": "确认密码" }, "phone": { "type": "string", "title": "手机号码", "pattern": "^1[3-9]\\d{9}$", "description": "请输入 11 位中国大陆手机号" }, "captcha": { "type": "string", "title": "验证码", "pattern": "^[0-9A-Z]{6}$", "description": "6 位字母数字组合" }, "agreeToTerms": { "type": "boolean", "title": "同意条款", "const": true }, "marketingOptIn": { "type": "boolean", "title": "接收营销邮件", "default": false } }, "required": ["username", "email", "password", "confirmPassword", "agreeToTerms"], "additionalProperties": false}前端验证实现:
import Ajv from 'ajv';import addFormats from 'ajv-formats';
const ajv = new Ajv({ allErrors: true });addFormats(ajv);
const validate = ajv.compile(registrationSchema);
function validateForm(formData) { const valid = validate(formData);
if (!valid) { const errors = validate.errors.map(err => ({ field: err.instancePath.slice(1), message: err.message })); return { valid: false, errors }; }
// 额外验证:密码匹配 if (formData.password !== formData.confirmPassword) { return { valid: false, errors: [{ field: 'confirmPassword', message: '两次输入的密码不一致' }] }; }
return { valid: true };}示例 4:电商订单表单 Schema
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "订单提交表单", "type": "object", "definitions": { "order_item": { "type": "object", "properties": { "productId": { "type": "string", "pattern": "^PROD-[0-9]{6}$" }, "quantity": { "type": "integer", "minimum": 1, "maximum": 99 }, "giftWrap": { "type": "boolean", "default": false } }, "required": ["productId", "quantity"] }, "shipping_address": { "type": "object", "properties": { "recipientName": { "type": "string", "minLength": 2, "maxLength": 50 }, "phone": { "type": "string", "pattern": "^1[3-9]\\d{9}$" }, "country": { "type": "string", "pattern": "^[A-Z]{2}$" }, "province": { "type": "string" }, "city": { "type": "string" }, "district": { "type": "string" }, "street": { "type": "string", "maxLength": 200 }, "postalCode": { "type": "string", "pattern": "^\\d{6}$" } }, "required": ["recipientName", "phone", "country", "city", "street"] } }, "properties": { "items": { "type": "array", "minItems": 1, "maxItems": 20, "items": { "$ref": "#/definitions/order_item" }, "uniqueItems": true }, "shippingAddress": { "$ref": "#/definitions/shipping_address" }, "billingAddress": { "oneOf": [ { "$ref": "#/definitions/shipping_address" }, { "type": "null" } ] }, "paymentMethod": { "type": "string", "enum": ["credit_card", "debit_card", "paypal", "bank_transfer", "cod"] }, "couponCode": { "type": "string", "pattern": "^COUPON[0-9A-Z]{6}$" }, "orderNotes": { "type": "string", "maxLength": 500 }, "deliveryTime": { "type": "string", "enum": ["asap", "morning", "afternoon", "evening"], "default": "asap" }, "invoiceRequired": { "type": "boolean", "default": false } }, "required": ["items", "shippingAddress", "paymentMethod"], "additionalProperties": false}配置文件 Schema {#config-files}
示例 5:应用配置文件 Schema
场景:Node.js 应用配置文件验证
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "应用配置", "type": "object", "definitions": { "database_config": { "type": "object", "properties": { "host": { "type": "string", "format": "hostname", "default": "localhost" }, "port": { "type": "integer", "minimum": 1, "maximum": 65535, "default": 5432 }, "database": { "type": "string", "minLength": 1 }, "username": { "type": "string" }, "password": { "type": "string" }, "pool": { "type": "object", "properties": { "min": { "type": "integer", "minimum": 0, "default": 2 }, "max": { "type": "integer", "minimum": 1, "default": 10 }, "idleTimeoutMillis": { "type": "integer", "minimum": 1000, "default": 30000 } } }, "ssl": { "type": "boolean", "default": false } }, "required": ["database", "username", "password"] }, "redis_config": { "type": "object", "properties": { "host": { "type": "string", "format": "hostname", "default": "localhost" }, "port": { "type": "integer", "minimum": 1, "maximum": 65535, "default": 6379 }, "password": { "type": ["string", "null"] }, "db": { "type": "integer", "minimum": 0, "maximum": 15, "default": 0 }, "keyPrefix": { "type": "string", "default": "" } } }, "logging_config": { "type": "object", "properties": { "level": { "type": "string", "enum": ["debug", "info", "warn", "error"], "default": "info" }, "format": { "type": "string", "enum": ["json", "text"], "default": "json" }, "outputs": { "type": "array", "items": { "type": "string", "enum": ["console", "file", "elasticsearch"] }, "default": ["console"] }, "file": { "type": "object", "properties": { "path": { "type": "string" }, "maxSize": { "type": "string", "pattern": "^\\d+[KMGT]B$" }, "maxFiles": { "type": "integer", "minimum": 1, "default": 5 } } } } } }, "properties": { "app": { "type": "object", "properties": { "name": { "type": "string", "default": "my-application" }, "version": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$" }, "env": { "type": "string", "enum": ["development", "staging", "production"], "default": "development" }, "port": { "type": "integer", "minimum": 1, "maximum": 65535, "default": 3000 }, "host": { "type": "string", "format": "hostname", "default": "0.0.0.0" } }, "required": ["version", "env"] }, "database": { "$ref": "#/definitions/database_config" }, "redis": { "$ref": "#/definitions/redis_config" }, "logging": { "$ref": "#/definitions/logging_config" }, "features": { "type": "object", "properties": { "enableCache": { "type": "boolean", "default": true }, "enableRateLimit": { "type": "boolean", "default": true }, "enableCors": { "type": "boolean", "default": true }, "enableCompression": { "type": "boolean", "default": true } } }, "rateLimit": { "type": "object", "properties": { "windowMs": { "type": "integer", "minimum": 1000, "default": 900000 }, "max": { "type": "integer", "minimum": 1, "default": 100 } } }, "cors": { "type": "object", "properties": { "origin": { "oneOf": [ { "type": "string", "format": "uri" }, { "type": "boolean", "const": true } ] }, "methods": { "type": "array", "items": { "type": "string", "enum": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"] }, "default": ["GET", "POST", "PUT", "DELETE"] }, "allowedHeaders": { "type": "array", "items": { "type": "string" } }, "credentials": { "type": "boolean", "default": true } } } }, "required": ["app", "database"]}使用示例:
{ "app": { "name": "ecommerce-api", "version": "1.0.0", "env": "production", "port": 3000, "host": "0.0.0.0" }, "database": { "host": "db.example.com", "port": 5432, "database": "ecommerce", "username": "app_user", "password": "secure_password", "pool": { "min": 5, "max": 20, "idleTimeoutMillis": 30000 }, "ssl": true }, "redis": { "host": "redis.example.com", "port": 6379, "password": "redis_password", "db": 0, "keyPrefix": "ecom:" }, "logging": { "level": "info", "format": "json", "outputs": ["console", "file"], "file": { "path": "/var/log/app", "maxSize": "100MB", "maxFiles": 10 } }, "features": { "enableCache": true, "enableRateLimit": true, "enableCors": true, "enableCompression": true }, "rateLimit": { "windowMs": 900000, "max": 100 }, "cors": { "origin": "https://example.com", "methods": ["GET", "POST", "PUT", "DELETE"], "credentials": true }}微服务通信 Schema {#microservices}
示例 6:服务间消息 Schema
场景:微服务架构中的事件消息
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "服务间事件消息", "type": "object", "definitions": { "event_metadata": { "type": "object", "properties": { "eventId": { "type": "string", "format": "uuid", "description": "事件唯一标识" }, "eventType": { "type": "string", "pattern": "^[a-z]+\\.[a-z]+(\\.[a-z]+)*$", "description": "事件类型(如:user.created)" }, "source": { "type": "string", "description": "事件来源服务" }, "timestamp": { "type": "string", "format": "date-time" }, "version": { "type": "string", "pattern": "^v\\d+$", "default": "v1" }, "correlationId": { "type": "string", "format": "uuid", "description": "关联 ID(用于链路追踪)" }, "causationId": { "type": ["string", "null"], "format": "uuid", "description": "因果 ID(触发此事件的上游事件)" } }, "required": ["eventId", "eventType", "source", "timestamp"] } }, "properties": { "metadata": { "$ref": "#/definitions/event_metadata" }, "data": { "type": "object", "description": "事件负载数据" }, "context": { "type": "object", "properties": { "userId": { "type": ["string", "null"], "format": "uuid" }, "sessionId": { "type": ["string", "null"], "format": "uuid" }, "ipAddress": { "type": ["string", "null"], "format": "ipv4" }, "userAgent": { "type": ["string", "null"] } } } }, "required": ["metadata", "data"]}具体事件示例:
{ "metadata": { "eventId": "550e8400-e29b-41d4-a716-446655440000", "eventType": "order.created", "source": "order-service", "timestamp": "2024-01-20T10:30:00Z", "version": "v1", "correlationId": "123e4567-e89b-12d3-a456-426614174000", "causationId": null }, "data": { "orderId": "ORD-2024-000001", "userId": "USR-10001", "totalAmount": 299.99, "currency": "CNY", "status": "pending", "items": [ { "productId": "PROD-001", "quantity": 2, "price": 149.995 } ] }, "context": { "userId": "USR-10001", "sessionId": "SES-ABC123", "ipAddress": "192.168.1.100", "userAgent": "Mozilla/5.0..." }}数据管道 Schema {#data-pipeline}
示例 7:ETL 数据转换 Schema
场景:数据管道中的数据格式定义
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "ETL 数据记录", "type": "object", "definitions": { "data_quality": { "type": "object", "properties": { "score": { "type": "number", "minimum": 0, "maximum": 100 }, "issues": { "type": "array", "items": { "type": "object", "properties": { "field": { "type": "string" }, "issue": { "type": "string" }, "severity": { "type": "string", "enum": ["low", "medium", "high", "critical"] } } } }, "validatedAt": { "type": "string", "format": "date-time" } } } }, "properties": { "recordId": { "type": "string", "format": "uuid" }, "sourceSystem": { "type": "string", "enum": ["salesforce", "sap", "oracle", "mysql", "mongodb"] }, "extractedAt": { "type": "string", "format": "date-time" }, "transformedAt": { "type": ["string", "null"], "format": "date-time" }, "loadedAt": { "type": ["string", "null"], "format": "date-time" }, "status": { "type": "string", "enum": ["extracted", "transforming", "transformed", "loading", "loaded", "failed"] }, "data": { "type": "object" }, "quality": { "$ref": "#/definitions/data_quality" }, "metadata": { "type": "object", "properties": { "version": { "type": "string" }, "checksum": { "type": "string", "pattern": "^[a-f0-9]{64}$" }, "size": { "type": "integer", "minimum": 0 }, "encoding": { "type": "string", "default": "utf-8" } } }, "errors": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "timestamp": { "type": "string", "format": "date-time" } } } } }, "required": ["recordId", "sourceSystem", "extractedAt", "status", "data"]}GraphQL 集成 Schema {#graphql}
示例 8:GraphQL 响应验证 Schema
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "GraphQL 响应", "type": "object", "definitions": { "graphql_error": { "type": "object", "properties": { "message": { "type": "string" }, "locations": { "type": "array", "items": { "type": "object", "properties": { "line": { "type": "integer" }, "column": { "type": "integer" } } } }, "path": { "type": "array", "items": { "oneOf": [ { "type": "string" }, { "type": "integer" } ] } }, "extensions": { "type": "object", "properties": { "code": { "type": "string" }, "classification": { "type": "string" } } } }, "required": ["message"] } }, "properties": { "data": { "type": ["object", "null"] }, "errors": { "type": "array", "items": { "$ref": "#/definitions/graphql_error" } }, "extensions": { "type": "object" } }}事件驱动架构 Schema {#event-driven}
示例 9:领域事件 Schema
场景:DDD 中的领域事件定义
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "领域事件", "type": "object", "definitions": { "money": { "type": "object", "properties": { "amount": { "type": "number", "minimum": 0 }, "currency": { "type": "string", "pattern": "^[A-Z]{3}$" } }, "required": ["amount", "currency"] } }, "oneOf": [ { "title": "订单创建事件", "properties": { "eventId": { "type": "string", "format": "uuid" }, "eventType": { "const": "OrderCreated" }, "aggregateId": { "type": "string" }, "occurredOn": { "type": "string", "format": "date-time" }, "payload": { "type": "object", "properties": { "orderId": { "type": "string" }, "customerId": { "type": "string" }, "items": { "type": "array", "items": { "type": "object", "properties": { "productId": { "type": "string" }, "quantity": { "type": "integer", "minimum": 1 }, "price": { "$ref": "#/definitions/money" } } } }, "totalAmount": { "$ref": "#/definitions/money" } } } }, "required": ["eventId", "eventType", "aggregateId", "occurredOn", "payload"] }, { "title": "订单支付事件", "properties": { "eventId": { "type": "string", "format": "uuid" }, "eventType": { "const": "OrderPaid" }, "aggregateId": { "type": "string" }, "occurredOn": { "type": "string", "format": "date-time" }, "payload": { "type": "object", "properties": { "orderId": { "type": "string" }, "paymentId": { "type": "string" }, "paymentMethod": { "type": "string" }, "paidAmount": { "$ref": "#/definitions/money" }, "paidAt": { "type": "string", "format": "date-time" } } } }, "required": ["eventId", "eventType", "aggregateId", "occurredOn", "payload"] }, { "title": "订单取消事件", "properties": { "eventId": { "type": "string", "format": "uuid" }, "eventType": { "const": "OrderCancelled" }, "aggregateId": { "type": "string" }, "occurredOn": { "type": "string", "format": "date-time" }, "payload": { "type": "object", "properties": { "orderId": { "type": "string" }, "reason": { "type": "string" }, "cancelledBy": { "type": "string" }, "cancelledAt": { "type": "string", "format": "date-time" } } } }, "required": ["eventId", "eventType", "aggregateId", "occurredOn", "payload"] } ]}总结
本文提供了 9 个来自真实项目的 JSON Schema 示例:
- REST API:用户 API 响应、分页列表
- 表单验证:用户注册、订单提交
- 配置文件:应用配置
- 微服务:服务间消息
- 数据管道:ETL 记录
- GraphQL:响应验证
- 事件驱动:领域事件
最佳实践总结:
- 使用 definitions 复用:避免重复定义
- 添加详细描述:便于理解和文档化
- 使用 $ref 引用:保持 Schema 模块化
- 提供示例数据:帮助理解和使用
- 版本控制:使用 $id 管理 Schema 版本
相关资源:
- JSON Schema Generator 工具 - 在线生成 Schema
- JSON Schema 完整指南 - 语法基础
- JSON Schema 最佳实践 - 设计技巧
- JSON Schema 常见问题 - 故障排除
使用这些示例作为起点,根据您的具体需求调整和扩展 Schema!
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
最后更新于 2026-01-17,距今已过 261 天
部分内容可能已过时
相关文章 智能推荐
1
JSON Schema 完整指南 - 从入门到精通
JSON 工具 全面掌握 JSON Schema 的完整指南。学习语法基础、类型系统、验证关键字、组合关键字、格式规范,包含丰富的实战示例。
2
JSON Schema 常见问题及解决方案 - 故障排除指南
JSON 工具 解决 JSON Schema 使用中的常见问题。学习验证错误、$ref 引用、类型验证、格式问题等故障排除技巧和解决方案。
3
JSON Schema 最佳实践 - 规范设计与性能优化
JSON 工具 掌握 JSON Schema 最佳实践,学习 Schema 设计原则、复用技巧、性能优化、错误处理、版本管理等实战经验。提升 Schema 可维护性和性能。
4
JSON Schema 验证集成指南与工作流自动化
技术教程 学习如何将 JSON Schema 验证集成到 Pre-commit Hook、CI Pipeline、Express 中间件和 MongoDB 中,实现全链路数据质量保障。
5
URL转JSON工具 - Query参数转JSON/JSON转Query在线(免费)
URL工具 在线 URL 参数转 JSON 工具:把 Query 参数或完整 URL 转为 JSON 对象,支持参数值类型识别(数字/布尔/null)与重复参数转数组;也支持 JSON 反向生成 Query。一键在星点 JSON 工具中打开,浏览器本地处理。
随机文章 随机推荐