I'm using a malli schema with embedded vars in order to get well-factored json-schema and open-api schema. However, in some places, I'd like to convert that schema to using camel-cased keywords, rather than kebab-cased keywords. I wrote this schema walker:
(defn- camel-case-map-child
[[key & rest]]
(into
[(if (keyword? key)
(csk/->camelCaseKeyword key)
key)]
rest))
(defn camel-case-schema
[schema]
(m/walk schema
(fn [schema _ children _]
(case (m/type schema)
:map (m/-set-children schema (map camel-case-map-child #p children))
schema))))
however, even using ::m/walk-vars and ::m/walk-schema-vars, it didn't seem to make the camel casing of the schemas referenced via vars actually stick (even though I confirmed that it did walk those schema). Is there a way to achieve what I want? (Currently, I'm just using the default registry).
Alternatively, is there a way (when exporting openapi schema) to transform the keywords right before handing them over to reitit for openapi conversion (possibly mapping my conversion function over both the spec and all of the associated definitions in the registry)?interesting problem
one option would be to use a registry (instead of vars) with CamelCase strings (or keywords) as schema names
it's hard to find a single place to insert some code to make a translation like that
you could wrap the reitit openapi handler with a middleware that processes the output
if malli.json-schema had an option for how to represent vars, you might be able to wire it through the reitit Coercion object
or something like a :json-schema/name malli attribute might make sense
here's the piece of code in malli.json-schema that computes the name of a ref schema: https://github.com/metosin/malli/blob/master/src/malli/json_schema.cljc#L14-L18
in practical terms, I'd just switch to using CamelCase vars for the schemas, less magic, and the openapi doc corresponds directly to the source
In this case, it's less about the names of the vars, and more about the keys of the maps in the schema. Sadly, I have two use cases that have different key conventions for the keys, but otherwise want the same schema. Middleware on the openapi handler is an interesting option, though, I'll take a look at that. Is it possible to manipulate the registry of a schema after the schema has been parsed? For instance, could I replace the registry (that contains all the var contents) with another where the subschema have all been camelcased as well?
I think you might be able to
but I haven't done anything like that
I was able to get it to work by generating an online registry while walking the schema
Hey Cale, been a while! I'm actually trying to solve a very similar problem. I'd been looking at using a transformer – didn't occur to me to use walk. What do you mean when you say you generated an online registry?
Sorry, an inline registry. I modeled my code on how the json-schema namespace generates its definitions (in an atom). One hiccup I hit was that when I generated a [:ref "some name"] where I was replacing vars, I had to drop a registry right there otherwise malli complained that my ref was invalid (because it wasn't being rendered as part of the full schema where I attached the complete registry at the end of the walk)