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

Apollo federation with code-first approach adds "@tag" to schema, throwing "invalid definition for directive "@tag" #2646

Closed
2 of 4 tasks
sebastiangug opened this issue Feb 12, 2023 · 5 comments

Comments

@sebastiangug
Copy link

sebastiangug commented Feb 12, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

With the code-first approach and with the federation driver (not the normal one), there is this bit that gets added by default to the schema:

directive @tag(name: String!) repeatable on ARGUMENT_DEFINITION | ENUM | ENUM_VALUE | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | INPUT_OBJECT | INTERFACE | OBJECT | SCALAR | SCHEMA | UNION

This then makes the server throw on startup:

AggregateGraphQLError [GraphQLError]: The schema is not a valid GraphQL schema.. Caused by:
Invalid definition for directive "@tag": "@tag" should have locations FIELD_DEFINITION, OBJECT, INTERFACE, UNION, ARGUMENT_DEFINITION, SCALAR, ENUM, ENUM_VALUE, INPUT_OBJECT, INPUT_FIELD_DEFINITION, but found (non-subset) FIELD_DEFINITION, OBJECT, INTERFACE, UNION, ARGUMENT_DEFINITION, SCALAR, ENUM, ENUM_VALUE, INPUT_OBJECT, INPUT_FIELD_DEFINITION, SCHEMA
.
.
.
.
.
path: undefined,
  locations: undefined,
  extensions: { code: 'GraphQLValidationFailed' },
  causes: [
    GraphQLError: Invalid definition for directive "@tag": "@tag" should have locations FIELD_DEFINITION, OBJECT, INTERFACE, UNION, ARGUMENT_DEFINITION, SCALAR, ENUM, ENUM_VALUE, INPUT_OBJECT, INPUT_FIELD_DEFINITION, but found (non-subset) FIELD_DEFINITION, OBJECT, INTERFACE, UNION, ARGUMENT_DEFINITION, SCALAR, ENUM, ENUM_VALUE, INPUT_OBJECT, INPUT_FIELD_DEFINITION, SCHEMA

Minimum reproduction code

https://github.com/sebastiangug/nest-graphql-vite

Steps to reproduce

  1. pnpm i
  2. pnpm dev
  3. go to http://localhost:3100/health so the server builds (vite doesn't build it until you make a req)

Expected behavior

Application should start

Package version

10.1.7

Graphql version

graphql: 16.6.0
apollo-server-express: 3.11.1
apollo-server-fastify:

NestJS version

9.3.2

Node.js version

19.5.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

EDIT:

    "@apollo/gateway": "2.1.2",
    "@apollo/subgraph": "2.1.2",

Changing these two dependencies to this version seems to fix the issue, therefore I'm guessing nestjs's code-first approach just doesn't support whatever was changed between those two versions?

@Tony133
Copy link
Contributor

Tony133 commented Feb 12, 2023

Hi @sebastiangug,

there is an open issue in the repository of the federation of apollograhql concerning this issue see here: apollographql/federation#2375

so it is not a problem related to the @nestjs/graphql package but rather to the @apollo/subgraph package.

however by updating these packages in your minimal reproduction

"@apollo/gateway": "2.2.3",
"@apollo/subgraph": "2.2.3"

you solve the problem ( see screenshot )

Screenshot 2023-02-12 alle 23 06 45

i hope i have been helpful

@geekmini
Copy link

geekmini commented Feb 22, 2023

My solution is to use the federation version 2, and you don't have to limit the version of package @apollo/subgraph

    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      // use the federation version 2
      autoSchemaFile: isOnline ? false : { path: "schema.gql", federation: 2 },
    })

@ddimitrioglo
Copy link

@Tony133 Thank you, man! You've saved my day!

P.S. For those who are exposing the schema as a subgraph "@apollo/subgraph": "2.2.3" is the only library that you need

@coler-j
Copy link

coler-j commented May 29, 2023

Tl;DR:

  • 31-graphql-federation-code-first sample appears to be broken with the @tag error
  • 31-graphql-federation-code-first with federation: 2 does not output federation directives in autoSchema file, but does generate the directives when running through introspection. Is there more details as to why?

I think this should be re-opened this error is currently demonstrable in the NestJS sample repo as it currently exists.

This issue is happening in the NestJS sample federated code first example: https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first

Pull that sample project, install the dependencies of each subgraph with a npm install and then on run you will get:

image

The dependencies of that sample repo are set to:

"@apollo/gateway": "2.4.0",
"@apollo/server": "4.5.0",
"@apollo/subgraph": "2.4.0",
"@nestjs/apollo": "11.0.4",
"@nestjs/graphql": "11.0.0",
"graphql": "16.6.0",

The issue persists if you update all dependencies as well:

"@apollo/gateway": "2.4.6",
"@apollo/server": "4.7.1",
"@apollo/subgraph": "2.4.6",
"@nestjs/apollo": "11.0.6",
"@nestjs/graphql": "11.0.6",

Also a related question:

In the sample codebase, with the above dependencies if you try to use Federation 2 by changing the config to:

GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: {
        path: "schema.gql", federation: 2
      },
    }),

Then the schema generated by autoSchemaFile will no longer have any federation directives outputted:

# ------------------------------------------------------
# THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
# ------------------------------------------------------

type User {
  id: ID!
  name: String!
}

type Query {
  getUser(id: ID!): User!
}

But the "@tag" error will go away, but I do not think this is producing a correct subgraph schema. (Seems related to #2231 or #1597) as directives are missing.

The schema still seems to be usable though through the gateway, and if you introspect through gql playground you can see the directives

image

Introspection of user GQL endpoint running with Federation 2 config:

directive @link(
  url: String
  as: String
  for: link__Purpose
  import: [link__Import]
) on SCHEMA

directive @key(
  fields: federation__FieldSet!
  resolvable: Boolean = true
) on OBJECT | INTERFACE

directive @requires(fields: federation__FieldSet!) on FIELD_DEFINITION

directive @provides(fields: federation__FieldSet!) on FIELD_DEFINITION

directive @external(reason: String) on OBJECT | FIELD_DEFINITION

directive @tag(
  name: String!
) on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA

directive @extends on OBJECT | INTERFACE

directive @shareable on OBJECT | FIELD_DEFINITION

directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION

directive @override(from: String!) on FIELD_DEFINITION

directive @composeDirective(name: String) on SCHEMA

directive @interfaceObject on OBJECT

type User {
  id: ID!
  name: String!
}

type Query {
  getUser(id: ID!): User!
  _entities(representations: [_Any!]!): [_Entity]!
  _service: _Service!
}

enum link__Purpose {
  # `SECURITY` features provide metadata necessary to securely resolve fields.
  SECURITY

  # `EXECUTION` features provide metadata necessary for operation execution.
  EXECUTION
}

scalar link__Import

scalar federation__FieldSet

scalar _Any

type _Service {
  sdl: String
}

union _Entity = User

@iamgutz
Copy link

iamgutz commented May 8, 2024

This is happening again on @apollo/subgraph version 2.7.6
Downgrading to version 2.2.3 fixed the problem. Newer version produce this error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants