Skip to content
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

Assume addTypename:true, but hide implicit __typename result fields. #5154

Closed

Conversation

benjamn
Copy link
Member

@benjamn benjamn commented Aug 9, 2019

As @jbaxleyiii pointed out in this comment, the root query and mutation types do not necessarily have to be called "Query" or "Mutation", and the only way to find their real names is to ask for their __typename fields. In other words, when adding __typename fields to a query, we should make sure the root operation has a __typename field, just like any other selection set. Hence the first commit in this PR: 4377e02.

Until now, the InMemoryCache has allowed application developers to decide if the cache should add __typename to the queries it processes. While this might seem like a reasonable configuration option, the truth is that the cache always needs __typename information, and the only legitimate reason to pass addTypename: false is when you (the application developer) don't want to receive __typename fields in your query results when you didn't ask for them.

It turns out we can satisfy the latter goal by simply excluding any implicitly-injected __typename fields from cache results. With that objection out of the way, it becomes much less disruptive to force addTypename: true as the default behavior, which allows the cache to rely on the presence of type information without visibly polluting cache results returned to the application.

benjamn added 2 commits August 9, 2019 17:49
As @jbaxleyiii pointed out in this comment, the root query and mutation
types do not necessarily have to be called "Query" or "Mutation", and the
only way to find their real names is to ask for the __typename property:
#5146 (comment)
Following up on some intentions I recently expressed on Twitter:
https://twitter.com/benjamn/status/1157422802359730176

This implementation is a bit more nuanced than simply forcing the
addTypename option to be true, since that approach yields a lot of
unwanted __typename fields in result trees. Instead, if we exclude those
automatically-injected __typename fields from query results, application
code will receive only the __typename information that it asked for
explicitly, and the cache will always receive the __typename information
that it needs.
@benjamn benjamn added this to the Release 3.0 milestone Aug 9, 2019
@benjamn benjamn requested review from hwillson and jbaxleyiii August 9, 2019 22:03
@benjamn benjamn self-assigned this Aug 9, 2019
@benjamn benjamn changed the title Assume add typename but hide implicit result fields Assume addTypename:true, but hide implicit __typename result fields. Aug 9, 2019
Copy link
Member

@hwillson hwillson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff @benjamn - looks good! 👍 from me after test fixes of course, but those are probably just mismatches between the mocked responses having or not having __typename, and not lining up with the expected results - should be quick to fix.

@benjamn
Copy link
Member Author

benjamn commented Aug 10, 2019

Those test failures run a bit deeper than I hoped.

Specifically, a surprising number of tests rely on { addTypename: false } to ensure the query document is not transformed by the cache, often because they expect exactly the same document to be sent over the network. That's unfortunate, as it prevents us from always adding __typename fields, because doing so generates a new DocumentNode object.

Somewhat fewer tests (but still more than I expected) are written in a way that expects __typename to be present in the result even if it wasn't present in the query. That's too bad, because this PR was based on the idea that most existing code should be happy to receive what the query specified, without unwanted __typename fields injected into it.

I'm not entirely sure how representative our test suite is of actual application code, but I'm afraid the strategy in this PR needs some more thought.

@jbaxleyiii
Copy link
Contributor

@benjamn I'm quite familiar with those tests and I feel quite confident that 1) they are not indicative of application code patterns and 2) usage of __typename without specifying it in the operation is relying on a leak of an internal utility and a potentially breaking change that we should make.

@jbaxleyiii
Copy link
Contributor

Furthermore, with our thinking around a different parsing strategy all together, allowing runtime setting of query manipulation is not in our best interest and I think should be removed as this PR is doing.

@benjamn
Copy link
Member Author

benjamn commented Aug 21, 2019

@jbaxleyiii Thanks for the confirmation that people don't really want/expect __typename fields in results that they didn't explicitly ask for.

@hwillson For the purposes of restructuring the repo, don't worry about merging this PR before you get started. I plan on revising this approach substantially when I get back from my vacation, so merge conflicts are not a concern.

@abernix
Copy link
Member

abernix commented Aug 22, 2019

With regards to adding the __typename to the top-level Query: it sounds like this could be a change that should be coupled with messaging to users of the operation registry since currently, during operation registration with apollo client:push, the CLI adds __typename fields to the operations so they'll match (exactly) when the request comes in from the client. Here is a relevant bit from apollo itself.

benjamn added a commit that referenced this pull request Sep 12, 2019
This change was adapted from #5154, per @jbaxleyiii's approval:
#5154 (comment)

If you read from the cache using a query that does not have explicit
__typename fields, the cache should not return data containing the
__typename field. Unfortunately, we have a bunch of tests that currently
enforce the accidental presence of __typename, so this relatively simple
change required updating a lot of test code.
@benjamn
Copy link
Member Author

benjamn commented Sep 13, 2019

Closing in favor of #5320… and also because I don't want to deal with those merge conflicts.

@benjamn benjamn closed this Sep 13, 2019
@apollographql apollographql locked and limited conversation to collaborators Feb 3, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants