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

GraphQLExecutionSource/DataDict/ObjectData Refactor #2990

Merged
merged 35 commits into from May 15, 2023

Conversation

AnthonyMDev
Copy link
Contributor

@AnthonyMDev AnthonyMDev commented May 2, 2023

This PR:

  • Defines a new GraphQLExecutionSource that is passed to GraphQLExecutor.
    • The execution source determines how fields in the data are read, what the underlying type for nested entity fields in the data is stored as, how to compute which selections and fulfilled fragments should be executed, and how to expose the source data for cache key resolution.
    • These were all being determined by different closures passed to the executor and some tightly coupled implementation details inside of the executor. Now they are grouped sensibly into accurate sets of configuration for the defined execution sources.
    • Defines execution sources for Network Response Data; Cache Response Data, and Selection Set Models.
    • By making the executor generic over it's source, we get generic specialization and additional type safety that improves both the code quality and performance of GraphQLExecutor.
  • Defines an ObjectData protocol to use for wrapping the data from individual execution sources while completing cache key resolution.
    • Because the shape and underlying types of raw data for each source differs, cache key resolution is inconsistent.
    • Implementations of ObjectData provide an opaque wrapper that lazily accesses and transforms the data for each execution source.
      • This should provide a consistent API for accessing data while computing cache keys.
      • This PR defines the data transformers for each of the necessary execution sources.
      • Breaking Change: The API for cache key resolution in SchemaConfiguration will be changing to use the new ObjectData protocol. This is a very minor breaking change for most users during the next version upgrade. Detailed explanation and documentation will be included to minimize confusion and impact to users during the upgrade.
      • This PR includes the initial changes to code generation templates to generate selection set initializers with the new DataDict shape. Additional work and unit tests to ensure code generation addresses all edge cases will come in following PRs on this stack.
  • DataDict refactoring:
    • Separates the fulfilledFragments from the object data in DataDict.
    • This allows us to operate on the fulfilledFragments (and any other future metadata on SelectionSets) without polluting the object's data dictionary.
    • Equatable and Hashable conformance for DataDict only check the data, not the fulfilledFragments. This fixes Equality operator shows incorrect values based on value of "__fulfilled" #2944.
    • DataDict now uses a class for storage with copy-on-write value semantics.
      • Early performance testing shows a 10-20% improvement in parsing and execution performance and a 65-75% improvement in type case conversion accessors and manual selection set model initialization!

@netlify
Copy link

netlify bot commented May 2, 2023

Deploy Preview for apollo-ios-docs canceled.

Name Link
🔨 Latest commit 63ce879
🔍 Latest deploy log https://app.netlify.com/sites/apollo-ios-docs/deploys/6462939afc42e90008f3bdf4

@AnthonyMDev AnthonyMDev added this to the Release 1.2 milestone May 4, 2023
@AnthonyMDev AnthonyMDev changed the title [1/x] GraphQLExecutionSource/DataDict/ObjectData Refactor GraphQLExecutionSource/DataDict/ObjectData Refactor May 12, 2023
@AnthonyMDev AnthonyMDev marked this pull request as ready for review May 12, 2023 23:04
This was referenced May 15, 2023
/// [aliased fields](https://spec.graphql.org/draft/#sec-Field-Alias) will be keyed on their
/// alias name, not the name of the field on the schema type.
///
/// 3. Because cache key resolution is performed both on raw JSON (from a network response or
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Invert this paragraph for clarity

/// An opaque wrapper for data representing the value for a list field on a GraphQL object.
/// This type wraps data from different sources, using a `_transformer` to ensure the raw data from
/// different sources (which may be in different formats) can be consumed with a consistent API.
public struct ListData {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe make this conform to sequence for iterations?

@AnthonyMDev AnthonyMDev merged commit 2e8bd2c into main May 15, 2023
16 of 17 checks passed
@AnthonyMDev AnthonyMDev deleted the ObjectData-wrapper branch May 15, 2023 20:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Equality operator shows incorrect values based on value of "__fulfilled"
1 participant