Nodejs中schemajs太啰嗦了

Nodejs中schemajs太啰嗦了

http request 参数传到server JSON.parse后,属性的value均是string的,每次都是自己手动转成对应的类型,如Number、Date等。

schemajs 提供了通过自己定义输入参数的schema(指定属性类型),从而帮你生成所需的最终对象,属性类型都会根据schema帮你转好。这很类似于mongoose。

但是,其实我只想在schema中申明需要转型的属性,多余的别管太多,向下面这样要是写完完整的schema真的好辛苦。

var reviewDemo =
    {
        "reviewId" : "133",
        "reviewBody" : "烤羊棒子很好次,一人一根也就足够了,一边点评一边点的菜,酸奶,鱼鱼都是不错的 感觉很快能吃饱 三个人两百多没吃到几样菜。",
        "price" : { "priceTitle" : "价格", "priceValue" : "34", "unit" : "元" },
        "scores" : [
            {      "scoreTitle" : "环境",      "scoreValue" : "3",      "scoreDescribe" : "好" },
            {      "scoreTitle" : "服务",      "scoreValue" : "3",      "scoreDescribe" : "好" },
            {      "scoreTitle" : "口味",      "scoreValue" : "4",      "scoreDescribe" : "很好" }
        ],
        "tags" : [ { "tagTitle" : "餐厅氛围", "tagValueList" : [ "商务宴请", "朋友聚会" ]  } ]
    }
var reviewModel = schemajs.create(
    {
        reviewId : { type:'int', filters:['trim', 'toInt'], required:true, error:'review must has a reviewId' },
        price : {
            type:'object',
            schema:{
                priceValue : { type:'float', filters:['trim', 'toFloat'], properties:{min:0}, error:'priceValue is not a valid priceValue' }
            }
        }
    }
);

var form = reviewModel.validate(reviewDemo); console.log(util.inspect(form.data));

但人家schemajs说了:‘strict mode, dissallowing extra parameters from being passed in’。 上面这样写schema,没定义的属性全没了,泪奔~

大家是怎么解决的?


2 回复

Node.js 中 schemajs 太啰嗦了

在处理 HTTP 请求时,从客户端传递到服务器的数据通常是以 JSON 形式接收的。这些数据中的属性值通常是字符串类型。每次都需要手动将这些字符串转换为相应的类型(例如 NumberDate 等)。

schemajs 提供了一种方式来定义输入参数的模式(schema),从而帮助你生成所需的对象,并自动进行类型转换。这种方式类似于 Mongoose 的模型定义。然而,有时候我们只希望在 schema 中声明需要进行类型转换的属性,而不希望对其他属性做过多的约束,以免丢失未定义的属性。

示例代码

假设我们有以下 JSON 数据:

{
    "reviewId": "133",
    "reviewBody": "烤羊棒子很好次,一人一根也就足够了,一边点评一边点的菜,酸奶,鱼鱼都是不错的 感觉很快能吃饱 三个人两百多没吃到几样菜。",
    "price": {
        "priceTitle": "价格",
        "priceValue": "34",
        "unit": "元"
    },
    "scores": [
        {
            "scoreTitle": "环境",
            "scoreValue": "3",
            "scoreDescribe": "好"
        },
        {
            "scoreTitle": "服务",
            "scoreValue": "3",
            "scoreDescribe": "好"
        },
        {
            "scoreTitle": "口味",
            "scoreValue": "4",
            "scoreDescribe": "很好"
        }
    ],
    "tags": [
        {
            "tagTitle": "餐厅氛围",
            "tagValueList": ["商务宴请", "朋友聚会"]
        }
    ]
}

我们可以使用 schemajs 来定义一个 schema,但不希望丢失未定义的属性。为此,可以使用 schemajsstrict 选项来放宽约束。

const schemajs = require('schemajs');
const util = require('util');

// 定义 schema
var reviewSchema = {
    reviewId: { type: 'int', required: true, error: 'review must have a reviewId' },
    price: {
        type: 'object',
        schema: {
            priceValue: { type: 'float', properties: { min: 0 }, error: 'priceValue is not a valid priceValue' }
        }
    }
};

// 创建 schema 实例
var reviewModel = schemajs.create({
    ...reviewSchema,
    strict: false // 放宽约束,允许额外的属性
});

var reviewDemo = {
    reviewId: "133",
    reviewBody: "烤羊棒子很好次,一人一根也就足够了,一边点评一边点的菜,酸奶,鱼鱼都是不错的 感觉很快能吃饱 三个人两百多没吃到几样菜。",
    price: {
        priceTitle: "价格",
        priceValue: "34",
        unit: "元"
    },
    scores: [
        {
            scoreTitle: "环境",
            scoreValue: "3",
            scoreDescribe: "好"
        },
        {
            "scoreTitle": "服务",
            "scoreValue": "3",
            "scoreDescribe": "好"
        },
        {
            "scoreTitle": "口味",
            "scoreValue": "4",
            "scoreDescribe": "很好"
        }
    ],
    tags: [
        {
            tagTitle: "餐厅氛围",
            tagValueList: ["商务宴请", "朋友聚会"]
        }
    ]
};

// 验证并转换数据
var form = reviewModel.validate(reviewDemo);
console.log(util.inspect(form.data));

在这个例子中,我们通过设置 strict: false 来放宽 schema 的约束,使得未定义的属性不会被丢弃。这样就可以避免丢失任何未定义的属性,同时仍然能够进行必要的类型转换。

总结

schemajs 可以帮助你在 Node.js 中更好地管理和验证输入数据,但有时默认的严格模式可能会导致不必要的问题。通过设置 strict: false,你可以更灵活地处理输入数据,保留所有未定义的属性,同时仍然能够进行类型转换。


对于这个问题,确实 schemajs 的严格模式会过滤掉未定义的属性。如果你希望保留所有未定义的属性,并只转换特定的类型,可以使用 schemajsoptions 参数来关闭严格模式。

以下是具体的解决方案:

const Schemajs = require('schemajs');

const reviewDemo = {
    "reviewId": "133",
    "reviewBody": "烤羊棒子很好次,一人一根也就足够了,一边点评一边点的菜,酸奶,鱼鱼都是不错的 感觉很快能吃饱 三个人两百多没吃到几样菜。",
    "price": { "priceTitle": "价格", "priceValue": "34", "unit": "元" },
    "scores": [
        { "scoreTitle": "环境", "scoreValue": "3", "scoreDescribe": "好" },
        { "scoreTitle": "服务", "scoreValue": "3", "scoreDescribe": "好" },
        { "scoreTitle": "口味", "scoreValue": "4", "scoreDescribe": "很好" }
    ],
    "tags": [{ "tagTitle": "餐厅氛围", "tagValueList": ["商务宴请", "朋友聚会"] }]
};

const reviewModel = Schemajs.create({
    reviewId: { type: 'int', filters: ['trim', 'toInt'], required: true, error: 'review must has a reviewId' },
    price: {
        type: 'object',
        schema: {
            priceValue: { type: 'float', filters: ['trim', 'toFloat'], properties: { min: 0 }, error: 'priceValue is not a valid priceValue' }
        }
    }
}, { strict: false }); // 关闭严格模式

const form = reviewModel.validate(reviewDemo);
console.log(util.inspect(form.data)); // 输出完整的 reviewDemo 对象,仅特定属性被转换

解释

  • 关闭严格模式:通过传递 { strict: false } 选项给 Schemajs.create 函数,允许保留未定义的属性。
  • 属性转换:只有你在 reviewModel 中定义的属性会被处理和转换类型,其他未定义的属性将保持不变。

这样,你可以保留所有原始数据,同时仅对指定属性进行类型转换。

回到顶部