JSON Object validation with JSONSchema Validator - jsonschema

const Validator = require('jsonschema').Validator;
const validator = new Validator();
const obj =
[
{
"id":"1",
"firstname":"Jack"
}
];
const instance= {
properties: {
id: {
type: 'number'
},
firstname: {
type: 'string'
}
},
required: ['id', 'firstname'],
additionalProperties: false
};
const result = validator.validate(obj, instance);
console.log(result.errors);
I want to validate a JSON Object using jsonschema Validator. when json object is not as per schema, then also validate function is not returning any error. irrespective of obj being as per schema/instance or not, its error section always returning null.

You've defined obj as an array as opposed to an object. As a result, validation is passing because you've used JSON Schema keywords which only apply to objects. (Many JSON Schema keywords are only applicable to specific types.)
In your schema, add "type": "object", and you should see an error when the instance is not an object.
On a side note, an "instance" is the data you want to validate, and a "schema" is the JSON Schema you want to use for validation.

Related

How to destruct a complex object

One of my functions returns the object below:
Promise {
{
user: {
name: 'Ervin Howell',
email: 'Shanna#melissa.tv',
type: 'authenticated'
}
}
}
How to destruct user object from this json?
hi you can read the JSON API in this site. it has two methods:JSON.parse and JSON.sringify.
for your situation, you can use JSON.parse if your function return a JSON string
let json = "{
user: {
name: 'Ervin Howell',
email: 'Shanna#melissa.tv',
type: 'authenticated'
}
}
}"
obj = JSON.parse(json);
// when you want the user object
let user = obj.user
// when you want the user's name
let name = user.name

Ember: Must include an 'id' in an object passed to 'push'

Currently experiencing the following error: You must include an 'id' for failed-shotlist in an object passed to 'push'. This is in a code base I have inherited mid-development and I am fairly new to Ember.
From what I understand, this occurs when the backend does not respond with an ID. The server payload looks like the following (returning an alert object with an embedded failedShotlist record):
alertAuthor: "Test name"
alertDate:"2018-06-28T16:25:21+12:00"
alertIdentifier:"456e15c7-7a8b-11e8-84a8-06f4aef780e3"
alertType:"failedShotlist"
email:"test#gmail.com"
failedShotlist:
projectIdentifier:"79050dfb-5faf-11e8-84a8-06f4aef780e3"
projectName:"8888 st"
projectRoleENUM:"bp"
projectRoleName:"Building Participant"
shotlistDescription:"Framing"
shotlistIdentifier:"79d52773-5faf-11e8-84a8-06f4aef780e3"
inviteIdentifier:null
profileId:"c4e02bee-3d26-11e8-84a8-06f4aef780e3"
shotlistIdentifier:"79d52773-5faf-11e8-84a8-06f4aef780e3"
Since the backend doesn't respond with an ID attr, the primary key needs to be transformed using a serializer's 'primaryKey' property:
serializers/alert.js
export default ApplicationSerializer.extend(EmbeddedRecordsMixin, {
primaryKey: 'alertIdentifier',
attrs: {
'invite': { deserialize: 'records' },
'failedShotlist': { deserialize: 'records' },
},
});
I couldn't find any mention of this, but I assume that embedded records are further serialized by their own serializers. The existing one is as follows:
serializers/failedShotlist.js
export default ApplicationSerializer.extend({
attrs: {
'shotlistId': { key: 'shotlistIdentifier' },
'projectId': { key: 'projectIdentifier' },
},
});
Since the ID's for the failedShotlist object also need to be transformed, I have updated this to include the primaryKey prop:
serializers/failedShotlist.js
export default ApplicationSerializer.extend({
primaryKey: 'shotlistIdentifier',
attrs: {
'shotlistId': { key: 'shotlistIdentifier' },
'projectId': { key: 'projectIdentifier' },
},
});
Unfortunately, this results in the same error I originally encountered. Any ideas as to how this might be resolved?
Something I had overlooked was that the source files for the adapter and the serializer weren't following the naming convention of the rest of the codebase.
Where the serializer was called failedShotlist.js, the model related to it was called failed-shotlist.js.
Renaming the serializer file to failed-shotlist.js allowed my existing code to work:
export default ApplicationSerializer.extend({
primaryKey: 'shotlistIdentifier'
}

Is there buttons / funtion calls & tables handled in MetaWidget - js

I am wondering if some can help me out to get the buttons , function calls and tables displayed using metawidget jsonSchema.
Unfortunately, I can see it just as a form render-er for our applications, is it something which we need to define externally? also if we could navigate from one form to another somehow
<script type="text/javascript">
var mw = new metawidget.Metawidget( document.getElementById( 'metawidget' ), {
inspector: new metawidget.inspector.CompositeInspector( [ new metawidget.inspector.PropertyTypeInspector(),
function( toInspect, type, names ) {
return {
properties:
name: {
required: true
},
notes: {
type: "string",
large: true
},
employer: {
type: "string",
section: "Work"
},
department: {
type: "string"
}
}
};
} ] ),
layout: new metawidget.jqueryui.layout.TabLayoutDecorator(
new metawidget.layout.TableLayout( { numberOfColumns: 2 } ))
} );
mw.toInspect = person;
mw.buildWidgets();
Above schema holds only properties to render the fields, but where to specify the functionalities?
Assuming the object you are inspecting has functions, in JSON schema you can specify the property with a type of function. Metawidget will render these as buttons (and will wire up their click handler).
Note that PropertyTypeInspector will find functions automatically, so you could also consider combining your JsonSchemaInspector with a PropertyTypeInspector using CompositeInspector.
Often your data object (e.g. var person = { firstname: 'Homer', surname: 'Simpson' } ) and your actions object (e.g. var personActions = { save: function() {...}, delete: function() {...}} ) are separate. In those cases you can position two Metawidgets as siblings (or nested within each other), each pointing at different objects.
Finally for tables use a type of array. In JSON schema, you nest an items object that further nests a properties object, to describe the properties of the array items. See this example http://blog.kennardconsulting.com/2016/04/metawidget-and-angular-arrays.html (it's for Angular, but the JSON Schema is the same)

hapijs joi validation , just validate one field and to allow any field

I want to validate one field and to allow another fields without validation; by example just to validate: "firstname" field. In my code when I comment 'payload', hapi allow me to record any field, when I uncomment 'payload' hapijs dont allow me record any field, but I want just to validate by example 'firstname' to be a 'string' and let rest of fields to allow. I plan to have variable fields accord a database config, so I'm going to just validate some fixed fields and let to save another variable fields controlled in the front end, not in the backend
config: {
validate: {
/* payload: {
firstname: Joi.string(),
lastname: Joi.string()
...anothers fields...
}*/
}
}
UPDATED:
thanks to Robert K. Bell, i've adapted the solution is to add 'validate':
config: {
validate: {
options: {
allowUnknown: true
},
payload: {
firstname: Joi.string()
}
}
}
You may be looking for the .unknown() method:
object.unknown([allow])
Overrides the handling of unknown keys for the scope of the current object only (does not apply to children) where:
allow - if false, unknown keys are not allowed, otherwise unknown keys are ignored.
js
const schema = Joi.object({ a: Joi.any() }).unknown();
config: {
validate: {
payload: Joi.object({
'firstname': Joi.string(),
}).options({ allowUnknown: true })
}
}
Instead of adding validation fields in the validate validate the payload directly using Joi object. Which accepts allowUnknown true using this it will only validated only the fields which are mentioned in the Joi Object.
.... {allowUnknown: true}
as per doc, there is "options" method can be used while creating Joi objectSchema.
i.e. tobe very simple UI can send many keys but use only 2 keys email, and password. so a validation function can be defined as this.
function validateUserForSubscription(input) {
const schema = Joi.object({
email: Joi.string().min(5).max(255).required().email(),
password: Joi.string().min(5).max(1024).required()
}).options({ allowUnknown: true });
return schema.validate(input);
}
in other file use it like this.
const isValidUser = validateUserForSubscription(req.body);

How to manage data template when serving an api using Node.js

I'm currently trying to create an api for my web app using Node.js. The api intended to return JSON data to the api user.
For example, i'm having following endpoint / object:
- Articles (collection of article)
- Article (single article, each article would be having tags)
- Tags
Each endpoint / object having they own json data format need to return, in example:
Articles: [{articleObject}, {articleObject}, {articleObject}]
Article
{
id: 12,
title: 'My awesome article *i said and i know it',
content: 'blah blah blah blah',
tags: [{tagObject}, {tagObject}, {tagObject}]
}
Each endpoint can call to other endpoint to get needed data, in example:
Article endpoint can calling the Tags endpoint to get the article tags collection, the Tags endpoint will be returning Array Object.
My questions:
How to manage the Object structures, so if a endpoint called from another endpoint it will return Array / Object, while it will be return JSON string when called from api user.
Should I create Object template for each endpoint. The process will be:
Endpoint will be calling Object Template;
The Object Template will fetching data from database;
Endpoint will return the Object Template when called from other endpoint;
Endpoint will call template engine to parse the Object Template to JSON string for api user. JSON string view will be provided for each endpoint.
What Template Engine can process below Object Template and treat them as variables, in PHP i'm using Twig that can receive PHP Object and treat them as variables. Here you can find how i do that using Twig
Object Template file content example:
var Tags = require('./tags');
module.exports = function(param){
/* do fetching data from database for specified parameters */
/* here */
var data = {};
return {
id: function() {
return data.id;
},
title: function() {
return data.title;
},
description: function() {
return data.description;
},
tags: function() {
return Tags(data.id);
}
}
}
Hope someone can show me the way for it.
I use express to do my apis...you can do something like this:
app.get('/api/article', authenticate, routes.api.article.get);
authenticate is just a middleware function that authenticates the user, typically this is grabbing the user from session and making sure they are logged in.
inside ./routes/api.js
var Article = require('../models/article.js');
exports.api = {}
exports.api.article = {}
exports.api.article.get = function(req, res){
//get article data here
Article.find({created_by: req.session.user._id}).populate('tags').populate('created_by').exec(function(err, list){
res.json(list);
});
};
This assume you're using mongoose and mongodb and have an Article schema similar to this, which includes a reference to a Tag schema:
var ArticleSchema = new Schema({
name : { type: String, required: true, trim: true }
, description: { type: String, trim: true }
, tags : [{ type: Schema.ObjectId, ref: 'Tag', index: true }]
, created_by : { type: Schema.ObjectId, ref: 'User', index: true }
, created_at : { type: Date }
, updated_at : { type: Date }
});