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

[resolvers][federation] Fix mapper being incorrectly used as the base type for reference #10216

Open
wants to merge 8 commits into
base: federation-fixes
Choose a base branch
from

Conversation

eddeee888
Copy link
Collaborator

@eddeee888 eddeee888 commented Dec 10, 2024

Description

__resolveReference's first param (i.e. usually called "reference") can never be mappers because:

  1. __resolveReference is only called by the gateway with data from @key and/or @requires
  2. __resolveReference is never reached by the subgraph it is in, therefore it can never receive mapper

This PR creates a new FederationTypes to make it easier to target federation object types in entity types that need it.

For example, the following User type is an entity with id being the key

type User @key(fields: "id") {
  id: ID!
  name: String
}

So, the UserResolvers would have some differences compared to normal types:

  1. It has an extra generic: FederationType extends FederationTypes['User'] = FederationTypes['User'] to target the base User entity
  2. __resolveReference uses FederationType to pick the key using GraphQLRecursivePick

Related #10206

Other notes

As part of change from ParentType -> FederationType, we no longer need the UnwrappedObject added when wrapFieldDefinitions = true. This PR also removes this utility type and relevant codes

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

  • Unit test
  • Alpha version tested

Copy link

changeset-bot bot commented Dec 10, 2024

🦋 Changeset detected

Latest commit: a784d3b

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

This PR includes changesets to release 18 packages
Name Type
@graphql-codegen/visitor-plugin-common Major
@graphql-codegen/typescript-resolvers Major
@graphql-codegen/plugin-helpers Major
@graphql-codegen/typescript-document-nodes Patch
@graphql-codegen/gql-tag-operations Patch
@graphql-codegen/typescript-operations Patch
@graphql-codegen/typed-document-node Patch
@graphql-codegen/typescript Patch
@graphql-codegen/introspection Patch
@graphql-codegen/client-preset Patch
@graphql-codegen/graphql-modules-preset Patch
@graphql-codegen/cli Patch
@graphql-codegen/core Patch
@graphql-codegen/testing Patch
@graphql-codegen/add Patch
@graphql-codegen/fragment-matcher Patch
@graphql-codegen/schema-ast Patch
@graphql-codegen/time Patch

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

@eddeee888 eddeee888 mentioned this pull request Dec 10, 2024
34 tasks
Copy link
Contributor

github-actions bot commented Dec 10, 2024

🚀 Snapshot Release (alpha)

The latest changes of this PR are available as alpha on npm (based on the declared changesets):

Package Version Info
@graphql-codegen/visitor-plugin-common 5.6.1-alpha-20241216083520-f3cad5e4c28fc18b31c96b0e186ce2261922c382 npm ↗︎ unpkg ↗︎
@graphql-codegen/typescript-document-nodes 4.0.13-alpha-20241216083520-f3cad5e4c28fc18b31c96b0e186ce2261922c382 npm ↗︎ unpkg ↗︎
@graphql-codegen/gql-tag-operations 4.0.13-alpha-20241216083520-f3cad5e4c28fc18b31c96b0e186ce2261922c382 npm ↗︎ unpkg ↗︎
@graphql-codegen/typescript-operations 4.4.1-alpha-20241216083520-f3cad5e4c28fc18b31c96b0e186ce2261922c382 npm ↗︎ unpkg ↗︎
@graphql-codegen/typescript-resolvers 4.4.2-alpha-20241216083520-f3cad5e4c28fc18b31c96b0e186ce2261922c382 npm ↗︎ unpkg ↗︎
@graphql-codegen/typed-document-node 5.0.13-alpha-20241216083520-f3cad5e4c28fc18b31c96b0e186ce2261922c382 npm ↗︎ unpkg ↗︎
@graphql-codegen/typescript 4.1.3-alpha-20241216083520-f3cad5e4c28fc18b31c96b0e186ce2261922c382 npm ↗︎ unpkg ↗︎
@graphql-codegen/client-preset 4.5.2-alpha-20241216083520-f3cad5e4c28fc18b31c96b0e186ce2261922c382 npm ↗︎ unpkg ↗︎
@graphql-codegen/graphql-modules-preset 4.0.13-alpha-20241216083520-f3cad5e4c28fc18b31c96b0e186ce2261922c382 npm ↗︎ unpkg ↗︎
@graphql-codegen/plugin-helpers 5.1.1-alpha-20241216083520-f3cad5e4c28fc18b31c96b0e186ce2261922c382 npm ↗︎ unpkg ↗︎

Copy link
Contributor

github-actions bot commented Dec 10, 2024

💻 Website Preview

The latest changes are available as preview in: https://29d1ff2c.graphql-code-generator.pages.dev

@eddeee888 eddeee888 changed the base branch from master to federation-fixes December 16, 2024 08:36
@eddeee888 eddeee888 force-pushed the fix-federation-mapper branch from f3cad5e to c932044 Compare December 16, 2024 10:00
Comment on lines +177 to +179
if (resolvableKeyDirectives.length === 0) {
return federationTypeSignature;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Since we need to return federationTypeSignature instead of parentTypeSignature when there's all @key are resolvable=false, I'm changing to return early here to make it easier to read as well

Comment on lines -110 to -113
defsToInclude.push(`export type UnwrappedObject<T> = {
[P in keyof T]: T[P] extends infer R | Promise<infer R> | (() => infer R2 | Promise<infer R2>)
? R & R2 : T[P]
};`);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For a given type:

export type ProductMapper = {
  id: () => Promise<string>;
};

This type seems to return something like (() => Promise<string>) & string which is unusual - How can a function intersect with a string?

Regardless, since we move from ParentType to FederationType, I don't think this is needed in the future.

Comment on lines +1226 to +1246
public buildFederationTypes(): string {
const federationMeta = this._federation.getMeta();

if (Object.keys(federationMeta).length === 0) {
return '';
}

const declarationKind = 'type';
return new DeclarationBlock(this._declarationBlockConfig)
.export()
.asKind(declarationKind)
.withName(this.convertName('FederationTypes'))
.withComment('Mapping of federation types')
.withBlock(
Object.keys(federationMeta)
.map(typeName => {
return indent(`${typeName}: ${this.convertName(typeName)}${this.getPunctuation(declarationKind)}`);
})
.join('\n')
).string;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This FederationTypes type will be used by federation entities to refer to the base types, similar to other types like ResolversParentTypes and ResolversTypes

@eddeee888 eddeee888 force-pushed the fix-federation-mapper branch from 46219bc to 01db0cc Compare December 16, 2024 10:25
@eddeee888 eddeee888 marked this pull request as ready for review December 16, 2024 11:57
@eddeee888 eddeee888 changed the base branch from federation-fixes to master December 16, 2024 11:58
@eddeee888 eddeee888 changed the base branch from master to federation-fixes December 16, 2024 11:58
@eddeee888 eddeee888 force-pushed the fix-federation-mapper branch from 01db0cc to bab88db Compare December 16, 2024 12:02
@eddeee888
Copy link
Collaborator Author

Note: current Examples Tests in CI are broken because of an unrelated issue.

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.

1 participant