Skip to content

Commit d6ceea4

Browse files
committed
Fixed ApolloFederation FieldSet directives. (#6838)
1 parent 9ccda58 commit d6ceea4

File tree

13 files changed

+129
-77
lines changed

13 files changed

+129
-77
lines changed

src/HotChocolate/ApolloFederation/src/ApolloFederation/FederationTypeInterceptor.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,7 @@ public override IEnumerable<TypeReference> RegisterMoreTypes(
102102
yield return _typeInspector.GetTypeRef(typeof(LinkDirective));
103103
}
104104
}
105-
106105

107-
108106
public override void OnBeforeCompleteName(
109107
ITypeCompletionContext completionContext,
110108
DefinitionBase definition)

src/HotChocolate/ApolloFederation/src/ApolloFederation/Types/Directives/ExtendServiceTypeDescriptorExtensions.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ public static IObjectTypeDescriptor<T> ExtendServiceType<T>(
3030
{
3131
ArgumentNullException.ThrowIfNull(descriptor);
3232

33-
descriptor.Directive(ExtendServiceTypeDirective.Default);
33+
if (descriptor.Extend().Context.GetFederationVersion() == FederationVersion.Federation10)
34+
{
35+
descriptor.Directive(ExtendServiceTypeDirective.Default);
36+
}
37+
3438
return descriptor;
3539
}
3640

@@ -62,7 +66,11 @@ public static IObjectTypeDescriptor ExtendServiceType(
6266
{
6367
ArgumentNullException.ThrowIfNull(descriptor);
6468

65-
descriptor.Directive(ExtendServiceTypeDirective.Default);
69+
if (descriptor.Extend().Context.GetFederationVersion() == FederationVersion.Federation10)
70+
{
71+
descriptor.Directive(ExtendServiceTypeDirective.Default);
72+
}
73+
6674
return descriptor;
6775
}
6876
}

src/HotChocolate/ApolloFederation/src/ApolloFederation/Types/Directives/KeyDirective.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,22 @@ namespace HotChocolate.ApolloFederation.Types;
3232
[KeyLegacySupport]
3333
public sealed class KeyDirective
3434
{
35-
public KeyDirective(string fieldSet, bool resolvable = true)
35+
public KeyDirective(string fields, bool resolvable = true)
3636
{
37-
ArgumentException.ThrowIfNullOrEmpty(fieldSet);
38-
FieldSet = FieldSetType.ParseSelectionSet(fieldSet);
37+
ArgumentException.ThrowIfNullOrEmpty(fields);
38+
Fields = FieldSetType.ParseSelectionSet(fields);
3939
Resolvable = resolvable;
4040
}
4141

42-
public KeyDirective(SelectionSetNode fieldSet, bool resolvable = true)
42+
public KeyDirective(SelectionSetNode fields, bool resolvable = true)
4343
{
44-
ArgumentNullException.ThrowIfNull(fieldSet);
45-
FieldSet = fieldSet;
44+
ArgumentNullException.ThrowIfNull(fields);
45+
Fields = fields;
4646
Resolvable = resolvable;
4747
}
4848

4949
[FieldSet]
50-
public SelectionSetNode FieldSet { get; }
50+
public SelectionSetNode Fields { get; }
5151

5252
[GraphQLType<BooleanType>]
5353
[DefaultValue(true)]

src/HotChocolate/ApolloFederation/src/ApolloFederation/Types/Directives/KeyLegacySupportAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ protected override void OnConfigure(
1313
{
1414
var desc = (IDirectiveTypeDescriptor<KeyDirective>)descriptor;
1515
desc.BindArgumentsExplicitly();
16-
desc.Argument(t => t.FieldSet);
16+
desc.Argument(t => t.Fields);
1717
}
1818
}
1919
}

src/HotChocolate/ApolloFederation/src/ApolloFederation/Types/Directives/ProvidesDirective.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
using HotChocolate.Language;
12
using static HotChocolate.ApolloFederation.FederationTypeNames;
23
using static HotChocolate.ApolloFederation.FederationVersionUrls;
34
using static HotChocolate.ApolloFederation.Properties.FederationResources;
5+
using DirectiveLocation = HotChocolate.Types.DirectiveLocation;
46

57
namespace HotChocolate.ApolloFederation.Types;
68

@@ -34,8 +36,20 @@ namespace HotChocolate.ApolloFederation.Types;
3436
[Package(Federation20)]
3537
[DirectiveType(ProvidesDirective_Name, DirectiveLocation.FieldDefinition)]
3638
[GraphQLDescription(ProvidesDirective_Description)]
37-
public sealed class ProvidesDirective(string fieldSet)
39+
public sealed class ProvidesDirective
3840
{
41+
public ProvidesDirective(string fields)
42+
{
43+
ArgumentException.ThrowIfNullOrEmpty(fields);
44+
Fields = FieldSetType.ParseSelectionSet(fields);
45+
}
46+
47+
public ProvidesDirective(SelectionSetNode fields)
48+
{
49+
ArgumentNullException.ThrowIfNull(fields);
50+
Fields = fields;
51+
}
52+
3953
[FieldSet]
40-
public string FieldSet { get; } = fieldSet;
54+
public SelectionSetNode Fields { get; }
4155
}

src/HotChocolate/ApolloFederation/src/ApolloFederation/Types/Directives/RequiresDirective.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
using HotChocolate.Language;
12
using static HotChocolate.ApolloFederation.FederationTypeNames;
23
using static HotChocolate.ApolloFederation.FederationVersionUrls;
34
using static HotChocolate.ApolloFederation.Properties.FederationResources;
5+
using DirectiveLocation = HotChocolate.Types.DirectiveLocation;
46

57
namespace HotChocolate.ApolloFederation.Types;
68

@@ -27,8 +29,20 @@ namespace HotChocolate.ApolloFederation.Types;
2729
[Package(Federation20)]
2830
[DirectiveType(RequiresDirective_Name, DirectiveLocation.FieldDefinition)]
2931
[GraphQLDescription(RequiresDirective_Description)]
30-
public sealed class RequiresDirective(string fieldSet)
32+
public sealed class RequiresDirective
3133
{
34+
public RequiresDirective(string fields)
35+
{
36+
ArgumentException.ThrowIfNullOrEmpty(fields);
37+
Fields = FieldSetType.ParseSelectionSet(fields);
38+
}
39+
40+
public RequiresDirective(SelectionSetNode fields)
41+
{
42+
ArgumentNullException.ThrowIfNull(fields);
43+
Fields = fields;
44+
}
45+
3246
[FieldSet]
33-
public string FieldSet { get; } = fieldSet;
47+
public SelectionSetNode Fields { get; }
3448
}

src/HotChocolate/ApolloFederation/src/ApolloFederation/Types/ServerFields.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public static class ServerFields
1717
internal static ObjectFieldDefinition CreateServiceField(IDescriptorContext context)
1818
{
1919
var descriptor = ObjectFieldDescriptor.New(context, WellKnownFieldNames.Service);
20-
descriptor.Resolve(_service);
20+
descriptor.Type<NonNullType<ObjectType<_Service>>>().Resolve(_service);
2121
descriptor.Definition.PureResolver = Resolve;
2222

2323
static _Service Resolve(IPureResolverContext ctx)

src/HotChocolate/ApolloFederation/test/ApolloFederation.Tests/CertificationSchema/AnnotationBased/__snapshots__/CertificationTests.Provides.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"data": {
33
"product": {
44
"createdBy": {
5-
"email": "support@apollographql.com",
5+
"email": "contact@chillicream.com",
66
"totalProductsCreated": 1337
77
}
88
}

src/HotChocolate/ApolloFederation/test/ApolloFederation.Tests/CertificationSchema/AnnotationBased/__snapshots__/CertificationTests.Schema_Snapshot.snap

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
schema @link(url: "https:\/\/specs.apollo.dev\/federation\/v2.5", import: [ "@extends", "@external", "@key", "@inaccessible", "@override", "@provides", "@requires", "@shareable", "@tag", "FieldSet", "@composeDirective", "@interfaceObject", "@authenticated", "@requiresPolicy" ]) {
1+
schema @link(url: "https:\/\/specs.apollo.dev\/federation\/v2.0", import: [ "@key", "@provides", "FieldSet", "@external" ]) {
22
query: Query
33
}
44

@@ -39,37 +39,20 @@ type _Service {
3939
"Union of all types that key directive applied. This information is needed by the Apollo federation gateway."
4040
union _Entity = Product | User
4141

42-
"Indicates to composition that the target element is accessible only to the authenticated supergraph users."
43-
directive @authenticated on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM
44-
45-
"Marks underlying custom directive to be included in the Supergraph schema."
46-
directive @composeDirective(name: String!) on SCHEMA
47-
48-
"Directive to indicate that marks target object as extending part of the federated schema."
49-
directive @extends on OBJECT | INTERFACE
50-
5142
"Directive to indicate that a field is owned by another service, for example via Apollo federation."
5243
directive @external on FIELD_DEFINITION
5344

54-
"Marks location within schema as inaccessible from the GraphQL Gateway"
55-
directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
56-
57-
"Provides meta information to the router that this entity type is an interface in the supergraph."
58-
directive @interfaceObject on OBJECT
59-
6045
"Used to indicate a combination of fields that can be used to uniquely identify and fetch an object or interface."
61-
directive @key(fields: _FieldSet! resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
46+
directive @key(fields: FieldSet! resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
6247

63-
directive @link(url: String! import: [String!]) repeatable on SCHEMA
64-
65-
"Overrides fields resolution logic from other subgraph. Used for migrating fields from one subgraph to another."
66-
directive @override(from: String!) on FIELD_DEFINITION
48+
"Object representation of @link directive."
49+
directive @link("Gets imported specification url." url: String! "Gets optional list of imported element names." import: [String!]) repeatable on SCHEMA
6750

6851
"Used to annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the federation gateway."
69-
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
52+
directive @provides(fields: FieldSet!) on FIELD_DEFINITION
53+
54+
"Scalar representing a set of fields."
55+
scalar FieldSet
7056

7157
"The _Any scalar is used to pass representations of entities from external services into the root _entities field for execution. Validation of the _Any scalar is done by matching the __typename and @external fields defined in the schema."
7258
scalar _Any
73-
74-
"Scalar representing a set of fields."
75-
scalar _FieldSet

src/HotChocolate/ApolloFederation/test/ApolloFederation.Tests/CertificationSchema/AnnotationBased/__snapshots__/CertificationTests.Subgraph_SDL.snap

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
schema @link(url: "https:\/\/specs.apollo.dev\/federation\/v2.5", import: [ "@extends", "@external", "@key", "@inaccessible", "@override", "@provides", "@requires", "@shareable", "@tag", "FieldSet", "@composeDirective", "@interfaceObject", "@authenticated", "@requiresPolicy" ]) {
1+
schema @link(url: "https:\/\/specs.apollo.dev\/federation\/v2.0", import: [ "@key", "@provides", "FieldSet", "@external" ]) {
22
query: Query
33
}
44

@@ -30,3 +30,29 @@ type User @key(fields: "email") {
3030
email: ID! @external
3131
totalProductsCreated: Int @external
3232
}
33+
34+
"This type provides a field named sdl: String! which exposes the SDL of the service's schema. This SDL (schema definition language) is a printed version of the service's schema including the annotations of federation directives. This SDL does not include the additions of the federation spec."
35+
type _Service {
36+
sdl: String!
37+
}
38+
39+
"Union of all types that key directive applied. This information is needed by the Apollo federation gateway."
40+
union _Entity = Product | User
41+
42+
"Directive to indicate that a field is owned by another service, for example via Apollo federation."
43+
directive @external on FIELD_DEFINITION
44+
45+
"Used to indicate a combination of fields that can be used to uniquely identify and fetch an object or interface."
46+
directive @key(fields: FieldSet! resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
47+
48+
"Object representation of @link directive."
49+
directive @link("Gets imported specification url." url: String! "Gets optional list of imported element names." import: [String!]) repeatable on SCHEMA
50+
51+
"Used to annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the federation gateway."
52+
directive @provides(fields: FieldSet!) on FIELD_DEFINITION
53+
54+
"Scalar representing a set of fields."
55+
scalar FieldSet
56+
57+
"The _Any scalar is used to pass representations of entities from external services into the root _entities field for execution. Validation of the _Any scalar is done by matching the __typename and @external fields defined in the schema."
58+
scalar _Any

0 commit comments

Comments
 (0)