JSON payload validates against schema even though field is missing - javascript

I assume I've missed something in defining the schema. Note that the id property is required under the form property, but it is not provided in the JSON, yet the JSON validates correctly according to multiple JSON validators online.
Schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.biz",
"type": "object",
"properties": {
"form": {
"type": "object",
"nullable": false,
"properties": {
"id": {
"type": "number",
"description": "The unique identifier of the form.",
"nullable": false
},
"name": {
"type": "string",
"description": "The name of the form.",
"nullable": false
}
}
}
}
}
JSON Payload
{
"form": {
"name": "Test 2"
}
}

Your schema doesn't specify which properties are required. You need to set required to the fields you want to be there. You may also wish to set additionalProperties to false.
Docs: https://json-schema.org/understanding-json-schema/reference/object.html#required-properties
I don't see nullable as a key anywhere in the json schema docs.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.biz",
"type": "object",
"properties": {
"form": {
"type": "object",
"properties": {
"id": {
"type": "number",
"description": "The unique identifier of the form."
},
"name": {
"type": "string",
"description": "The name of the form."
}
},
"required": ["id", "name"],
"additionalProperties": false
}
}
}

Related

Can we refer to the field of the object validating in JSON schema to minLength property of the declared JSON schema?

{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Text",
"description": "Form Text ",
"type": "object",
"properties": {
"value": {
"type": "string",
"default": "",
"minLength":"this needs to point to fieldSpecific.minLength of the validating object"
}
}
can we do something like this the object we receive to validate will be as below
{
"fieldSpecific": {
"minLength": 4
},
"value": "asfasfasfafasfasF"
}
in the above-received object we receive minLength under fieldSpecific can we write a JSON schema to refer minLength in field specific to validate the minLength of the value?
JSON Schema doesn't support this out of the box, but you can do it with JsonSchema.Net and the extension Data Vocabulary package.
The docs can be found on json-everything.net.
Here's what your schema would look like with this:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Text",
"description": "Form Text ",
"type": "object",
"properties": {
"value": {
"type": "string",
"default": "",
"data": {
"minLength": "/fieldSpecific/minLength"
}
}
}
Disclaimer: these libraries are mine.

Using the "watch" field in "description" in JSON editor

I'm using a JSON configuration schema which gets pushed to a website which should by using this JSON editor. And I would like to have the user input shown in the description field. Here is a snippet of the JSON file:
{
"type": "object",
"required": [
"file_name"
],
"properties": {
"file_name": {
"type": "string",
"title": "<h3>Table name</h3>",
"description": "Only alphanumeric characters dash and underscores are allowed.</br>Your data will be loaded to some_path.{your table name}",
"options": {
"inputAttributes": {
"placeholder": "your table name"
}
},
"propertyOrder": 100
}
}
}
I would like to have the "Table name" inputted by the user in the "description" field instead of {your table name}. According to the documentation you can use the "watch" variable:
{
"type": "object",
"properties": {
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"full_name": {
"type": "string",
"template": "{{fname}} {{lname}}",
"watch": {
"fname": "first_name",
"lname": "last_name"
}
}
}
}
But this doesn't work in the "description" field. Any ideas how I can deal with this?

ChaiJS jsonSchema check for multiple types

In my Chai-Test (using it for PostMan) I want to validate my API-response-design. For that I have written a Chai-Test:
pm.test("Check response schema", () => {
const schema = {
"type": "object",
"properties": {
"success": { "type": "boolean" },
"data": { "type": "object" },
"err": { "type": "object" },
"info": { "type": "string" }
},
"required": ["success", "data", "err", "info"]
}
pm.response.to.have.jsonSchema(schema)
})
My problem now is, that either the data or the err object is defined based on whether the request to the API was successful or not. I wanted to accomplish that by using two types for the data and the err: object AND null. So, how can I check for two types with the jsonSchema? Or is there an other and better way to do this?
You can do that:
"data": { "type": ["object", "null"] },
"err": { "type": ["object", "null"] }

LoopbackJS Get authenticated UserId to be stored against a model without exposing it via the API

I have the below "Content" model in Loopback which requires an authenticated user to access.
Each piece of Content can be created by only one user. (user is inherited from the Loopback internal User model) So when creating Content I would like the UserId to be stored in the Content record.
However, i'd like this to happen behind the scenes without having to pass through the userId via the API.
I've had a play with relations, but this doesn't seem to be working out..
{
"name": "Content",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"BooId": {
"type": "string",
"required": true
},
"Name": {
"type": "string",
"required": true
},
"Language": {
"type": "string",
"required": true,
"default": "en-gb"
},
"Version": {
"type": "number",
"default": 1
},
"Text": {
"type": "string",
"required": true
},
"Created": {
"type": "date",
"defaultFn": "now"
},
"Tags": {
"type": [
"string"
],
"default": []
}
},
"validations": [],
"relations": [],
"acls": [
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$unauthenticated",
"permission": "DENY"
}
],
"methods": {}
}
First of all, I would create a new relation for the content. So I would add the relation to your Content model:
"relations": {
"author": {
"type": "belongsTo",
"model": "user", // <-- your user model name
"foreignKey": ""
}
}
Then, you could use the before save hook to set the userId on your content model.
Or, you can simply just download this mixin to do it for you.
https://github.com/akkonrad/loopback-author-mixin

How to override and rename properties of User built-in model in Loopback Framework

I'm using the loopback framework to create a RESTful API for my application.
Following the documentation, I create my own Customer Model extending the built-in model User.
What I'm trying to achieve is:
How can I rename and remove some properties from this built-in model?
{
"name": "Cliente",
"plural": "Clientes",
"base": "User",
"idInjection": false,
"strict":"true",
...
}
{
"name": "User",
"properties": {
"realm": {
"type": "string"
},
"username": {
"type": "string"
},
"password": {
"type": "string",
"required": true
},
"email": {
"type": "string",
"required": true
},
"emailVerified": "boolean",
"verificationToken": "string"
},
...
}
I reached the results modyfing the loopbacks models inside the node modules, but this solution does not seem the right way, is there a way to config this in my code instead change loopback base models?
I think what you are trying to do is "rename" a property, am I correct?
If so, you can do the following:
"senha": {
"type": "string",
"id": true,
"required": true,
"index": true,
"postgresql": {
"columnName": "password"
}
}
Notice that I have a "postgresql" attribute, which depends on your database connector. Check it here. Inside that attribute I have a "columnName", which is the real name of that column in my database. So "senha" is the new name of that attribute.
For hiding the username property, you could do the following in the root object:
"hidden":["username"]
Your final file should look something like this:
{
"name": "Cliente",
"plural": "Clientes",
"base": "User",
"idInjection": false,
"strict": "true",
"properties": {
"realm": {
"type": "string"
},
"username": {
"type": "string"
},
"senha": {
"type": "string",
"required": true,
"postgresql": {
"columnName": "password"
}
},
"email": {
"type": "string",
"required": true
},
"emailVerified": "boolean",
"verificationToken": "string"
},
"hidden": ["username"]
}

Categories