How to filter JSON objects according to the "schema",

I am creating a RESTful api with node.js and express / koa.

I want to filter out JSON data input - for security reasons, to have only the necessary business properties. After filtering, a validation is performed for a specific business.

How can I discard unwanted properties of a JSON / JS object - that is, properties not in my database schema, as well as empty properties?

+5
source share
3 answers

I think joi is a good library for validation and normalization. You can also sometimes leave with something simple than _. Choose from lodash / underscore.

+4
source

You can use JSON schema validators.

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

Validators metrics: https://github.com/ebdrup/json-schema-benchmark

Disclaimer: I created ajv

+2
source

From the documentation, joi.validate () can discard fields, but only fields that are objects. I wrote this, avialable in gist , which seems to work fine. It returns a new object containing only those fields of the comparison object that have the same name and type corresponding to the corresponding field of the schema object:

// 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; } 

In the following test cases, invalid fields are cut correctly:

 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:

 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' ] 
+1
source

Source: https://habr.com/ru/post/1210261/


All Articles