如何根据“模式”过滤JSON对象

我使用node.js和express / koa构build了一个RESTful API。

我想过滤JSON数据input – 出于安全原因,以及只有需要的业务特定的属性。 过滤后,业务特定的validation发生。

我如何扔掉不需要的JSON / JS对象属性 – 即属性不在我的数据库架构以及空属性?

  • 根据这个定义架构和filter? 使用例如https://github.com/alank64/json-schema-filter
  • 任何可configuration的过滤可用?

我认为joi是一个validation和规范化的好库。 你也可以通过lodash /下划线中的_.pick来简化它。

您可以考虑使用JSON模式validation器。

http://json-schema.org/implementations.html

validation器基准: https : //github.com/ebdrup/json-schema-benchmark

免责声明:我创build了ajv

从文档中,joi.validate()可以剥离字段,但只能是对象字段。 我写了这个,在一个主意 ,这似乎工作正常。 它返回一个只包含比较对象中与模式对象中的相应字段具有相同名称和types的字段的新对象:

// Recursively strip out fields in objects and subobjects function stripFields(schema, obj) { var newObj = {}; var schemaType = schema.constructor.name; var objType = obj.constructor.name; // If types match and this property is not an Object, return the value if (schemaType !== "Object") { if(schemaType === objType) { return obj; } else { return null; } } var keys = Object.keys(schema); keys.forEach(function(key) { if(key in obj) { // Get instance names for properties var schemaConstructor = schema[key].constructor.name; var objConstructor = obj[key].constructor.name; // Only copy fields with matching types. if (schemaConstructor === objConstructor) { // Handle cases with subObjects if (objConstructor === "Object") { var res = stripFields(schema[key], obj[key]); if (res !== null) { newObj[key] = res; } } else { // Just copy in non-Object properties (String, Boolean, etc.) newObj[key] = obj[key]; } } }; if (newObj === {}) { return null; } }); return newObj; } 

以下testing用例正确删除不正确的字段:

 var stripFields = require("./stripfields"); var schema = { a: 1, b: 1, c:{ foo:"bar", obj:{nestedField:1} }, d:[1] }; var testObj1 = { a: 7, b: 8, c:{ foo:"bar" }, d:[4,5] }; var testObj2 = { a: 1, b: 2, c:{ foo:"bar", obj:{nestedField:213} }, d:[1,3,4], e:"someOtherField" }; var testObj3 = { a: 1, c:{ foo:"some string", bar:1 }, d:"string instead of array" }; var res1 = stripFields(schema, testObj1); var res2 = stripFields(schema, testObj2); var res3 = stripFields(schema, testObj3); var res4 = stripFields([1,2,3], ["a"]); console.log("Results:"); console.log(res1); console.log(res2); console.log(res3); console.log(res4); 

结果:

 Results: { a: 7, b: 8, c: { foo: 'bar' }, d: [ 4, 5 ] } { a: 1, b: 2, c: { foo: 'bar', obj: { nestedField: 213 } }, d: [ 1, 3, 4 ] } { a: 1, c: { foo: 'some string' } } [ 'a' ]