diff --git a/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource.go b/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource.go index b82be9f9ef..21decffd1c 100644 --- a/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource.go +++ b/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource.go @@ -944,7 +944,12 @@ func (p *Planner) addOnTypeInlineFragment() { selectionSet := p.upstreamOperation.AddSelectionSet() p.addTypenameToSelectionSet(p.nodes[len(p.nodes)-1].Ref) + onTypeName := p.visitor.Config.Types.RenameTypeNameOnMatchBytes([]byte(p.lastFieldEnclosingTypeName)) + + // rename type name in case it is required by entity interface + onTypeName = p.dataSourceConfig.RenameTypes.RenameTypeNameOnMatchBytes([]byte(p.lastFieldEnclosingTypeName)) + typeRef := p.upstreamOperation.AddNamedType(onTypeName) inlineFragment := p.upstreamOperation.AddInlineFragment(ast.InlineFragment{ HasSelections: true, @@ -1449,7 +1454,7 @@ func (p *Planner) printOperation() []byte { return nil } - p.printQueryPlan(p.upstreamOperation) + p.printQueryPlan(operation) buf.Reset() diff --git a/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource_federation_entity_interfaces_test.go b/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource_federation_entity_interfaces_test.go index d1c0db59e2..5357058dc8 100644 --- a/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource_federation_entity_interfaces_test.go +++ b/v2/pkg/engine/datasource/graphql_datasource/graphql_datasource_federation_entity_interfaces_test.go @@ -86,10 +86,6 @@ func TestGraphQLDataSourceFederationEntityInterfaces(t *testing.T) { firstDatasourceConfiguration := plan.DataSourceConfiguration{ RootNodes: []plan.TypeField{ - { - TypeName: "Account", - FieldNames: []string{"id", "title"}, - }, { TypeName: "Admin", FieldNames: []string{"id"}, @@ -107,6 +103,12 @@ func TestGraphQLDataSourceFederationEntityInterfaces(t *testing.T) { FieldNames: []string{"allAccountsInterface", "allAccountsUnion", "user", "admin"}, }, }, + ChildNodes: []plan.TypeField{ + { + TypeName: "Account", + FieldNames: []string{"id", "title"}, + }, + }, Custom: ConfigJson(Configuration{ Fetch: FetchConfiguration{ URL: "http://first.service", @@ -163,6 +165,18 @@ func TestGraphQLDataSourceFederationEntityInterfaces(t *testing.T) { TypeName: "Account", FieldNames: []string{"id", "locations"}, }, + { + TypeName: "User", + FieldNames: []string{"id", "locations"}, + }, + { + TypeName: "Moderator", + FieldNames: []string{"id", "locations"}, + }, + { + TypeName: "Admin", + FieldNames: []string{"id", "locations"}, + }, { TypeName: "Query", FieldNames: []string{"accountLocations"}, @@ -191,6 +205,35 @@ func TestGraphQLDataSourceFederationEntityInterfaces(t *testing.T) { TypeName: "Account", SelectionSet: "id", }, + { + TypeName: "Admin", + InterfaceNames: []string{"Account"}, + SelectionSet: "id", + }, + { + TypeName: "Moderator", + InterfaceNames: []string{"Account"}, + SelectionSet: "id", + }, + { + TypeName: "User", + InterfaceNames: []string{"Account"}, + SelectionSet: "id", + }, + }, + }, + RenameTypes: plan.TypeConfigurations{ + { + TypeName: "Admin", + RenameTo: "Account", + }, + { + TypeName: "Moderator", + RenameTo: "Account", + }, + { + TypeName: "User", + RenameTo: "Account", }, }, } @@ -241,6 +284,18 @@ func TestGraphQLDataSourceFederationEntityInterfaces(t *testing.T) { TypeName: "Account", FieldNames: []string{"id", "age"}, }, + { + TypeName: "User", + FieldNames: []string{"id", "age"}, + }, + { + TypeName: "Moderator", + FieldNames: []string{"id", "age"}, + }, + { + TypeName: "Admin", + FieldNames: []string{"id", "age"}, + }, }, Custom: ConfigJson(Configuration{ Fetch: FetchConfiguration{ @@ -259,6 +314,35 @@ func TestGraphQLDataSourceFederationEntityInterfaces(t *testing.T) { TypeName: "Account", SelectionSet: "id", }, + { + TypeName: "Admin", + InterfaceNames: []string{"Account"}, + SelectionSet: "id", + }, + { + TypeName: "Moderator", + InterfaceNames: []string{"Account"}, + SelectionSet: "id", + }, + { + TypeName: "User", + InterfaceNames: []string{"Account"}, + SelectionSet: "id", + }, + }, + }, + RenameTypes: plan.TypeConfigurations{ + { + TypeName: "Admin", + RenameTo: "Account", + }, + { + TypeName: "Moderator", + RenameTo: "Account", + }, + { + TypeName: "User", + RenameTo: "Account", }, }, } @@ -274,25 +358,33 @@ func TestGraphQLDataSourceFederationEntityInterfaces(t *testing.T) { DataSources: ShuffleDS(dataSources), DisableResolveFieldPositions: true, Debug: plan.DebugConfiguration{ - PrintQueryPlans: true, + PrintOperationTransformations: true, + PrintQueryPlans: true, + PrintPlanningPaths: true, + PrintNodeSuggestions: true, }, } - t.Run("query 1 - ", func(t *testing.T) { + t.Run("query 1 - Interface to interface object", func(t *testing.T) { t.Run("run", RunTest( definition, ` - query { + query _1_InterfaceToInterfaceObject { + allAccountsInterface { + id + locations { + country + } } - `, - "Accounts", + }`, + "_1_InterfaceToInterfaceObject", &plan.SynchronousResponsePlan{ Response: &resolve.GraphQLResponse{ Data: &resolve.Object{ Fetch: &resolve.SingleFetch{ FetchConfiguration: resolve.FetchConfiguration{ - Input: `{"method":"POST","url":"http://first.service","body":{"query":"{account {__typename ... on User {__typename id} ... on Admin {__typename id}}}"}}`, + Input: `{"method":"POST","url":"http://first.service","body":{"query":""}}`, PostProcessing: DefaultPostProcessingConfiguration, DataSource: &Source{}, }, diff --git a/v2/pkg/engine/plan/datasource_configuration.go b/v2/pkg/engine/plan/datasource_configuration.go index b6d09ea3e2..654a902dd2 100644 --- a/v2/pkg/engine/plan/datasource_configuration.go +++ b/v2/pkg/engine/plan/datasource_configuration.go @@ -38,6 +38,7 @@ type DataSourceConfiguration struct { Custom json.RawMessage FederationMetaData FederationMetaData + RenameTypes TypeConfigurations hash DSHash }