[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
}