worldturner/medeia-validator

Support for relative files in $ref

jebbench opened this issue · 5 comments

I would be really handy to have the ability to split a schema into multiple files and be able to reference these files using $ref - currently using "$ref": "./attribute.json" gives the error java.lang.IllegalArgumentException: Invalid schema combination, unresolved $ref references: attribute.json.

Setting the base url when creating the SchemaSource results in the same error but with the absolute path to the file.

How are you constructing the schema from the SchemaSource objects? You need to provide all included schema's up-front - medeia doesn't load additional schemas on-demand. If you specify a schema with baseUri "./attribute.json" it should work; if it doesn't, that's a bug.

@worldturner is there any reason why we have to provide all the included schema's up front?

Would it be possible to plugin a json-schema source resolver of some kind so that you can specify how and where to load the json schema sources (for unknown refs) from?

The main reason was stability and simplicity.
A production application that links to external URLs can't start unless that external URL is available. And it's a security risk. I've seen many production issues because of misconfigured XML parsers and schema validators where applications became unavailable in production because external links couldn't be loaded (anymore).
That's less of a problem for relative file links though.
The other reason, simplicity: not having to go into relative URL resolution, which is a problem if you refer to the same external resource with multiple different relative URLs.

But an optional feature that would need to be turned on explicitly wouldn't be a problem. I don't have enough time to build that right now though.

@worldturner : Any update on this? I am experiencing the same issues with ref statements. Hoping for a solution since otherwise your lib seems really cool and lightweight, exactly what I was looking for 👍

Here comes the test case:
Given a schema:

//schema.json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "other": {"$ref": "other.json"}
  },
  "required" :  ["other"]
}

And one we reference to:

//other.json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "item": {
      "type": "string"
    }
  },
  "required": ["item"]
  }

How can I load schema.json?

val source = UrlSchemaSource(schemaURL)
api.loadSchema(source)

fails with IllegalArgumentException: Invalid schema combination, unresolved $ref references: other.json

And when supplying the baseUri, we get the same behaviour as already reported by @jebbench:

[...]
val source = UrlSchemaSource(schemaURL,baseUri = baseURI)
[...]

fails with the same error message only with the full path to other.json

And when I try to supply all schemas up front:

val source = listOf(UrlSchemaSource(schemaURL),UrlSchemaSource(otherURL))
val schema = api.loadSchemas(source)

this fails with IllegalStateException: Duplicate schema id registration: '#'

Ok, succeeded in loading the schema with:

val source = listOf(
    UrlSchemaSource(schemaURL),
    UrlSchemaSource(otherURL,baseUri = URI("other.json")
)
val schema = api.loadSchemas(source)

Is this part of the documentation and I just didn't find it?