[go]将 jsonSchema def 与 Go struct def 进行比较 - 在应用层而不是数据库层失败
· 收录于 2024-01-06 04:35:06 · source URL
问题详情
用于 mongodb 目的的 JsonSchema 如下所示:
package main
import (
"context"
"log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func main() {
jsonSchema := bson.M{
"bsonType": "object",
"required": []string{"name", "age"},
"properties": bson.M{
"name": bson.M{
"bsonType": "string",
"minLength": 1, // Minimum length of 1 character
"maxLength": 50, // Maximum length of 50 characters
"description": "must be a string with 1 to 50 characters and is required",
},
"age": bson.M{
"bsonType": "int",
"minimum": 0,
"description": "must be an integer greater than or equal to 0 and is required",
},
},
}
validationOptions := options.CreateCollection().SetValidator(bson.M{"$jsonSchema": jsonSchema})
err = db.CreateCollection(context.TODO(), "your_collection_name", validationOptions)
collection := db.Collection("your_collection_name")
newPerson := Person{Name: "John Doe", Age: 30} // NUM #1
insertResult, err := collection.InsertOne(context.Background(), newPerson)
// or we could do this instead:
newPerson := bson.D{{"name", "John Doe"}, {"age", 30}} // NUM #2
insertResult, err := collection.InsertOne(context.Background(), newPerson)
}
我的问题是 - 是否有可以验证人结构 (#1) 或 BSon 的库/技术。M person map (#2) 在插入到该数据库之前针对 jsonSchema 映射定义?这样,我们就可以在应用程序级别早期失败,并知道 struct/bson.M 声明与架构匹配。(并在应用层进行测试)。
最佳回答
这似乎有效,但如果有人知道更好的方法,请告诉我:
import (
"encoding/json"
"github.com/xeipuuv/gojsonschema"
)
func validateAgainstSchema(doc bson.M, jsonSchema string) error {
jsonDoc, err := json.Marshal(doc)
if err != nil {
return err
}
documentLoader := gojsonschema.NewStringLoader(string(jsonDoc))
schemaLoader := gojsonschema.NewStringLoader(jsonSchema)
result, err := gojsonschema.Validate(schemaLoader, documentLoader)
if err != nil {
return err
}
if !result.Valid() {
return errors.New(result.String())
}
return nil
}
bsonDoc := bson.M{"name": "John", "age": 30}
err := validateAgainstSchema(bsonDoc, yourJSONSchemaString)
if err != nil {
// Handle validation error
}