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
Marshal methods and multiple fragments using the same structure #3672
Comments
Hi 👋 ! Thanks for sending this. This problem happens when using merged fields. This is unfortunately a limitation in the 2.x version and pretty hard to fix without breaking the API. The good news is that significant work was made in 3.x to address this issue, as well as giving more typed models using fragments as interfaces. Any chance you can try the just released |
I think I faced exactly the same issue in ( and it seems like there is a behavior change between 2.x and 3.x and 3.x 🤔 2.x seems to pick first fragment, 3.x picks last fragment (which in my case results
(☝️ sceenshots generated after dropping custom viewer id generation) edit: I can also link related issue I reported in the past: #2818 which sounds almost the same) |
Feel free to ignore my comment from above. It seem like I stumbled upon yet another issue where superfluous field in json response was written into the cache, which seems to be fixed 3.x. Here's proper repro on 3.0.0-rc02 for both this issue and #2818: https://github.com/mateuszkwiecinski/apollo-playground/blob/7c5ae7530511bb872a7b04694a0a9423b8757555/src/test/kotlin/com/example/Test.kt#L15 3.0.0-rc02 tries to read all requested fields and throws 3.0.0-rc02 doesn't fix merged fragments issue and it seems it introduces regression to how they behave in 2.5.11 |
Thanks a lot for the reproducer, that helps a ton 💙 ! Turns out there was a bug in As a side note, if you have a lot of merged fields like |
🎉
Sure! I probably could have adding tests in this project in the first place to make it even easier. Thanks!
Nice, didn't know that 👍 I don't think I have that many merged fields in my default project (I only aimed to try all types of them in the repro), but I'll definitelly try that out and see if there's any profit, thanks again! |
This is fixed in |
@martinbonnin 👋 I think I found another edge case where Here's updated repro: https://github.com/mateuszkwiecinski/apollo-playground/tree/fragments_with_lists I tried to modify the functional test you've added, but I'm having trouble to set-up the project on Java17 :/ (btw I think I made a mistake previously when declaring CacheResolver I should have used the one migration guide suggests (it doesn't affect the previous repro, but it seems to be important now, so I updated its definition)) |
Fixed in 3.0.0, hopefully for good 🤞 |
I'm not 100% done migrating to 3.0.0 (rc3) but for my initial problem it's ok |
Hello 👋 It's me again 😬
And if I'm not mistaken the repro is to have 2 queries, first writes data into cache, the other one tries to fetch part of the previous object, but it uses fragments as a part of its definition. If I inline the Reproducible in 3.0.0 and 3.0.1-SNAPSHOT |
Hi @mateuszkwiecinski and apologies for huge Holidays delay. Wish you and everyone in this thread all the best for 2022 🎄 :) This issue is somewhat different because the underlying cause is the algorithm used to add In a nutshell, the 3.x code adds This is more restrictive than 2.x that added it on all composite fields by default. Overall, we're trying to remove the unneeded added What we can do is add an optimization that doesn't add typename if we know by construction that the fragment type condition is always true (i.e. the field is monomorphic). This will not fix all issues. For an example, someone could do this: interface Product
type Book implements Product
# read from network
query Query1 {
book {
id # "1001"
title
}
}
# read from cache
query Query2 {
product(id: "1001") {
... on Book {
id
title
}
}
}
All in all:
|
It's great to have this optimization, always fetching I just wanted to point out that the current behavior makes it pretty easy to shoot yourself in the foot, because intuitively fragment extraction like from this: query Foo {
foo {
bar
baz
}
} to this: query Foo {
foo {
...fooData
}
}
fragment fooData on Foo {
bar
baz
} shouldn't be a functional change. It's really easy to not realize that Apollo will fetch different data in both cases and thus cause potential cache misses. Perhaps it'd be worth documenting this somehow? |
Marshal methods have problems with multiple fragments using (partially) the same structure
Apollo 2.5.9
Combining fragments as a workaround of the lack of inheritance :
This is just a small example, my real Product structure is really big and I really want to use fragments combination.
No problem with this as a client, the parsing works and you can reach the images via the "light" fragment and videos via the "complete" fragment in return of the query.
But using the marshal methods in my embedded mock server leads to a merge problem in the final json :
Only one of the partial media structure of the two fragments is serialized, here the light version (only the images are returned in the media node of the final json). Then the client fails to parse media for the "complete" fragment.
Probably one of those 2 situations :
The text was updated successfully, but these errors were encountered: