Skip to content

Rework data masking types - #12837

Merged
phryneas merged 38 commits into
release-4.0from
jerel/masking-types
Aug 13, 2025
Merged

Rework data masking types#12837
phryneas merged 38 commits into
release-4.0from
jerel/masking-types

Conversation

@jerelmiller

@jerelmiller jerelmiller commented Aug 8, 2025

Copy link
Copy Markdown
Member

While working on #12835 we found some opportunity for improvement on the data masking types.

  • The types mode has been removed in favor of always using the default "preserve types" mode.
  • You must now opt-in to use GraphQL Codegen data masking types. By default, we use identity types for all masking types as if masking weren't enabled
  • The Masked and MaskedDocumentNode types have been removed as these no longer have any effect with the default type preservation

@jerelmiller
jerelmiller requested a review from phryneas August 8, 2025 19:14
@changeset-bot

changeset-bot Bot commented Aug 8, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9a7c492

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@apollo-librarian

apollo-librarian Bot commented Aug 8, 2025

Copy link
Copy Markdown
Contributor

✅ Docs preview ready

The preview is ready to be viewed. View the preview

File Changes

26 new, 66 changed, 5 removed
+ (developer-tools)/react/(latest)/api/link/apollo-link-base-batch-http.mdx
+ (developer-tools)/react/(latest)/api/link/apollo-link-base-http.mdx
+ (developer-tools)/react/(latest)/api/link/apollo-link-batch.mdx
+ (developer-tools)/react/(latest)/api/link/apollo-link-client-awareness.mdx
+ (developer-tools)/react/(latest)/api/link/apollo-link.mdx
+ (developer-tools)/react/(latest)/api/react/ApolloProvider.mdx
+ (developer-tools)/react/(latest)/api/react/skipToken.mdx
+ (developer-tools)/react/(latest)/api/react/useApolloClient.mdx
+ (developer-tools)/react/(latest)/api/react/useBackgroundQuery.mdx
+ (developer-tools)/react/(latest)/api/react/useFragment.mdx
+ (developer-tools)/react/(latest)/api/react/useLazyQuery.mdx
+ (developer-tools)/react/(latest)/api/react/useLoadableQuery.mdx
+ (developer-tools)/react/(latest)/api/react/useMutation.mdx
+ (developer-tools)/react/(latest)/api/react/useQuery.mdx
+ (developer-tools)/react/(latest)/api/react/useQueryRefHandlers.mdx
+ (developer-tools)/react/(latest)/api/react/useReactiveVar.mdx
+ (developer-tools)/react/(latest)/api/react/useReadQuery.mdx
+ (developer-tools)/react/(latest)/api/react/useSubscription.mdx
+ (developer-tools)/react/(latest)/api/react/useSuspenseQuery.mdx
+ (developer-tools)/react/(latest)/api/errors/CombinedGraphQLErrors.mdx
+ (developer-tools)/react/(latest)/api/errors/CombinedProtocolErrors.mdx
+ (developer-tools)/react/(latest)/api/errors/LinkError.mdx
+ (developer-tools)/react/(latest)/api/errors/LocalStateError.mdx
+ (developer-tools)/react/(latest)/api/errors/ServerError.mdx
+ (developer-tools)/react/(latest)/api/errors/ServerParseError.mdx
+ (developer-tools)/react/(latest)/api/errors/UnconventionalError.mdx
* (developer-tools)/react/(latest)/get-started.mdx
* (developer-tools)/react/(latest)/index.mdx
* (developer-tools)/react/(latest)/why-apollo.mdx
* (developer-tools)/react/(latest)/api/cache/InMemoryCache.mdx
* (developer-tools)/react/(latest)/api/core/ApolloClient.mdx
* (developer-tools)/react/(latest)/api/core/ObservableQuery.mdx
* (developer-tools)/react/(latest)/api/link/apollo-link-batch-http.mdx
* (developer-tools)/react/(latest)/api/link/apollo-link-context.mdx
* (developer-tools)/react/(latest)/api/link/apollo-link-error.mdx
* (developer-tools)/react/(latest)/api/link/apollo-link-http.mdx
* (developer-tools)/react/(latest)/api/link/apollo-link-remove-typename.mdx
* (developer-tools)/react/(latest)/api/link/apollo-link-retry.mdx
* (developer-tools)/react/(latest)/api/link/apollo-link-schema.mdx
* (developer-tools)/react/(latest)/api/link/apollo-link-subscriptions.mdx
* (developer-tools)/react/(latest)/api/link/apollo-link-ws.mdx
* (developer-tools)/react/(latest)/api/link/community-links.mdx
* (developer-tools)/react/(latest)/api/link/introduction.mdx
* (developer-tools)/react/(latest)/api/link/persisted-queries.mdx
* (developer-tools)/react/(latest)/api/react/hooks.mdx
* (developer-tools)/react/(latest)/api/react/preloading.mdx
* (developer-tools)/react/(latest)/api/react/ssr.mdx
* (developer-tools)/react/(latest)/api/react/testing.mdx
* (developer-tools)/react/(latest)/caching/advanced-topics.mdx
* (developer-tools)/react/(latest)/caching/cache-configuration.mdx
* (developer-tools)/react/(latest)/caching/cache-field-behavior.mdx
* (developer-tools)/react/(latest)/caching/cache-interaction.mdx
* (developer-tools)/react/(latest)/caching/garbage-collection.mdx
* (developer-tools)/react/(latest)/caching/memory-management.mdx
* (developer-tools)/react/(latest)/caching/overview.mdx
* (developer-tools)/react/(latest)/data/defer.mdx
* (developer-tools)/react/(latest)/data/directives.mdx
* (developer-tools)/react/(latest)/data/document-transforms.mdx
* (developer-tools)/react/(latest)/data/error-handling.mdx
* (developer-tools)/react/(latest)/data/file-uploads.mdx
* (developer-tools)/react/(latest)/data/fragments.mdx
* (developer-tools)/react/(latest)/data/mutations.mdx
* (developer-tools)/react/(latest)/data/operation-best-practices.mdx
* (developer-tools)/react/(latest)/data/queries.mdx
* (developer-tools)/react/(latest)/data/refetching.mdx
* (developer-tools)/react/(latest)/data/subscriptions.mdx
* (developer-tools)/react/(latest)/data/suspense.mdx
* (developer-tools)/react/(latest)/development-testing/client-schema-mocking.mdx
* (developer-tools)/react/(latest)/development-testing/developer-tooling.mdx
* (developer-tools)/react/(latest)/development-testing/schema-driven-testing.mdx
* (developer-tools)/react/(latest)/development-testing/static-typing.mdx
* (developer-tools)/react/(latest)/development-testing/testing.mdx
* (developer-tools)/react/(latest)/integrations/integrations.mdx
* (developer-tools)/react/(latest)/integrations/react-native.mdx
* (developer-tools)/react/(latest)/integrations/webpack.mdx
* (developer-tools)/react/(latest)/local-state/local-resolvers.mdx
* (developer-tools)/react/(latest)/local-state/local-state-management.mdx
* (developer-tools)/react/(latest)/local-state/managing-state-with-field-policies.mdx
* (developer-tools)/react/(latest)/local-state/reactive-variables.mdx
* (developer-tools)/react/(latest)/migrating/apollo-client-3-migration.mdx
* (developer-tools)/react/(latest)/networking/advanced-http-networking.mdx
* (developer-tools)/react/(latest)/networking/authentication.mdx
* (developer-tools)/react/(latest)/networking/basic-http-networking.mdx
* (developer-tools)/react/(latest)/pagination/core-api.mdx
* (developer-tools)/react/(latest)/pagination/cursor-based.mdx
* (developer-tools)/react/(latest)/pagination/key-args.mdx
* (developer-tools)/react/(latest)/pagination/offset-based.mdx
* (developer-tools)/react/(latest)/performance/babel.mdx
* (developer-tools)/react/(latest)/performance/optimistic-ui.mdx
* (developer-tools)/react/(latest)/performance/performance.mdx
* (developer-tools)/react/(latest)/performance/server-side-rendering.mdx
* (developer-tools)/react/(latest)/_sidebar.yaml
- (developer-tools)/react/(latest)/api/link/apollo-link-rest.mdx
- (developer-tools)/react/(latest)/api/react/components.mdx
- (developer-tools)/react/(latest)/api/react/hoc.mdx
- (developer-tools)/react/(latest)/local-state/client-side-schema.mdx
- (developer-tools)/react/(latest)/migrating/hooks-migration.mdx

Build ID: 4dc20d93b56070a09151783c
Build Logs: View logs

URL: https://www.apollographql.com/docs/deploy-preview/4dc20d93b56070a09151783c

@pkg-pr-new

pkg-pr-new Bot commented Aug 8, 2025

Copy link
Copy Markdown
npm i https://pkg.pr.new/apollographql/apollo-client/@apollo/client@12837

commit: 32e24f2

@github-actions

github-actions Bot commented Aug 8, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size
import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client" (CJS) 42.83 KB (0%)
import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client" (production) (CJS) 37.74 KB (0%)
import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client" 32.83 KB (0%)
import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client" (production) 27 KB (0%)
import { ApolloProvider } from "@apollo/client/react" 5.9 KB (0%)
import { ApolloProvider } from "@apollo/client/react" (production) 971 B (0%)
import { useQuery } from "@apollo/client/react" 7.21 KB (0%)
import { useQuery } from "@apollo/client/react" (production) 2.23 KB (0%)
import { useLazyQuery } from "@apollo/client/react" 7.1 KB (0%)
import { useLazyQuery } from "@apollo/client/react" (production) 2.13 KB (0%)
import { useMutation } from "@apollo/client/react" 6.45 KB (0%)
import { useMutation } from "@apollo/client/react" (production) 1.48 KB (0%)
import { useSubscription } from "@apollo/client/react" 6.77 KB (0%)
import { useSubscription } from "@apollo/client/react" (production) 1.79 KB (0%)
import { useSuspenseQuery } from "@apollo/client/react" 8.57 KB (0%)
import { useSuspenseQuery } from "@apollo/client/react" (production) 3.63 KB (0%)
import { useBackgroundQuery } from "@apollo/client/react" 8.33 KB (0%)
import { useBackgroundQuery } from "@apollo/client/react" (production) 3.38 KB (0%)
import { useLoadableQuery } from "@apollo/client/react" 8.28 KB (0%)
import { useLoadableQuery } from "@apollo/client/react" (production) 3.36 KB (0%)
import { useReadQuery } from "@apollo/client/react" 6.59 KB (0%)
import { useReadQuery } from "@apollo/client/react" (production) 1.63 KB (0%)
import { useFragment } from "@apollo/client/react" 6.66 KB (0%)
import { useFragment } from "@apollo/client/react" (production) 1.69 KB (0%)

@jerelmiller
jerelmiller requested a review from a team as a code owner August 8, 2025 19:33
Comment thread src/masking/types.ts Outdated
DefaultImplementation,
TData
>;
export type MaybeMasked<TData> =

@jerelmiller jerelmiller Aug 8, 2025

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I opted to leave MaybeMasked here since we still can't determine at any given time when to use the masked type or to unwrap the type with unmask.

If we completely removed MaybeMasked, we'd force all formats in the future to output the masking types since the rest of Apollo Client would need to remove MaybeMasked<TData> in favor of plain TData. This wouldn't work super great with the preset output as you suggest since we have no additional wrapping type to know how to pull out the masked/unmasked type.

As you can see, what I did here instead is remove MaybeMasked as an HKT type in favor of a new overridable IsMaskingEnabled type for determing if masking is enabled. In the case of GraphQLCodegen, we can assume it always generates the masked type. In the case of our preset in the future, we can update this to check for the presence of that updated format and unwrap it with the Mask type. This should cover all cases, whether or not the masked type is generated by default or is wrapped in a different object that nests the masks/unmasked variants.

@jerelmiller
jerelmiller force-pushed the jerel/masking-types branch from ebe5325 to 6e74f21 Compare August 8, 2025 21:34
Comment thread .changeset/five-bugs-know.md Outdated

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Look at this from a zoomed out view, does this change make any sense? It might be worth just leaving the names alone to avoid confusion. Would love your thoughts.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Made an executive decision to leave as-is. I saw no good reason to change as it felt like a change for the sake of change.

export interface Implementation {
Masked: HKTImplementation.Masked;
MaskedDocumentNode: HKTImplementation.MaskedDocumentNode;
export interface TypeOverrides {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Renamed to TypeOverrides to make this more obvious what they are used for. This reads nicely when used in end-user code:

declare module "@apollo/client" {
  export interface TypeOverrides extends GraphQLCodegenDataMasking.TypeOverrides {}
}

}
}

{

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

With the Masked type removed, these sections became copies of the block right before this so I removed it to avoid an unnecessary duplicate.

@phryneas phryneas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Generally approved, assuming a few documentation additions.


3. [Enable data masking](#enabling-data-masking) in Apollo Client.

#### Setting a types mode for masked types

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This document now needs some information on how to opt into the data masking types for codegen.

import { GraphQLCodegenDataMasking } from "@apollo/client/masking";

declare module "@apollo/client" {
  export interface TypeOverrides extends GraphQLCodegenDataMasking.TypeOverrides {}
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good call. I'll make sure that goes in #12835

Comment thread src/masking/PreserveTypes.ts Outdated
Comment thread src/masking/types.ts
type DefaultImplementation = GraphQLCodegenDataMasking.Implementation;
import type { PreserveTypes } from "./PreserveTypes.js";

export interface DataMasking {}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we also remove this interface?

@github-actions github-actions Bot added the auto-cleanup 🤖 label Aug 11, 2025
@phryneas

Copy link
Copy Markdown
Member

I'm going to apply one change (the suggested inlining in PreserveTypes.ts above) and merge this.

Everything else can easily be a follow-up, but it's probably good to get this out into a RC sooner than later.

@phryneas
phryneas merged commit 7c49fdc into release-4.0 Aug 13, 2025
32 of 33 checks passed
@github-actions github-actions Bot mentioned this pull request Aug 13, 2025
@jerelmiller
jerelmiller deleted the jerel/masking-types branch August 14, 2025 14:43
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Sep 14, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants