Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sgpinkus/6770770f02a5af29fe3b0481072952f5 to your computer and use it in GitHub Desktop.
Save sgpinkus/6770770f02a5af29fe3b0481072952f5 to your computer and use it in GitHub Desktop.

Overview

This document provides a brief numerical analysis of the use of the JSON Schema $id keyword in schema documents contained in the schemastore.org collection. Scripts to generate stats are attached.

Overview Statisitics

TOTAL FILES: 310
SCHEMAS USED:
      1 http://json-schema.org/draft-03/schema
      5 http://json-schema.org/draft/2019-09/schema
      6 http://json-schema.org/draft-06/schema
      6 http://json-schema.org/schema
     74 http://json-schema.org/draft-07/schema
    218 http://json-schema.org/draft-04/schema
NO SCHEMA DECLARED: 0
NUM FILES THAT USE '$id' AT ALL: 46
NUM FILES THAT USE '$id' ONLY AT ROOT: 30
NUM FILES THAT USES '$id' BEYOND ROOT: 16
THE FILES THAT USES '$id' BEYOND ROOT:
container-structure-test.json
cryproj.52.schema.json
cryproj.53.schema.json
cryproj.54.schema.json
cryproj.55.schema.json
cryproj.dev.schema.json
cryproj.json
datalogic-scan2deploy-android.json
datalogic-scan2deploy-ce.json
gitversion.json
hemtt-0.6.2.json
neoload.json
nest-cli.json
nodehawkrc.json
ocelot.json
pgap_yaml_input_reader.json

Usage of $id Beyond The Root

  • Of the 16 files that use $id beyond the root, most occurances simply set the $id to the JSON Pointer path of the object, sometimes prepended with "#", sometimes not.
  • Of the 16 files, 10 files have occurances of $id that is not at the root and is not a "$id is the JSON Pointer" case. These are shown below.
  • In all 16 cases one of the following is true:
    • Relative base URI resolution descibed in the JSON Schema specifications would not have different behaviour to base resolution against a document wide base URI.
    • Relative base URI resolution would result in $refs that do not resolve to valid JSON.
cryproj.52.schema.json
Found $id at /properties/require/properties/plugins/items/properties/platforms: /properties/plugins/items/properties/platforms
Found $id at /properties/require/properties/plugins/items/properties/platforms/items: /properties/plugins/items/properties/platforms/items
cryproj.53.schema.json
Found $id at /properties/require/properties/plugins/items/properties/platforms: /properties/plugins/items/properties/platforms
Found $id at /properties/require/properties/plugins/items/properties/platforms/items: /properties/plugins/items/properties/platforms/items
cryproj.54.schema.json
Found $id at /properties/require/properties/plugins/items/properties/platforms: /properties/plugins/items/properties/platforms
Found $id at /properties/require/properties/plugins/items/properties/platforms/items: /properties/plugins/items/properties/platforms/items
cryproj.55.schema.json
Found $id at /properties/require/properties/plugins/items/properties/platforms: /properties/plugins/items/properties/platforms
Found $id at /properties/require/properties/plugins/items/properties/platforms/items: /properties/plugins/items/properties/platforms/items
cryproj.dev.schema.json
Found $id at /properties/require/properties/plugins/items/properties/platforms: /properties/plugins/items/properties/platforms
Found $id at /properties/require/properties/plugins/items/properties/platforms/items: /properties/plugins/items/properties/platforms/items
cryproj.json
Found $id at /properties/require/properties/plugins/items/properties/platforms: /properties/plugins/items/properties/platforms
Found $id at /properties/require/properties/plugins/items/properties/platforms/items: /properties/plugins/items/properties/platforms/items
hemtt-0.6.2.json
Found $id at /properties/scripts/additionalProperties: #/properties/scripts/properties/
Found $id at /properties/scripts/additionalProperties/properties/steps: #/properties/scripts/properties//properties/steps
Found $id at /properties/scripts/additionalProperties/properties/steps/items: #/properties/scripts/properties//properties/steps/items
Found $id at /properties/scripts/additionalProperties/properties/steps_linux: #/properties/scripts/properties//properties/steps_linux
Found $id at /properties/scripts/additionalProperties/properties/steps_linux/items: #/properties/scripts/properties//properties/steps_linux/items
Found $id at /properties/scripts/additionalProperties/properties/steps_windows: #/properties/scripts/properties//properties/steps_windows
Found $id at /properties/scripts/additionalProperties/properties/steps_windows/items: #/properties/scripts/properties//properties/steps_windows/items
Found $id at /properties/scripts/additionalProperties/properties/show_output: #/properties/scripts/properties//properties/show_output
Found $id at /properties/scripts/additionalProperties/properties/foreach: #/properties/scripts/properties//properties/foreach
Found $id at /properties/scripts/additionalProperties/properties/parallel: #/properties/scripts/properties//properties/parallel
neoload.json
Found $id at /properties/includes: #root/includes
Found $id at /properties/variables: #root/variables
Found $id at /properties/servers: #root/servers
Found $id at /properties/sla_profiles: #root/sla_profiles
Found $id at /properties/populations: #root/populations
Found $id at /properties/scenarios: #root/scenarios
Found $id at /properties/user_paths: #root/user_paths
Found $id at /definitions/server/properties/scheme: #root/servers/items/scheme
Found $id at /definitions/sla/properties/thresholds: #/definitions/sla/thresholds
Found $id at /definitions/populations/population: #/definitions/population
Found $id at /definitions/scenario/properties/populations: #/definitions/scenario/populations
Found $id at /definitions/scenario/properties/populations/items: #/definitions/scenario/populations/items
nest-cli.json
Found $id at /definitions/CompilerOptions: #CompilerOptions
Found $id at /definitions/GenerateOptions: #GenerateOptions
Found $id at /definitions/ProjectConfiguration: #ProjectConfiguration
pgap_yaml_input_reader.json
Found $id at /properties/$schema: /$schema
git clone git@github.com:SchemaStore/schemastore.git
cd schemastore/src/schemas/json
#!/bin/bash
total_files=$(ls -1 *.json | wc -l)
schemas=$( (jq '.["$schema"]' *.json -r | sed -r 's/#$//;s/^https/http/' | sort | uniq -c | sort -n) )
no_schema_count=( $(jq '.["$schema"]' *.json -r | grep "^null" ) )
uses_id=( $(jq '.["id"]' *.json | egrep -v "^null") )
uses_dollar_id=( $(egrep '"\$id"' -nrI *.json -l) )
uses_dollar_id_at_root=( $(jq '.["$id"]' *.json | egrep -v "^null" | wc -l) )
uses_dollar_id_once=( $(egrep '"\$id"' *.json -c | egrep ":1$" | sed -r 's/:1$//') )
uses_dollar_id_once_at_root=( $(jq '.["$id"]' $(echo "${uses_dollar_id_once[@]}") -r | grep -v "^null") )
uses_dollar_id_more_than_once=( $(egrep '"\$id"' *.json -c | egrep -v "(:1|:0)$" | sed -r 's/:[0-9]+$//') )
uses_dollar_id_more_than_once_and_at_root=( $(jq '.["$id"]' $(echo "${uses_dollar_id_more_than_once[@]}") | grep -v "^null" | wc -l) )
uses_dollar_id_fragment=( $(egrep '"\$id":\s*\"#' -nrI *.json -l) )
cat <<EOF
TOTAL FILES: ${total_files}
SCHEMAS USED:
${schemas}
NO SCHEMA DECLARED: ${no_schema_count:-0}
NUM FILES THAT USE '\$id' AT ALL: ${#uses_dollar_id[@]}
NUM FILES THAT USE '\$id' ONLY AT ROOT: ${#uses_dollar_id_once_at_root[@]}
NUM FILES THAT USES '\$id' BEYOND ROOT: ${#uses_dollar_id_more_than_once[@]}
THE FILES THAT USES '\$id' BEYOND ROOT:
$(echo ${uses_dollar_id_more_than_once[@]} | sed -r 's/\s+/\n/g')
EOF
#!/usr/bin/env node
const fs = require('fs');
o = JSON.parse(fs.readFileSync(process.argv[2]))
const results = walk(o, '')
if(results.length) {
console.log(process.argv[2])
console.log(results.join('\n'))
}
function walk(o, path='', results = []) {
if(!o instanceof Object) {
throw new TypeError()
}
if(o instanceof Array) {
for(i in o) {
if(o[i] instanceof Object) {
walk(o[i], `${path}/$i`, results)
}
}
}
else {
for([k,v] of Object.entries(o)) {
if(k == '$id') {
if(path !== v.replace(/^#/, '') && path) {
results.push(`Found $id at ${path}: ${v}`)
}
}
if(v instanceof Object) {
walk(v, `${path}/${k}`, results)
}
}
}
return results
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment