Swift JSON Schema 库提供了一种类型安全的方式,可以直接在 Swift 中生成和验证 JSON schema 文档。
请查看这个示例仓库,它使用 swift-json-schema
来创建类型安全的 OpenAI API 函数工具调用。
利用 Swift result builders 的强大功能来生成 JSON schema 文档。
@JSONSchemaBuilder var personSchema: some JSONSchemaComponent {
JSONObject {
JSONProperty(key: "firstName") {
JSONString()
.description("The person's first name.")
}
JSONProperty(key: "lastName") {
JSONString()
.description("The person's last name.")
}
JSONProperty(key: "age") {
JSONInteger()
.description("Age in years which must be equal to or greater than zero.")
.minimum(0)
}
}
.title("Person")
}
{
"$id": "https://example.com/person.schema.json",
"$schema": "https://json-schema.fullstack.org.cn/draft/2020-12/schema",
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The person's first name."
},
"lastName": {
"type": "string",
"description": "The person's last name."
},
"age": {
"description": "Age in years which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0
}
}
}
使用来自 JSONSchemaBuilder
的 @Schemable
宏来自动生成 result builders。
@Schemable
struct Person {
let firstName: String
let lastName: String?
@NumberOptions(minimum: 0, maximum: 120)
let age: Int
}
struct Person {
let firstName: String
let lastName: String?
let age: Int
// Auto-generated schema ↴
static var schema: some JSONSchemaComponent<Person> {
JSONSchema(Person.init) {
JSONObject {
JSONProperty(key: "firstName") {
JSONString()
}
.required()
JSONProperty(key: "lastName") {
JSONString()
}
JSONProperty(key: "age") {
JSONInteger()
.minimum(0)
.maximum(120)
}
.required()
}
}
}
}
extension Person: Schemable {}
@Schemable
可以应用于枚举 (enums)。
@Schemable
enum Status {
case active
case inactive
}
enum Status {
case active
case inactive
static var schema: some JSONSchemaComponent<Status> {
JSONString()
.enumValues {
"active"
"inactive"
}
.compactMap {
switch $0 {
case "active":
return Self.active
case "inactive":
return Self.inactive
default:
return nil
}
}
}
}
extension Status: Schemable {}
也支持使用 anyOf
schema 组合的带有关联值的枚举。有关更多信息,请参阅 JSONSchemaBuilder 文档。
使用 Schema
类型,您可以针对 schema 验证 JSON 数据。
let schemaString = """
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1
}
}
}
"""
let schema1 = try Schema(instance: schemaString)
let result = try schema1.validate(instance: #"{"name": "Alice"}"#)
或者,您可以使用 JSONSchemaBuilder
构建器(或 宏)来创建 schema 并验证实例。
let nameBuilder = JSONObject {
JSONProperty(key: "name") {
JSONString()
.minLength(1)
}
}
let schema = nameBuilder.defintion()
let instance1: JSONValue = ["name": "Alice"]
let instance2: JSONValue = ["name": ""]
let result1 = schema.validate(instance1)
dump(result1, name: "Instance 1 Validation Result")
let result2 = schema.validate(instance2)
dump(result2, name: "Instance 2 Validation Result")
▿ Instance 1 Validation Result: JSONSchema.ValidationResult
- isValid: true
▿ keywordLocation: #
- path: 0 elements
▿ instanceLocation: #
- path: 0 elements
- errors: nil
▿ annotations: Optional([JSONSchema.Annotation<JSONSchema.Keywords.Properties>(keyword: "properties", instanceLocation: #, schemaLocation: #/properties, absoluteSchemaLocation: nil, value: Set(["name"]))])
▿ some: 1 element
▿ JSONSchema.Annotation<JSONSchema.Keywords.Properties>
- keyword: "properties"
▿ instanceLocation: #
- path: 0 elements
▿ schemaLocation: #/properties
▿ path: 1 element
▿ JSONSchema.JSONPointer.Component.key
- key: "properties"
- absoluteSchemaLocation: nil
▿ value: 1 member
- "name"
▿ Instance 2 Validation Result: JSONSchema.ValidationResult
- isValid: false
▿ keywordLocation: #
- path: 0 elements
▿ instanceLocation: #
- path: 0 elements
▿ errors: Optional([JSONSchema.ValidationError(keyword: "properties", message: "Validation failed for keyword \'properties\'", keywordLocation: #/properties, instanceLocation: #, errors: Optional([JSONSchema.ValidationError(keyword: "minLength", message: "The string length is less than the specified \'minLength\'.", keywordLocation: #/properties/name/minLength, instanceLocation: #/name, errors: nil)]))])
▿ some: 1 element
▿ JSONSchema.ValidationError
- keyword: "properties"
- message: "Validation failed for keyword \'properties\'"
▿ keywordLocation: #/properties
▿ path: 1 element
▿ JSONSchema.JSONPointer.Component.key
- key: "properties"
▿ instanceLocation: #
- path: 0 elements
▿ errors: Optional([JSONSchema.ValidationError(keyword: "minLength", message: "The string length is less than the specified \'minLength\'.", keywordLocation: #/properties/name/minLength, instanceLocation: #/name, errors: nil)])
▿ some: 1 element
▿ JSONSchema.ValidationError
- keyword: "minLength"
- message: "The string length is less than the specified \'minLength\'."
▿ keywordLocation: #/properties/name/minLength
▿ path: 3 elements
▿ JSONSchema.JSONPointer.Component.key
- key: "properties"
▿ JSONSchema.JSONPointer.Component.key
- key: "name"
▿ JSONSchema.JSONPointer.Component.key
- key: "minLength"
▿ instanceLocation: #/name
▿ path: 1 element
▿ JSONSchema.JSONPointer.Component.key
- key: "name"
- errors: nil
- annotations: nil
注意: 动态引用、词汇表和其他高级功能尚未支持。该库仍在开发中,将来会添加更多功能。 请参阅 当前不支持的测试,来自 JSON Schema 测试套件。
当使用构建器或 宏时,您还可以将 JSON 实例解析为 Swift 类型。
@Schemable
enum TemperatureUnit {
case celsius
case fahrenheit
}
@Schemable
struct Weather {
let temperature: Double
let unit: TemperatureUnit
let conditions: String
}
let data = """
{
"temperature": 20,
"unit": "celsius",
"conditions": "Sunny"
}
"""
let weather: Parsed<Weather, ParseIssue> = Weather.schema.parse(instance: data)
可以选择将解析和验证合并为一个步骤。
let weather: Weather = try Weather.schema.parseAndValidate(instance: data)
感谢 swift-parsing 库和 Point-Free Parsing 系列,它们为解析 API 和实现提供了灵感。
该库的完整文档可通过 Swift Package Index 获得。
您可以使用 Swift Package Manager (SPM) 或 Xcode 将 SwiftJSONSchema 包添加到您的项目中。
要使用 Swift Package Manager 将 SwiftJSONSchema 添加到您的项目,请将以下依赖项添加到您的 Package.swift 文件中
dependencies: [
.package(url: "https://github.com/ajevans99/swift-json-schema", from: "0.2.1")
]
然后,将 JSONSchema
和/或 JSONSchemaBuilder
作为目标的依赖项包含进去
targets: [
.target(
name: "YourTarget",
dependencies: [
.product(name: "JSONSchema", package: "swift-json-schema"),
.product(name: "JSONSchemaBuilder", package: "swift-json-schema"),
]
)
]
添加后,您可以在您的 Swift 文件中导入 JSONSchema
并开始在您的项目中使用它。
该库是在 MIT 许可证下发布的。 有关详细信息,请参阅 LICENSE。