shale
shale copied to clipboard
Allow customization of JSON schema $defs key and $ref
Suppose you have the following code:
class Person; end
class PersonMapper < Shale::Mapper
model Person
end
require 'shale/schema'
puts Shale::Schema.to_json(
PersonMapper,
pretty: true
)
You get
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$ref": "#/$defs/Person",
"$defs": {
"Person": {
"type": "object",
"properties": {}
}
}
}
But, what if you want a $defs
key and $ref
calculated differently from the current logic? This is the cleanest way I've figured out so far:
def schema_with_custom_defs_key_and_ref(mapper, defs_key:)
schema = Shale::Schema::JSONGenerator.new.as_schema(mapper)
old_defs_key = mapper.model.name
old_ref = schema['$ref']
new_defs_key = defs_key
new_ref = "#/defs/#{new_defs_key}"
schema['$ref'] = new_ref
schema['$defs'][new_defs_key] = schema['$defs'].delete(old_defs_key)
schema
end
puts JSON.pretty_generate(schema_with_custom_defs_key_and_ref(PersonMapper, defs_key: 'User'))
Which gives
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$ref": "#/defs/User",
"$defs": {
"User": {
"type": "object",
"properties": {}
}
}
}
But it's quite cumbersome. What about something like
class PersonMapper < Shale::Mapper
model Person
json do
defs_key 'User'
end
end
Another option I guess would be to pass defs_key
to as_schema
, e.g.:
Shale::Schema::JSONGenerator.new.as_schema(PersonMapper, defs_key: 'User')
But I'm new to JSON schemas, I don't know which one makes more sense
What you're doing is probably the best way to change refs at the moment. I'm curious, what is the use case for doing that?
I'm curious, what is the use case for doing that?
Basically these are my mappers:
module ShaleMappers
class Model < Shale::Mapper
model ::Model
...
Which would make the $defs
key to be ShaleMappers_Model
but I'd like to have just Model
. Also, in case of a model namespace, I'm not enthusiast of having _
as separator, I'd like to use something else (I was even thinking of /
, but I'm new to JSON schemas so I'm unsure it makes sense), so yeah stuff like this
UPDATE Actually, I was wrong about the ShaleMappers_Model
point, I've just realized I miswrote the model
forgetting the ::
, that's why ShaleMappers_
was included in the $defs
key. But the argument about the _
still remains.
(btw thanks for this library, I love that it doesn't have any open issues nor pull requests so much that opening one made me sad :joy: )
Thanks. Like I said, for now I would stick to what you're doing currently. I might implement it in the future, but for now I don't have much free time.