santhosh-tekuri/jsonschema

Validating using part of document?

Closed this issue · 4 comments

Hi, I'm looking at various golang JSON-Schema validators, I like this one mostly because it exposes the Schema struct. But my use case is to decode documents that contains JSON schema (and JSON pointers) but is not a pure JSON Schema document. And then validating structs against Schema in that document.

This does not seem possible right now (results in 'unknown $schema "some url"'). Do you have any advice to get around this?

Thanks.

yes. you can do that. for example consider following file "component.json"

{
    "name": "DBInsert",
    "ports": {
        "input" : {
            "schema": {
			   "$schema": "http://json-schema.org/draft-04/schema#",
			   "title": "Product",
			   "description": "A product from Acme's catalog",
			   "type": "object",
				
			   "properties": {
				
				  "id": {
					 "description": "The unique identifier for a product",
					 "type": "integer"
				  },
					
				  "name": {
					 "description": "Name of the product",
					 "type": "string"
				  },
					
				  "price": {
					 "type": "number",
					 "minimum": 0,
					 "exclusiveMinimum": true
				  }
			   },
				
			   "required": ["id", "name", "price"]
			}
        },
        "output": {
            "schema": {
			  "$schema": "http://json-schema.org/draft-07/schema#",
			  "$id": "http://example.com/product.schema.json",
			  "title": "Product",
			  "description": "A product from Acme's catalog",
			  "type": "object",
			  "properties": {
				"productId": {
				  "description": "The unique identifier for a product",
				  "type": "integer"
				}
			  },
			  "required": [ "productId" ]
			}
        }
    }
}

there are two jsonschemas embedded in above json. one for input and another for output

to load jsonschemas:

inschema, err := jsonschema.Compile("component.json#/ports/input")
if err!=nil {
    panic(err)
}
outschema, err := jsonschema.Compile("component.json#/ports/output")
if err!=nil {
    panic(err)
}

i.e, you can specify jsonpointer after the filename separated by #

Thanks for the reply. That is pretty close to what I need.

I'm looking at something like this (YAML instead of JSON for readability only):

schema_property_a:
  ...
schema_property_b:
  ...
sub_documents:
  - schema_property_a:
      ...
    schema_property_b:
      ...
    sub_documents:
      -  ... etc

I looked a little closer at the code and see that jsonschema.Compile("file.json#/schema_property_a") followed by jsonschema.Compile("file.json#/schema_property_b") will internally result in a single resource with two Schema objects in a map by ref.

I'll need to traverse down the document into a potentially large number subdocument. I could just recursively build the refs until I hit an invalid reference but that seems terribly inefficient. If I had access to resource.doc and maybe Compiler.compile(), I could just traverse the data structure and create Schema objects from data I know to be JSON-Schema..

yes. resources are cached in compiler for reuse.

for your json document, resource.doc will be of type map[string]interface{}. so even if you have access to this field, you still need to parse the map recursively to find potential schema documents.
only difference will be you have avoiding parsing json document into map[string][interface{}]

why can't you simply parse json doucment into map[string][interface{}]. traverse it recursively to find potential schemas and find jsonpointer's to them

I guess I could do something like that. Initialization performance is not critical anyway. Thanks for the info :)