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

cannot load a supergraph composed by rover #837

Closed
Geal opened this issue Apr 12, 2022 · 3 comments
Closed

cannot load a supergraph composed by rover #837

Geal opened this issue Apr 12, 2022 · 3 comments
Assignees

Comments

@Geal
Copy link
Contributor

Geal commented Apr 12, 2022

If I try to compose the following subgraphs(obtained with rover subgraph introspect):

speakers.graphql:

schema
  @link(url: "https://specs.apollo.dev/link/v1.0")
{
  query: Query
}

extend schema
  @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key", "@shareable"])

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

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

directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION

directive @federation__provides(fields: federation__FieldSet!) on FIELD_DEFINITION

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

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

directive @federation__extends on OBJECT | INTERFACE

directive @shareable on OBJECT | FIELD_DEFINITION

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

directive @federation__override(from: String!) on FIELD_DEFINITION

type Speaker
  @key(fields: "link")
{
  uuid: ID!
  firstName: String
  lastName: String
  link: String
}

type Query {
  speakers: [Speaker]
  speaker(id: ID!): Speaker
  _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 = Speaker

schedule.graphql

schema
  @link(url: "https://specs.apollo.dev/link/v1.0")
{
  query: Query
}

extend schema
  @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key", "@shareable", "@external"])

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

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

directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION

directive @federation__provides(fields: federation__FieldSet!) on FIELD_DEFINITION

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

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

directive @federation__extends on OBJECT | INTERFACE

directive @shareable on OBJECT | FIELD_DEFINITION

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

directive @federation__override(from: String!) on FIELD_DEFINITION

type Room {
  id: ID!
  name: String
  capacity: Int
}

type Slot {
  roomId: ID!
  slotId: ID!
  talk: Talk
}

type Talk {
  trackId: String
  talkType: String
  talkId: ID!
  title: String
  speakers: [Speaker]
}

extend type Speaker
  @key(fields: "link")
{
  link: String @external
}

type Query {
  rooms: [Room]
  room(id: ID!): Room
  slots: [Slot]
  _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 = Speaker

supergraph.yml:

subgraphs:
  speakers:
    routing_url: https://localhost:4001/
    schema:
      file: ./speakers.graphql
  schedule:
    routing_url: https://localhost:4002/
    schema:
      file: ./schedule.graphql

I will get the supergraph schema:

schema
  @core(feature: "https://specs.apollo.dev/core/v0.2"),
  @core(feature: "https://specs.apollo.dev/join/v0.1", for: EXECUTION)
{
  query: Query
}

directive @core(as: String, feature: String!, for: core__Purpose) repeatable on SCHEMA

directive @join__field(graph: join__Graph, provides: join__FieldSet, requires: join__FieldSet) on FIELD_DEFINITION

directive @join__graph(name: String!, url: String!) on ENUM_VALUE

directive @join__owner(graph: join__Graph!) on INTERFACE | OBJECT

directive @join__type(graph: join__Graph!, key: join__FieldSet) repeatable on INTERFACE | OBJECT

type Query {
  room(id: ID!): Room @join__field(graph: SCHEDULE)
  rooms: [Room] @join__field(graph: SCHEDULE)
  slots: [Slot] @join__field(graph: SCHEDULE)
  speaker(id: ID!): Speaker @join__field(graph: SPEAKERS)
  speakers: [Speaker] @join__field(graph: SPEAKERS)
}

type Room {
  capacity: Int
  id: ID!
  name: String
}

type Slot {
  roomId: ID!
  slotId: ID!
  talk: Talk
}

type Speaker
  @join__owner(graph: SPEAKERS)
  @join__type(graph: SPEAKERS, key: "link")
  @join__type(graph: SCHEDULE, key: "link")
{
  firstName: String @join__field(graph: SPEAKERS)
  lastName: String @join__field(graph: SPEAKERS)
  link: String @join__field(graph: SPEAKERS)
  uuid: ID! @join__field(graph: SPEAKERS)
}

type Talk {
  speakers: [Speaker]
  talkId: ID!
  talkType: String
  title: String
  trackId: String
}

enum core__Purpose {
  """
  `EXECUTION` features provide metadata necessary to for operation execution.
  """
  EXECUTION

  """
  `SECURITY` features provide metadata necessary to securely resolve fields.
  """
  SECURITY
}

scalar federation__FieldSet

scalar join__FieldSet

enum join__Graph {
  SCHEDULE @join__graph(name: "schedule" url: "https://localhost:4002/")
  SPEAKERS @join__graph(name: "speakers" url: "https://localhost:4001/")
}

scalar link__Import

enum link__Purpose {
  """
  `EXECUTION` features provide metadata necessary for operation execution.
  """
  EXECUTION

  """
  `SECURITY` features provide metadata necessary to securely resolve fields.
  """
  SECURITY
}

The router will fail to load this schema, with this error:

$ ./router -s supergraph.graphql -c router.config.yml --hot-reload
2022-04-12T12:57:22.276818Z  INFO apollo_router::executable: [email protected]
2022-04-12T12:57:22.322167Z  INFO apollo_router: starting Apollo Router
2022-04-12T12:57:22.413046Z ERROR apollo_router::state_machine: cannot create the router: couldn't build Router Service: query planning had errors: bridge errors: UNKNOWN: Type federation__FieldSet already exists in this schema
2022-04-12T12:57:22.413326Z  INFO apollo_router: stopped with error
2022-04-12T12:57:22.413389Z ERROR apollo_router::executable: could not create the HTTP pipeline: couldn't build Router Service: query planning had errors: bridge errors: UNKNOWN: Type federation__FieldSet already exists in this schema
could not create the HTTP pipeline: couldn't build Router Service: query planning had errors: bridge errors: UNKNOWN: Type federation__FieldSet already exists in this schema

If I remove the following definitions from the schema, it will load properly:

scalar federation__FieldSet

scalar link__Import

enum link__Purpose {
  """
  `EXECUTION` features provide metadata necessary for operation execution.
  """
  EXECUTION

  """
  `SECURITY` features provide metadata necessary to securely resolve fields.
  """
  SECURITY
}
@Geal Geal added the triage label Apr 12, 2022
@Geal
Copy link
Contributor Author

Geal commented Apr 12, 2022

I have not tested yet if this affects the gateway too

@Geal
Copy link
Contributor Author

Geal commented Apr 12, 2022

I'm using rover 0.5.1 and the router 0.1.0-preview4

@Geal
Copy link
Contributor Author

Geal commented Apr 14, 2022

closing this as it is handled in apollographql/rover#1089 and apollographql/rover#1090

@Geal Geal closed this as completed Apr 14, 2022
@BrynCooke BrynCooke added this to the v0.1.0-preview.5 milestone Apr 20, 2022
@BrynCooke BrynCooke removed the triage label Apr 20, 2022
@BrynCooke BrynCooke removed this from the v0.1.0-preview.5 milestone Apr 20, 2022
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