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

Aligned Fusion more with the Fusion spec. #6485

Merged
merged 6 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions src/HotChocolate/Fusion/src/Abstractions/FusionEnumValueNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,17 @@ namespace HotChocolate.Fusion;
internal static class FusionEnumValueNames
{
/// <summary>
/// Gets the name of the query resolver kind.
/// Gets the name of the fetch resolver kind.
/// </summary>
public const string Query = "QUERY";
public const string Fetch = "FETCH";

/// <summary>
/// Gets the name of the batch resolver kind.
/// </summary>
public const string Batch = "BATCH";

/// <summary>
/// Gets the name of the batch by key resolver kind.
/// Gets the name of the subscibe resolver kind.
michaelstaib marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
public const string BatchByKey = "BATCH_BY_KEY";

/// <summary>
/// Gets the name of the subscription resolver kind.
/// </summary>
public const string Subscription = "SUBSCRIPTION";
public const string Subscribe = "SUBSCRIBE";
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ public enum EntityResolverKind
{
Single = 0,
Batch = 1,
BatchWithKey = 2,
Subscription = 3
Subscribe = 2
}
37 changes: 24 additions & 13 deletions src/HotChocolate/Fusion/src/Composition/FusionTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,9 @@ private InputObjectType RegisterArgumentDefType(
private EnumType RegisterResolverKindType(string name)
{
var resolverKind = new EnumType(name);
resolverKind.Values.Add(new EnumValue(FusionEnumValueNames.Query));
resolverKind.Values.Add(new EnumValue(FusionEnumValueNames.Fetch));
resolverKind.Values.Add(new EnumValue(FusionEnumValueNames.Batch));
resolverKind.Values.Add(new EnumValue(FusionEnumValueNames.BatchByKey));
resolverKind.Values.Add(new EnumValue(FusionEnumValueNames.Subscription));
resolverKind.Values.Add(new EnumValue(FusionEnumValueNames.Subscribe));
resolverKind.ContextData.Add(WellKnownContextData.IsFusionType, true);
_fusionGraph.Types.Add(resolverKind);
return resolverKind;
Expand Down Expand Up @@ -237,8 +236,7 @@ public Directive CreateResolverDirective(
var kindValue = kind switch
{
EntityResolverKind.Batch => FusionEnumValueNames.Batch,
EntityResolverKind.BatchWithKey => FusionEnumValueNames.BatchByKey,
EntityResolverKind.Subscription => FusionEnumValueNames.Subscription,
EntityResolverKind.Subscribe => FusionEnumValueNames.Subscribe,
_ => throw new NotSupportedException()
};

Expand All @@ -256,12 +254,11 @@ private DirectiveType RegisterResolverDirectiveType(
EnumType resolverKind)
{
var directiveType = new DirectiveType(name);
directiveType.Locations |= DirectiveLocation.Object;
directiveType.Arguments.Add(new InputField(SelectArg, new NonNullType(selectionSet)));
directiveType.Arguments.Add(new InputField(SubgraphArg, new NonNullType(typeName)));
directiveType.Arguments.Add(
new InputField(ArgumentsArg, new ListType(new NonNullType(argumentDef))));
directiveType.Arguments.Add(new InputField(ArgumentsArg, new ListType(new NonNullType(argumentDef))));
directiveType.Arguments.Add(new InputField(KindArg, resolverKind));
directiveType.Locations |= DirectiveLocation.Object;
directiveType.ContextData.Add(WellKnownContextData.IsFusionType, true);
_fusionGraph.DirectiveTypes.Add(directiveType);
return directiveType;
Expand All @@ -279,11 +276,25 @@ public Directive CreateSourceDirective(string subgraphName, string? originalName

private DirectiveType RegisterSourceDirectiveType(string name, ScalarType typeName)
{
var directiveType = new DirectiveType(name);
directiveType.Locations = DirectiveLocation.FieldDefinition;
directiveType.Arguments.Add(new InputField(SubgraphArg, new NonNullType(typeName)));
directiveType.Arguments.Add(new InputField(NameArg, typeName));
directiveType.ContextData.Add(WellKnownContextData.IsFusionType, true);
var directiveType = new DirectiveType(name)
{
Locations = DirectiveLocation.Object |
DirectiveLocation.FieldDefinition |
DirectiveLocation.Enum |
DirectiveLocation.EnumValue |
DirectiveLocation.InputObject |
DirectiveLocation.InputFieldDefinition |
DirectiveLocation.Scalar,
Arguments =
{
new InputField(SubgraphArg, new NonNullType(typeName)),
new InputField(NameArg, typeName)
},
ContextData =
{
[WellKnownContextData.IsFusionType] = true
}
};
_fusionGraph.DirectiveTypes.Add(directiveType);
return directiveType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ private static void ResolveWithNodes(

// Create a new EntityResolver for the entity
var resolver = new EntityResolver(
EntityResolverKind.BatchWithKey,
EntityResolverKind.Batch,
selectionSet,
sourceType.Name,
sourceSchema.Name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ private static void TryRegisterBatchEntityResolver(

// Create a new EntityResolver for the entity
var resolver = new EntityResolver(
EntityResolverKind.BatchWithKey,
EntityResolverKind.Batch,
selectionSet,
entityType.Name,
schema.Name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public ValueTask EnrichAsync(

// Create a new EntityResolver for the entity
var resolver = new EntityResolver(
EntityResolverKind.BatchWithKey,
EntityResolverKind.Batch,
selectionSet,
type.Name,
schema.Name);
Expand Down Expand Up @@ -92,6 +92,7 @@ private static void TryRegisterEntityResolver(
if ((entityResolverField.Type == entityType ||
(entityResolverField.Type.Kind is TypeKind.NonNull &&
entityResolverField.Type.InnerType() == entityType)) &&
entityResolverField.Arguments.Count > 0 &&
entityResolverField.Arguments.All(t => t.ContainsIsDirective()))
{
var arguments = new List<ArgumentNode>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private static Directive CreateResolverDirective(
subgraphName,
selectionSet,
arguments,
EntityResolverKind.Subscription);
EntityResolverKind.Subscribe);

private static Directive CreateVariableDirective(
CompositionContext context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,10 +453,9 @@ private ResolverDefinition ReadResolverDefinition(
case KindArg:
kind = Expect<StringValueNode>(argument.Value).Value switch
{
FusionEnumValueNames.Query => ResolverKind.Query,
FusionEnumValueNames.Fetch => ResolverKind.Query,
FusionEnumValueNames.Batch => ResolverKind.Batch,
FusionEnumValueNames.BatchByKey => ResolverKind.BatchByKey,
FusionEnumValueNames.Subscription => ResolverKind.Subscription,
FusionEnumValueNames.Subscribe => ResolverKind.Subscribe,
_ => throw new InvalidOperationException(
FusionGraphConfigurationReader_ReadResolverDefinition_InvalidKindValue)
};
Expand Down
3 changes: 1 addition & 2 deletions src/HotChocolate/Fusion/src/Core/Metadata/ResolverKind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ internal enum ResolverKind
{
Query,
Batch,
BatchByKey,
Subscription,
Subscribe,
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using HotChocolate.Types;
using HotChocolate.Utilities;
using static HotChocolate.Fusion.FusionResources;
using static HotChocolate.Fusion.Metadata.ResolverKind;

namespace HotChocolate.Fusion.Planning.Pipeline;

Expand Down Expand Up @@ -42,14 +41,14 @@ public void Invoke(QueryPlanContext context, QueryPlanDelegate next)
continue;
}

if (selectionStep.Resolver?.Kind == BatchByKey)
if (selectionStep.Resolver?.Kind == ResolverKind.Batch)
{
var resolve = CreateResolveByKeyBatchNode(context, selectionStep);
context.RegisterNode(resolve, selectionStep);
}
else if (selectionStep.Resolver is null &&
selectionStep.RootSelections.Count == 1 &&
selectionStep.RootSelections[0].Resolver?.Kind is Subscription)
selectionStep.RootSelections[0].Resolver?.Kind is ResolverKind.Subscribe)
{
var resolve = CreateSubscribeNode(context, selectionStep);
context.RegisterNode(resolve, selectionStep);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ private static bool TryGetResolver(
{
if (preference is PreferredResolverKind.Subscription)
{
if (current.Kind is ResolverKind.Subscription)
if (current.Kind is ResolverKind.Subscribe)
{
resolver = current;
return true;
Expand All @@ -616,15 +616,6 @@ private static bool TryGetResolver(
{
case ResolverKind.Batch:
resolver = current;

if (preference is PreferredResolverKind.Batch)
{
return true;
}
break;

case ResolverKind.BatchByKey:
resolver = current;
break;

default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,7 @@ private static ResolverDefinition SelectResolver(
if (requirements > resolver.Requires.Count || selectedResolver is null ||
(selectedResolver.Requires.Count == resolver.Requires.Count &&
selectedResolver.Kind == ResolverKind.Query &&
(resolver.Kind == ResolverKind.Batch ||
resolver.Kind == ResolverKind.BatchByKey)))
resolver.Kind == ResolverKind.Batch))
{
requirements = resolver.Requires.Count;
selectedResolver = resolver;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ currentStep.ParentSelection is { } parent &&

// if we do by key batching the current execution step must
// re-export its requirements so we know where entities belong to.
if (currentStep.Resolver.Kind is ResolverKind.BatchByKey)
if (currentStep.Resolver.Kind is ResolverKind.Batch)
{
foreach (var variable in step.SelectionSetTypeMetadata.Variables)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Query {
userById(id: ID!): User
users: [User!]!
usersById(ids: [ID!]!): [User!]!
viewer: Viewer!
}

type Mutation {
Expand All @@ -19,13 +20,22 @@ type AddUserPayload {
user: User
}

type SomeData {
accountValue: String!
}

type User implements Node {
birthdate: Date!
id: ID!
name: String!
username: String!
}

type Viewer {
data: SomeData!
user: User
}

interface Node {
id: ID!
}
Expand Down Expand Up @@ -54,6 +64,7 @@ type Query {
userById(id: ID!): User @variable(subgraph: "Accounts", name: "id", argument: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $id) }", arguments: [ { name: "id", type: "ID!" } ])
users: [User!]! @resolver(subgraph: "Accounts", select: "{ users }")
usersById(ids: [ID!]!): [User!]! @variable(subgraph: "Accounts", name: "ids", argument: "ids") @resolver(subgraph: "Accounts", select: "{ usersById(ids: $ids) }", arguments: [ { name: "ids", type: "[ID!]!" } ])
viewer: Viewer! @resolver(subgraph: "Accounts", select: "{ viewer }")
}

type Mutation {
Expand All @@ -64,13 +75,22 @@ type AddUserPayload {
user: User @source(subgraph: "Accounts")
}

type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH_BY_KEY") {
type SomeData {
accountValue: String! @source(subgraph: "Accounts")
}

type User implements Node @variable(subgraph: "Accounts", name: "User_id", select: "id") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ usersById(ids: $User_id) }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") @resolver(subgraph: "Accounts", select: "{ userById(id: $User_id) }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ node(id: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "ID!" } ]) @resolver(subgraph: "Accounts", select: "{ nodes(ids: $User_id) { ... on User { ... User } } }", arguments: [ { name: "User_id", type: "[ID!]!" } ], kind: "BATCH") {
birthdate: Date! @source(subgraph: "Accounts")
id: ID! @source(subgraph: "Accounts")
name: String! @source(subgraph: "Accounts")
username: String! @source(subgraph: "Accounts")
}

type Viewer {
data: SomeData! @source(subgraph: "Accounts")
user: User @source(subgraph: "Accounts")
}

interface Node {
id: ID!
}
Expand All @@ -92,7 +112,7 @@ Accounts Subgraph Configuration
---------------
{
"Name": "Accounts",
"Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\ntype User implements Node {\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\n\"The `DateTime` scalar represents an ISO-8601 compliant date time type.\"\nscalar DateTime\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: DateTime!\n}\n\ntype AddUserPayload {\n user: User\n}",
"Schema": "schema {\n query: Query\n mutation: Mutation\n}\n\n\"The node interface is implemented by entities that have a global unique identifier.\"\ninterface Node {\n id: ID!\n}\n\ntype Query {\n \"Fetches an object given its ID.\"\n node(\"ID of the object.\" id: ID!): Node\n \"Lookup nodes by a list of IDs.\"\n nodes(\"The list of node IDs.\" ids: [ID!]!): [Node]!\n users: [User!]!\n userById(id: ID!): User\n usersById(ids: [ID!]!): [User!]!\n viewer: Viewer!\n}\n\ntype Mutation {\n addUser(input: AddUserInput!): AddUserPayload!\n}\n\ntype User implements Node {\n id: ID!\n name: String!\n birthdate: Date!\n username: String!\n}\n\ntype Viewer {\n user: User\n data: SomeData!\n}\n\n\"The `DateTime` scalar represents an ISO-8601 compliant date time type.\"\nscalar DateTime\n\n\"The `Date` scalar represents an ISO-8601 compliant date type.\"\nscalar Date\n\ntype SomeData {\n accountValue: String!\n}\n\ninput AddUserInput {\n name: String!\n username: String!\n birthdate: DateTime!\n}\n\ntype AddUserPayload {\n user: User\n}",
"Extensions": [
"extend type Query {\n userById(id: ID!\n @is(field: \"id\")): User!\n usersById(ids: [ID!]!\n @is(field: \"id\")): [User!]!\n}"
],
Expand Down
Loading