Fork me on GitHub
#graphql
<
2023-02-27
>
wickedev01:02:21

In lacinia, I would like to convert the keys of arguments and variables to kebab-case, while keeping the use of camelCase for SDL (or edn) cases. Is there an official way to do this or a way that I can contribute to achieve it?

👍 2
oliy09:02:42

not official, but i made a library for this - it provides clj->gql and gql->clj using the schema to make the transforms as efficient as possible https://github.com/oliyh/locksmith

oliy09:02:54

however, it feels like a losing battle without native and third party support which you are unlikely to get (chiefly because a-thing is not a valid key in a javascript map)

hlship15:02:26

Any time your schema names and your Clojure map keys differ, there's an easy chance for confusion. That being said, Lacinia does map from field name to map keys; generally, they are identical. The :default-field-resolver option for schema/compile is responsible for this. When there is no explicit resolver for a field specified in the schema, this option (it's a function) is used to generate a resolver. That, unfortunately, commingles two things: mapping the field name to the map key, and creating an optimized field resolver function. Essentially, the ::direct-fn meta data directs Lacinia that it can bypass the whole ResolverResult dance and directly extract a field's value from the Clojure map. This is an important optimization.

wickedev02:02:27

I am already using :default-field-resolver to convert the case of the field. I just want to the arguments and variables coming inside the resolver to be in kebab case.

wickedev02:02:22

For instance, I'm converting all the arguments per resolver into kebab case, and this is a huge inefficiency when it comes to operate on field resolvers; because the cases have to be converted back and forth (camel->kebab->camel->kebab..) if the arguments are translated into kebab from the beginning, such incident can be avoided.

hlship17:03:32

This is a limitation w/ the default field resolver, it is only passed the field's name. The kind of translation you desire could be provided if the default field resolver was passed the FieldDef structure instead, so it could know what the arguments are and build a translation from camel to kebab on the way in (for arguments). This kind of thing can be done using a field annotation, as the annotation code does get the FieldDef and can wrap the application's field resolver with an extra layer that performs the extra transformations. Or, you could bite the bullet and just use consistent keys front to back. It looks a little odd to have Clojure keywords named :userId instead of :user-id, but the consistency is a big benefit.

❤️ 2
gratitude-thank-you 2