-
Notifications
You must be signed in to change notification settings - Fork 738
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
Shape of models with fragments unexpectedly different when migrating to V1 #3496
Comments
This is due to apollographql/apollo-ios-dev#571. Because this is not an issue on a released version, I'm going to close this issue. Discussion to follow in the PR. |
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo iOS usage and allow us to serve you better. |
What are the types used here? If the But this would be the expected generated code for something that looks like this: type Me { ... }
type MeFragmentOne { ... }
type MeFragmentTwo { ... } {
me { // type is Me
...meFragmentOne
...meFragmentTwo
}
}
fragment meFragmentOne on MeFragmentOne { ... }
fragment meFragmentTwo on MeFragmentTwo { ... } |
If they are of the same type, you may be able to get this working by using a field merging policy of |
@AnthonyMDev assume the Again, in this case I'd expect to be able to access each fragment like: |
I see, thank you for the clarification. This is a design decision that was made for 1.0 and is a change from the behavior of the legacy models. This is not a bug. You will need to change your call sites. The 1.0 version has a lot of breaking changes from the 0.x, and it's not an easy migration. Unfortunately, we needed to make some future-forward decisions to create a more stable API to support additional features, and this just means a lot of legacy code is incompatible. Once you've migrated to 1.0, future versions should be easy to migrate to though. We are working on 2.0 right now, and anticipate the migration path to be much less work there. |
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo iOS usage and allow us to serve you better. |
@AnthonyMDev thx. Is there an issue/PR that explains why this design decision was made? I'm sure it was well founded, I'm just curious to learn the reasoning. |
I can give you the reasoning! Given this schema and operation: interface Me { ... }
type A { ... }
type B { ... } {
me { // type is Me
...meFragmentOne
...meFragmentTwo
}
}
fragment meFragmentOne on A { ... }
fragment meFragmentTwo on B { ... } The way this is actually executed by a GraphQL server is to check if the underlying type of {
me { // type is Me
... on A {
...meFragmentOne
}
... on B {
...meFragmentTwo
}
}
} And this is actually how the GraphQL spec expects that a server handles execution of this operation. We decided to have the response models more closely resemble the expanded version of this operation. And the reason actually has to do with clarity of the code when dealing with optionality. In this situation, if you were to handle it the way we did in the legacy codegen, Instead, the call site now requires you to call this as Even in the operation above, the legacy version would have callosities like This design change dramatically improves local reasoning. That is why we went in this direction. I'd also note that in the situation where we can guarantee that the fragment will be resolved, we do simplify the generated models (though some of that simplification does require field merging to be enabled, which I know you are not able to use). Given this alternative schema: interface Me implements A & B { ... }
interface A { ... }
interface B { ... } The code generation engine does recognize that |
Thanks for the detailed explaination :) |
Summary
Let's say I have the following .graphql:
The shape of the generated swift will look like:
To access these fragments it looks like:
Prior to V1 accessing these fragments would look like:
It seems there is a
fragments
property on the Me SelectionSet but it resolves toNoFragments
which makes me think this is a bug? If not, this makes migration extremely inconvenient because each usage of a fragment in code will need to be updatedI generated this using the
.none
option for FieldMergingVersion
apollographql/apollo-ios-dev#571
Steps to reproduce the behavior
Logs
No response
Anything else?
No response
The text was updated successfully, but these errors were encountered: