-
-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Types with names that only differ by capitalization get overwritten #335
Comments
Hello! The challenge for the generated code is that Elm top-level definitions (functions and values) must start with a lowercase alpha character. Module names and types in Elm must start with a capital alpha character. So Here is the relevant code for normalizing names:
So it's challenging to find a strategy that works well for that. The underlying philosophy I'm aiming for is to shoot for is:
Idea 1 - Normalize Non-Idiomatic NamesThere are no great options here and no silver bullets (there are problems with any approach). But one strategy could be to take these non-idiomatic names (types are idiomatically capitalized in GraphQL) and generate something that will be less likely to result in name collisions. For example: type SortBy {
# idiomatic class case name
}
type sortBy {
# non-idiomatic camel case type name
} We could generate resulting modules like this:
Idea 2 - Normalize All NamesJust for completeness, another idea is to normalize all names. That is, start every module name with Idea 3 - Warnings for Ambiguous Collisions
Idea 4 - Errors for Ambiguous CollisionsSimilar to idea 3, but stop the build. Erroring out when there are collisions is more robust, but also more rigid. If you don't have control over your API, then you're out of luck. So this doesn't seem like a viable approach in itself. Idea 5 - Require Mappings for Ambiguous NamesAnother approach could be to require a mapping file to map any irregular names. In your case, that might look like a JSON file like this:
{"typeNames":{"sortBy":"X_sortBy"},
"fieldNames": {}
} There are some special cases here that would probably deserve errors:
One of the challenges with this approach is that you may run this when there is an API change and not expect a failure. But that might be an acceptable tradeoff because you probably want to stop rather than having a silent conflict like the current state. Idea 6 - Allow Custom Mapping FunctionsIt could even allow for custom error messages. This could even just be Elm code that runs with a type signature like: normalize : String -> Result String String Or it could take in a custom type which enumerates possibilities, like: type GraphqlName = Regular String | Irregular IrregularReason String
type IrregularReason = LowerCaseTypeName | ... ConclusionI think that Idea 5 may be the best balance between simplicity, robustness, and flexibility. I'd love to hear other peoples thoughts on this. Real world use cases and experiences with GraphQL/elm-graphql would be very useful to hear as well! I'll gather some feedback here, and then consider implementing Idea 5. |
I think idea 5 sounds good. For our use case, we would like to have In our case, having an explicit "Disallow unidiomatic names" option could be nice, even when there are no ambiguities. We do currently have a few unidiomatic names, and we can't just replace them immediately, because we want to have deprecation periods for any schemas we might change (as our customers use those them). It would be useful to verify that we are not adding new unidiomatic names though, so maybe such an option could require us to add unidiomatic names to the mapping file, to make them explicit. Such an option would grow |
Just got bitten by something similar: enum Order {
ASC
asc
DESC
desc
} The lowercase versions exist only for backwards compatibility reasons and are deprecated, but it causes the generation of the invalid elm type: type Order
= Asc
| Asc
| Desc
| Desc Could it be simply / at least deduplicated in this instance? |
If someone wants to try adding a feature for approach 5, I would welcome a PR there. It may be a little bit involved because it would require passing around the mapping configuration to all the relevant places. I'd be happy to give guidance on that if someone wants to work on that. |
We have a GraphQL backend, where one of our developers recently added a
sortBy
type, which caused us some trouble, given that aSortBy
type already existed. The GraphQL standard defines that types must have unique names, but doesn't specify anything about case sensitivity as far as I can tell, so it seems like this is legal.Using elm-graphql to generate our Elm code, it would only generate one
SortBy
module, non-deterministically letting one type overwrite the other. This made the issue go undetected by the developer who introduced the change, since only one of the two types were actually used on our front-end at the time, so the build would be green if the right type was generated.The fix was pretty simple once we knew what the issue was, since we don't want disparate types that are named so closely, so we prefixed the type names with more info. However, it would be nice if elm-graphql could warn or fail completely in this situation, since the generated code is arguably invalid. But if it's troublesome to support, it's also not a huge deal, since the problem was relatively straight forward to deal with 🙂
The text was updated successfully, but these errors were encountered: