-
Notifications
You must be signed in to change notification settings - Fork 739
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
Apollo 1.0 Beta: Fragment name collisions with selection sets are easy #2405
Comments
You know I see |
Thanks for the report!
I think this should work. We tried to reduce the amount of namespacing as much as possible to keep the generated code concise, but I think it has to be here. The only other way to handle that would be if we kept track of the names of Fragments and fields and when they conflict we then and only then namespace them. I think that's way more work that it's worth though. It hurts the performance and memory impact of the codegen execution for very little benefit (and it's a bunch of extra complexity we have to add to the already complex codegen system). I'll add the namespacing to these. |
As I've been working on #2424, I'm realizing we need to prefix with schema name for other types as well.
|
Realizing as I test this, that it only works when the Fragments are in the schema module. If the fragments are placed in your other targets, I don't really know how to resolve this naming conflict... I'm thinking about how to handle this, but I'm wondering if the only real solution is to disallow fragments to have the name of an object? You could still name the fragment @jimisaacs How much would that bother you? |
I don't think it would bother me 🤔. I would just suggest if that it already ends with |
Okay, I've come up with a few options for how to resolve this. I'm looking for feedback on how we should handle it before I can implement it, so I don't think this is going to make it into Beta 2 today. I'll slate it for a Beta 3 next week. I'd love feedback from anyone interested, but specifically tagging people I know may have opinions: This is also related to #2433, which deals with Fragments file names colliding with the file names of object types. Please let me know which of these options you prefer: Input:Schema.graphqlstype Query {
dog: Dog!
}
type Dog {
species: String!
} Dog.graphqlfragment Dog on Dog {
species
} DogQuery.graphqlquery DogQuery {
dog {
...Dog
}
} Option 1a - Put All Fragments in the Schema ModuleIt's important to recognize that this is only a problem when your operations & fragments are generated and included in your other modules. If you put the operations & fragments in the schema module (which I believe is what @jimisaacs is doing in the initial examples he created this issue from), then the solution is as easy as the codegen adding the If all fragments are put in the schema module, then this works just fine, but I don't think that's a great solution. It limits some significant functionality for multi-module support. I'm not a huge fan of this solution. I could be wrong here, but I actually expect that most people will want to have their operations/fragments co-located with feature code that consumes those operations/fragments. This allows you to just have a shared module with your schema types, and compartmentalize the operations/fragments where they are used. Option 1b - Use Namespace only if Fragments In Schema ModuleOf the fragments are in the schema module, we can use the namespacing technique. If they aren't then we have to use one of the below options. This seems like a really inconsistent solution, and it still requires us to solve the problem using one of the below solutions as well for many cases. Option 2a - Automatically Suffix Generated Fragment Types with
|
I'm also good with Option 2a, but just not suffixing if it already ends with Fragment. (no DogFragmentFragment). |
@AnthonyMDev thanks for such a thorough breakdown and exploration of the potential options! I agree with your preference and @jimisaacs - option 2a seems like a great solution and is totally reasonable, especially given that we're doing something similar with operations already. Thanks! |
Thanks for the detailed breakdown @AnthonyMDev!
The one true answer for this is "don't name things the same" and I feel like we're simply pushing that answer further along to a place where we're more comfortable with it being the final answer to the problem. Take the outrageously ridiculous example of both the type and fragment being named |
|
After further consideration, we've decided to make option 2a an opt-in solution. You can choose to use a field alias on a single conflicting name. If you want to handle this across your entire schema with a name suffix because this is a common pattern for you, then you can enable the option to do this. But by making it the default, you remove a lot of control over the expressibility of your view models and generated types, so its not a great default solution. After talking to @jimisaacs, it looks like he has a workaround for now, so I'm going to push this off until Beta 3. |
After talking with the team about #3024 and recognizing the similarity in this issue we've decided to implement an error during code generation that will alert the user to this kind of naming conflict and recommend a type alias be used to resolve it. |
Bug report
Reduced case that does not compile.
Notice a field of
dog
becomes incompatible with a fragment ofDog
.schema.graphqls
DogQuery.graphql
Fragments/Dog.swift
Operations/Queries/DogQuery.swift
Error
Suggestion
Use namespace somehow, can we assume
schemaName
is a package name?Sorry, I don't have much else at this time.
The text was updated successfully, but these errors were encountered: