Hello,
I’ve just released a new version for JSV (a JSON Schema Validation library).
While working on support for OpenAPI 3.1 I needed to be able to use generic JSON documents as a repository for schemas. For instance, in an OpenAPI specification JSON document, the “API spec” itself is not a JSON schema, but it contains schemas. There is no need to transform the whole document in a schema that would validate nothing (as there are no schema keywords like type
or properties
at the root level).
So it’s now possible to have a document, and only build one or several parts of it into the “validation root” that JSV uses for validation. This is not documented for now as I am still waiting to see if it covers all my needs. But to implement that I had to make some breaking changes, and I’m releasing those now, better sooner than later.
Breaking changes
For regular usage of the library this should not impact your workflow.
- [breaking] Defschema does not automatically define $id anymore
- [breaking] Error normalizer will now sort error by instanceLocation
- [breaking] Changed caster tag of defschema to 0
- [breaking] Changed order of arguments for Normalizer.normalize/3
Incoming changes
In a next release I also want to sunset the composition API for schemas. This API looks like this:
alias JSV.Schema
%Schema{}
|> Schema.object()
|> Schema.properties(%{
age: Schema.integer(description: "The age")
my_prop: name_schema
})
|> Schema.required([...])
While this looks nice, I feel it’s pretty useless. If you already know what’s going to be in the schema you can just declare it that way:
%Schema{
type: :object,
properties: %{
age: Schema.integer(description: "The age")
my_prop: name_schema
},
required: [...]
}
This does not prevent you to have dynamic values like the name_schema
variable.
The problem with that API is that the functions accept an optional first argument, the base to merge onto. For instance with Schema.integer/1
above,instead of piping in, I just passed the base directly and it’s explicit.
But if you want to define a schema with string_to_atom_enum/2
and a description for instance, you need to do this:
%{
properties: %{
my_enum:
JSV.Schema.string_to_atom_enum(
%{
description: "Some description"
},
[:aaa, :bbb, :ccc]
)
}
}
Whereas what you expect to see is something like that:
%{
properties: %{
my_enum: JSV.Schema.string_to_atom_enum(
[:aaa, :bbb, :ccc],
description: "Some description"
)
}
}
That is, the first argument corresponds to the function name (in this case an enumeration of atoms), and maybe some optional overrides.
So I plan to move all those functions into a “composition API” module, and maybe deprecate them. JSON schemas are data and not code, it should always be possible to know the keys we want in there from the beginning. For the rare cases where we could not, I’ll keep the merge
function anyway.
And then replace those functions with new helpers that take overrides as the last argument.
But I’d like to have you opinion on this
Thank you