Federated _service query does not honour schema-altering directives

I’m constructing a subgraph schema using custom directives using the code pattern:

// Create subraph schema
const schema = buildSubgraphSchema([{
    typeDefs,
    resolvers
  }]);

  // Fold in custom directives
  SchemaDirectiveVisitor.visitSchemaDirectives(schema, schemaDirectives);

  // Run server
  const server = new ApolloServer({ schema, .. });

My subgraph schema uses a custom directive to “expand” enums on apollo startup, but querying for _service { sdl } does not take into account their action.

For example, the following gql

enum Foo @dynamicEnum(...) {
    PLACEHOLDER @description(value: "Placeholder")
}

will use the @dynamicEnum directive on startup to replace the PLACEHOLDER value with actual values, so that executing the following GQL query:

  __type(name: "Foo") {
    name
    enumValues(includeDeprecated:true) {
      name
      description
      isDeprecated
      deprecationReason
    }
  }
}

Returns the response

{
  "data": {
    "__type": {
      "name": "Foo",
      "enumValues": [
        {
          "name": "LIVE_VALUE_A",
          "description": "Live value A",
          "isDeprecated": false,
          "deprecationReason": null
        },
        {
          "name": "LIVE_VALUE_B",
          "description": "Live value B",
          "isDeprecated": false,
          "deprecationReason": null
        }
      ]
    }
  }
}

However if I include the subgraph in my federated gateway then the same query issued against my API gateway gives me:

{
  "data": {
    "__type": {
      "name": "FOO",
      "enumValues": [
        {
          "name": "PLACEHOLDER",
          "description": "Placeholder",
          "isDeprecated": false,
          "deprecationReason": null
        }
      ]
    }
  }
}

which I believe is because rover supergraph compose does not resolve the directive, which in turn is because the _service { sdl } does not resolve it.

Is this is a known issue/limitation of the implementation of the _service Query?

I think the issue is that the buildSubgraphSchema method provided by the @apollo/subgraph library doesn’t allow for the caller to pass in some directive functions that can be visited after the schema is built but before printSubgraphSchema is called.

What I ended up doing to workaround this for now is to recalculate the SDL after using a SchemaDirectiveVisitor and then plugging that into the _service resolver e.g.

// Build subgraph schema 
const schema = buildSubgraphSchema([{ typeDefs, resolvers }]); 

// Allow the directives to visit the schema 
SchemaDirectiveVisitor.visitSchemaDirectives(schema, mySchemaDirectives); 

// Recalculate the SDL now the directives have done their work 
const sdl = (0, printSubgraphSchema)(schema); 

// Plug in the revised SDL to the _service query resolver 
schema.getQueryType().getFields()['_service'].resolve = () => ({ sdl });

I’ve raised an issue for this.