apollographql / rover

The CLI for Apollo GraphOS
https://rover.apollo.dev
Other
408 stars 85 forks source link

Link to the federation specifcation v2 is not detected by rover #1115

Closed split closed 2 years ago

split commented 2 years ago

Description

Federation v2 link is not detected correctly when attempting to publish printSubgraphSchema generated schema. Other errors rover is reporting are most likely more printSubgraphSchema related.

Steps to reproduce

Attempted to publish following subgraph using rover subgraph publish:

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

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 @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 Greeting @key(fields: "name") {
  message: String! @shareable
  name: String!
}

type Query {
  hello(name: String!): Greeting!
  _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 federation__FieldSet

This schema was generated using printSubgraphSchema (subgraph version 2.0.1) with following code:

import { buildSubgraphSchema, printSubgraphSchema } from '@apollo/subgraph'
import { gql } from '@apollo/core-schema'

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

  type Greeting @key(fields: "name") {
    message: String! @shareable
    name: String!
  }

  type Query {
    hello(name: String!): Greeting!
  }
`

const schema = buildSubgraphSchema({ typeDefs })

console.log(printSubgraphSchema(schema))

Expected result

Expected Rover to detect that schema is defined to be Federation v2

Actual result

$ node index.js | rover subgraph publish foobar@testing --name greeting --schema -  --routing-url https://localhost:3001/graphql 
Publishing SDL to foobar@testing (subgraph: greeting) using credentials from the default profile.
The 'greeting' subgraph for the 'foobar@testing' graph was updated
The gateway for the 'foobar@testing' graph was NOT updated with a new schema
Monitor your schema delivery progresson on studio: https://studio.apollographql.com/graph/foobar/launches/XXX
WARN: The following build errors occurred:
TYPE_DEFINITION_INVALID: Invalid definition of type Purpose: expected values [EXECUTION,SECURITY] but found [].
TYPE_DEFINITION_INVALID: Invalid definition of type Purpose: expected values [EXECUTION,SECURITY] but found [].
UNKNOWN: Unknown directive "@shareable". If you meant the "@shareable" federation 2 directive, note that this schema is a federation 1 schema. To be a federation 2 schema, it needs to @link to the federation specifcation v2.

Environment

Rover Info:
Version: 0.5.4
Install Location: /Users/hela/.nvm/versions/node/v16.11.1/lib/node_modules/@apollo/rover/node_modules/binary-install/node_modules/.bin/rover
OS: Mac OS 12.3.1 [64-bit]
Shell: /bin/zsh
EverlastingBugstopper commented 2 years ago

Hey @split, thanks so much for the report.

I believe that what you're encountering here is expected behavior, though likely not the most intuitive.

You'll have to opt in to Federation 2 in Apollo Studio in order for this to work. rover supergraph compose has a bit looser version selection rules that can allow @link directives to make the default composition function Federation 2.

However, managed federation requires an explicit opt-in. This is because we want to prevent a situation where somebody accidentally publishes a single subgraph with an @link directive without meaning to turn on Federation 2 for the entire supergraph, possibly breaking gateways that do not support Federation 2.

You'll want to follow the docs here to explicitly opt-in to Federation 2, then this command should work as expected.

split commented 2 years ago

@EverlastingBugstopper Thanks for your reply and I should have mentioned I have opt-in to Federation 2 in Apollo Studio and publishing works if I use schema fetched via rover introspection

benweatherman commented 2 years ago

howdy @split! We've confirmed this is an issue in the underlying printSubgraphSchema code as you mentioned and are working on fixing that in https://github.com/apollographql/federation/issues/1824.

While we work through that, would publishing your subgraph directly work for your usecase? Calling rover subgraph publish with this subgraph should succeed:

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

type Greeting @key(fields: "name") {
  message: String! @shareable
  name: String!
}

type Query {
  hello(name: String!): Greeting!
}

If that's not an option, would you mind telling me more about what you're going to be doing with the subgraph schema?