2015-01-02 11 views
5

Costruisco un api RESTful con node.js ed express/koa.Come filtrare gli oggetti JSON secondo lo "schema"

Desidero filtrare l'input di dati JSON, anche per motivi di sicurezza, per avere solo le proprietà specifiche del business necessarie. Dopo il filtraggio avviene la convalida specifica del business.

In che modo è possibile eliminare le proprietà indesiderate dell'oggetto JSON/JS, ovvero le proprietà non presenti nello schema del database e le proprietà vuote?

risposta

4

Penso che joi sia una buona libreria per la convalida e la normalizzazione. A volte puoi anche farla franca con qualcosa di semplice come _.pick da lodash/underscore.

1

Dalla documentazione, joi.validate() può rimuovere campi, ma solo campi che sono Oggetti. Ho scritto questo, disponibile in un gist, che sembra funzionare bene. Restituisce un nuovo oggetto contenente solo i campi nell'oggetto confronto che hanno lo stesso nome e tipo del campo corrispondente nell'oggetto schema:

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

I seguenti casi di test correttamente striscia su campi non corretti:

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); 

Risultati:

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' ]