This question already has an answer here:
Custom Properties in JSON Schema
(1 answer)
Closed 4 months ago.
language: {
type: "array",
items: {
type: "string",
enum: ["en", "es"],
},
ui_display: {"end": "English", "es": "Spanish"},
}
This is a JSON schema for an array. the "ui_display" field is obviously not a recognized property. Will anything break if I include it?
It's just a python dict/javascript object/whatever, so you can add properties as much as you like.
However, a lot of different things use JSON Schema. Some will be fine with this others will break I would think.
I know for example Connexion using OpenAPI will break, so there's at least one case which will break.
That being said, according to this answer (did you even google this before posting the question?) you can extend JSON Schema.
Related
I'm trying to understand how a single JSON Schema behaves when used in different validators. Some validators define custom keywords. For example ajv validator ajv-keywords package defines a prohibited keyword that is not part of the JSON Schema standard. JSON Schema on the other hand defines the required keyword that would seem to be the polar opposite of prohibited. JSON Schema also defines a oneOf combinator that can be used to validate that the input should match one and only one of several schema definitions.
Consider the following schema example. By reading the json schema specification, I get the impression that the example json schema should validate any json object when used in ajv. However, according to the unknown keyword rules, validators are supposed to ignore any keywords they do not support. So, I imagine that another validator would ignore the custom prohibited keyword, causing the schema to reject an input with property foo. Is this correct or am I failing to read the json schema specification?
{
"oneOf": [
{
"type": "object",
"required": ["foo"]
},
{
"type": "object",
"prohibited": ["foo"]
}
]
}
You are correct. A standard JSON Schema validator will fail validation for an object that has a property "foo". You should be very careful using non-standard keywords if you expect your schemas to be used by standard validators.
It should be okay to use custom keywords as long as you follow the principle of progressive enhancement. Effectively, that means the behavior should degrade as gracefully as possible if the custom keyword is ignored. Your example violates this principle because you end up with a false negative result if prohibited is ignored.
An simple example that does follow progressive enhancement might look like this...
{
"type": "object",
"properties": {
"foo": {}
},
"required": ["foo"],
"prohibited": ["bar"]
}
If I run this through a standard validator, all assertions work as expected except prohibited which is ignored. Assuming a client-server architecture, this allows clients to mostly validate their requests before sending them to the server. The server then does it's own validation with a validator that understands the custom keywords and can respond with an error if "bar" is present.
I want to describe the JSON my API will return using JSON Schema, referencing the schemas in my OpenAPI configuration file.
I will need to have a different schema for each API method. Let’s say I support GET /people and GET /people/{id}. I know how to define the schema of a "person" once and reference it in both /people and /people/{id} using $ref.
[EDIT: See a (hopefully) clearer example at the end of the post]
What I don’t get is how to define and reuse the structure of my response, that is:
{
"success": true,
"result" : [results]
}
or
{
"success": false,
"message": [string]
}
Using anyOf (both for the success/error format check, and for the results, referencing various schemas (people-multi.json, people-single.json), I can define a "root schema" api-response.json, and I can check the general validity of the JSON response, but it doesn’t allow me to check that the /people call returns an array of people and not a single person, for instance.
How can I define an api-method-people.json that would include the general structure of the response (from an external schema of course, to keep it DRY) and inject another schema in result?
EDIT: A more concrete example (hopefully presented in a clearer way)
I have two JSON schemas describing the response format of my two API methods: method-1.json and method-2.json.
I could define them like this (not a schema here, I’m too lazy):
method-1.json :
{
success: (boolean),
result: { id: (integer), name: (string) }
}
method-2.json :
{
success: (boolean),
result: [ (integer), (integer), ... ]
}
But I don’t want to repeat the structure (first level of the JSON), so I want to extract it in a response-base.json that would be somehow (?) referenced in both method-1.json and method-2.json, instead of defining the success and result properties for every method.
In short, I guess I want some kind of composition or inheritance, as opposed to inclusion (permitted by $ref).
So JSON Schema doesn’t allow this kind of composition, at least in a simple way or before draft 2019-09 (thanks #Relequestual!).
However, I managed to make it work in my case. I first separated the two main cases ("result" vs. "error") in two base schemas api-result.json and api-error.json. (If I want to return an error, I just point to the api-error.json schema.)
In the case of a proper API result, I define a schema for a given operation using allOf and $ref to extend the base result schema, and then redefine the result property:
{
"$schema: "…",
"$id": "…/api-result-get-people.json",
"allOf": [{ "$ref": "api-result.json" }],
"properties": {
"result": {
…
}
}
}
(Edit: I was previously using just $ref at the top level, but it doesn’t seem to work)
This way I can point to this api-result-get-people.json, and check the general structure (success key with a value of true, and a required result key) as well as the specific form of the result for this "get people" API method.
Could not find this answer online, so decided to post the question then the answer.
I created a table in the capabilities.json file:
"dataRoles": [
{
"displayName": "Stakeholders",
"name": "roleIwant",
"kind": "GroupingOrMeasure"
}
...
"dataViewMappings": [
{
"table": {
"rows": {
"select": [
{
"for": {
"in": "roleIwant"
}
}
]
}
}
}
]
I realized that I could not simply set, for instance, legend data from the first category, because the first category comes from the first piece of data the user drags in, regardless of position. So if they set a bunch of different pieces of data in Power BI online, for instance, then remove one, the orders of everything get messed up. I thought the best way to settle this would be to identify the role of each column and go from there.
When you click on show Dataview, the hierarchy clearly shows:
...table->columns[0]->roles: { "roleIwant": true }
So I thought I could access it like:
...table.columns[0].roles.roleIwant
but that is not the case. I was compiling using pbiviz start from the command prompt, which gives me an error:
error TYPESCRIPT /src/visual.ts : (56,50) Property 'roleIwant' does not exist on type '{ [name: string]: boolean; }'.
Why can I not access this in this way? I was thinking because natively, roles does not contain the property roleIwant, which is true, but that shouldn't matter...
The solution is actually pretty simple. I got no 'dot' help (typing a dot after roles for suggestions), but you can use regular object properties for roles. The command for this case would be:
...table.columns[0].roles.hasOwnProperty("roleIwant")
And the functional code portion:
...
columns.forEach((column) =>{
if(column.roles.hasOwnProperty("roleIwant")){
roleIwantData = dataview.categorical.categories[columns.indexOf(column)].values;
})
If it has the property, it belongs to that role. From here, the data saved will contain the actual values of that role! The only thing I would add on here is that if a column is used for multiple roles, depending on how you code, you may want to do multiple if's to check for the different roles belonging to a column instead of if else's.
If anyone has any further advice on the topic, or a better way to do it, by all means. I searched for the error, all over for ways to access columns' roles, and got nothing, so hopefully this topic helps someone else. And sorry for the wordiness - I tend to talk a lot.
Trying to generate JSON schema (http://jsonschema.net) from the syncthing (https://docs.syncthing.net/rest/system-connections-get.html) JSON below.
The problem is that the connection objects start with their ID (e.g.
YZJBJFX-RDB...) which is interpreted as a type.
Is it the JSON from synching that isn't standard or is it the issue with the schema generator?
Do you have any suggestions how to get around this if schema generation is a requirement (I.e. no typing schemas manually).
{
"total":{
"paused":false,
"clientVersion":"",
"at":"2015-11-07T17:29:47.691637262+01:00",
"connected":false,
"inBytesTotal":1479,
"type":"",
"outBytesTotal":1318,
"address":""
},
"connections":{
"YZJBJFX-RDBL7WY-6ZGKJ2D-4MJB4E7-ZATSDUY-LD6Y3L3-MLFUYWE-AEMXJAC":{
"connected":true,
"inBytesTotal":556,
"paused":false,
"at":"2015-11-07T17:29:47.691548971+01:00",
"clientVersion":"v0.12.1",
"address":"127.0.0.1:22002",
"type":"TCP (Client)",
"outBytesTotal":550
},
"DOVII4U-SQEEESM-VZ2CVTC-CJM4YN5-QNV7DCU-5U3ASRL-YVFG6TH-W5DV5AA":{
"outBytesTotal":0,
"type":"",
"address":"",
"at":"0001-01-01T00:00:00Z",
"clientVersion":"",
"paused":false,
"inBytesTotal":0,
"connected":false
},
"UYGDMA4-TPHOFO5-2VQYDCC-7CWX7XW-INZINQT-LE4B42N-4JUZTSM-IWCSXA4":{
"address":"",
"type":"",
"outBytesTotal":0,
"connected":false,
"inBytesTotal":0,
"paused":false,
"at":"0001-01-01T00:00:00Z",
"clientVersion":""
}
}
}
Any input is appreciated.
Is it the JSON from synching that isn't standard or is it the issue
with the schema generator?
There is nothing non-standard about this JSON. Neither is there any issue with the schema generation.
Unfortunately, defining a schema for what is effectively dynamic content is difficult. This will always be the case because the job of schemas is to describe static data structures.
That said, it may be possible to do this using the patternProperties field in JSON schema. This post is effectively asking the same question as yours.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
(I know there are post about data visualization, but none of them completely answered my question.)
I am looking for a tool to generate charts from data. I want to tool that is be able to do some computation for me, not only show the data a nice way.
For example here is data from tests I run:
{
"destination" : "30be317c-e586-4448-8fed-1a9481710670",
"source" : "30be317c-e586-4448-8fed-1a9481710670",
"userStatus" : "UNDEF",
"testName" : "VolumeUp",
"testStatus" : "WORKED",
"testStart" : 1323378809108,
"testEnd" : 1323378809108
}, {
"destination" : "30be317c-e586-4448-8fed-1a9481710670",
"source" : "30be317c-e586-4448-8fed-1a9481710670",
"userStatus" : "FAILED",
"testName" : "VolumeDown",
"testStatus" : "FAILED",
"testStart" : 1323378814065,
"testEnd" : 1323378816077
}
Note this is currently in JSON, but I can transform it to XML or push it to a database if needed.
What I would like to have is a way to tell the tool:
Create a table with:
Column one: number of "testStatus" : "WORKED"
Column two: number of "testStatus" : "FAILED"
Column three: percentage between one and two.
Rows: "testName"
Show the percentage higher than 90% in green
The calculations remain very basic.
I did some research and found tools that do it (JasperReport, SpagoBI, RapidMiner) but all of them seem to be too much of a pain to generate easy reports like mine.
Is there a tool/framework that could help me doing that?
Or will I have to do the calculations by myself and use a tool like Google Visualization API to show the output?
Thanks
I am not sure if understand correctly.
I understand that you have some data in json format. You can convert this data to xml or load to a database. And you need to visualize this data with special calculations and/or conditional formatting.
The first tool you can use is Excel. You can use Excel's built-in functions to process and visualize your data. I believe that Excel will be enough for your requirements.
If you are going to design a cube with your data you have 2 options. First, you can make these calculations at cube level or you can use the features of the tool you use to visualize your data.
If you design a cube, you can also use Excel. But if you need a more advanced tool, my first suggestion will be TARGIT because of it's ease of use. You can also use QlikView or Tableau. For more advanced solutions, you can go for Microsoft's SharePoint or OBIEE.
I would take a look at JavaScript libraries like Sencha (ext-JS).
Check out their documentation: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.grid.Panel
You can define a store with your data using the json format. You can add a field to your store based on the value of each record. If you need to have this value relative to all the others as percentile, you can listen to the 'load' event and traverse the records to calculate this 'high'/'low' value.
Ext.create('Ext.data.Store', {
storeId:'myStore',
fields:['destination', 'source', 'testName', 'testStatus', 'testStart', 'testEnd'],
data:{'items':[
// ... your data here
]},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});
Then you can create a grid view of your data, using any of their built-in views. You can define Renderer that will add a class with the calculated value. Using simple CSS you can color each class with a different color.
Ext.create('Ext.grid.Panel', {
title: 'My Data',
store: Ext.data.StoreManager.lookup('myStore'),
columns: [
{ header: 'Test Name', dataIndex: 'testName' },
{ header: 'Value',
dataIndex: 'calculatedValue',
renderer: function(value) {
return Ext.String.format('<span class="{0}">{1}</span>', value, value);
}
},
// Other columns
],
height: 200,
width: 400,
renderTo: Ext.getBody()
});
This is exactly where d3js shines. There are few data visualization JS frameworks out there, you can look at KendoUI and sencha UI you can use as well, but just like google chart APIs they do not help you with complex math. D3JS does.