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

Errors with rover subgraph publish due to invalid definition #59

Open
damienpontifex opened this issue Nov 25, 2023 · 4 comments
Open

Comments

@damienpontifex
Copy link
Contributor

Subgraph publish errors when using this library:

DIRECTIVE_DEFINITION_INVALID: [shop] Invalid definition for directive "@key": argument "fields" should have type "_FieldSet!" but found type "FieldSet!"
DIRECTIVE_DEFINITION_INVALID: [shop] Invalid definition for directive "@requires": argument "fields" should have type "_FieldSet!" but found type "FieldSet!"
DIRECTIVE_DEFINITION_INVALID: [shop] Invalid definition for directive "@provides": argument "fields" should have type "_FieldSet!" but found type "FieldSet!"

The directives that are written in the schema (whether through /graphql?sdl or rover subgraph introspect) are

directive @allowAnonymous repeatable on FIELD_DEFINITION

"Indicates to composition that the target element is accessible only to the authenticated supergraph users."
directive @authenticated on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM

directive @authorize("The name of the authorization policy that determines access to the annotated resource." policy: String "Roles that are allowed to access the annotated resource." roles: [String!] "Defines when when the authorize directive shall be applied.By default the authorize directives are applied during the validation phase." apply: ApplyPolicy! = BEFORE_RESOLVER) repeatable on OBJECT | FIELD_DEFINITION

"Marks underlying custom directive to be included in the Supergraph schema."
directive @composeDirective(name: String!) on SCHEMA

"Provides contact information of the owner responsible for this subgraph schema."
directive @contact(name: String! url: String description: String) on SCHEMA

"Directive to indicate that marks target object as extending part of the federated schema."
directive @extends on OBJECT | INTERFACE

"Directive to indicate that a field is owned by another service, for example via Apollo federation."
directive @external on OBJECT | FIELD_DEFINITION

"Marks location within schema as inaccessible from the GraphQL Gateway"
directive @inaccessible on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION

"Provides meta information to the router that this entity type is an interface in the supergraph."
directive @interfaceObject on OBJECT

"Used to indicate a combination of fields that can be used to uniquely identify and fetch an object or interface."
directive @key(fields: FieldSet! resolvable: Boolean = true) repeatable on OBJECT | INTERFACE

directive @link(url: String! import: [String]) repeatable on SCHEMA

"Overrides fields resolution logic from other subgraph. Used for migrating fields from one subgraph to another."
directive @override(from: String!) on FIELD_DEFINITION

"Used to annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the federation gateway."
directive @provides(fields: FieldSet!) on FIELD_DEFINITION

"Used to annotate the required input fieldset from a base type for a resolver."
directive @requires(fields: FieldSet!) on FIELD_DEFINITION

"Indicates to composition that the target element is accessible only to the authenticated supergraph users with the appropriate JWT scopes."
directive @requiresScopes(scopes: [[Scope!]!]!) on SCALAR | OBJECT | FIELD_DEFINITION | INTERFACE | ENUM

"Indicates that given object and\/or field can be resolved by multiple subgraphs."
directive @shareable repeatable on OBJECT | FIELD_DEFINITION

"Allows users to annotate fields and types with additional metadata information."
directive @tag(name: String!) on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION

"The built-in `Decimal` scalar type."
scalar Decimal

"Scalar representing a set of fields."
scalar FieldSet

"Scalar representing a JWT scope"
scalar Scope

"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."
scalar _Any

Versions used

ApolloGraphQL.HotChocolate.Federation: 1.2.1
HotChocolate.* 13.6.1

Setup code

builder.Services.AddGraphQLServer()
    .AddApolloFederationV2(schemaConfiguration: schema =>
    {
        schema.Contact(
            name: "<value>",
            url: "<value>",
            description: "<value>"
        );
    })
    .AddDirectiveType<ContactDirectiveType>()
    .AddQueryType<Query>()
    .AddAuthorization()
    .AddInstrumentation(o =>
    {
        o.IncludeDocument = true;
        o.RenameRootActivity = true;
    })
    .InitializeOnStartup();
@dariuszkuc
Copy link
Member

Hello 👋
This issue is generally caused when you are trying to upload Federation v2 schema (which uses FieldSet) as a Federation v1 schema (which used _FieldSet). Make sure your supergraph is using v2 composition and double check whether your generated SDL applies @link on your schema type.

@damienpontifex
Copy link
Contributor Author

This is a new graph in studio and has 2.5 as the version
image

On my side/client side, this is using setup code as posted above, which (without specifying the version), I can see is using fed 2.5

public static ISchemaBuilder AddApolloFederationV2(
this ISchemaBuilder builder,
FederationVersion version = FederationVersion.FEDERATION_25,
Action<ISchemaTypeDescriptor>? schemaConfiguration = null)

The generated SDL definitely doesn't have @link, rather is declaring all the directives in the schema output (pasted above). Although I haven't configured anything to use or not use link, my assumption is it would do that automatically.

@damienpontifex
Copy link
Contributor Author

Sample project reproducing the issue https://github.com/damienpontifex/HotChocolate.Fed.Issue

@willgittoes
Copy link

willgittoes commented Dec 12, 2023

I had the same issue when I didn't have a link before my schema:

schema @link(url: "https:\/\/specs.apollo.dev\/federation\/v2.5", import: [ "@extends", "@external", "@key", "@inaccessible", "@override", "@provides", "@requires", "@shareable", "@tag", "FieldSet", "@composeDirective", "@interfaceObject" ]) {
  query: Query
}

For some reason this doesn't seem to be generated when I call BuildSchemaAsync().Print(), but when I add it in manually it will at least allow me to publish the subgraph schema.

Edit: Probably because of this: #55

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

No branches or pull requests

3 participants