printSchema with directives for uploading to Apollo Studio managed federation

I’m working on a federated subgraph and trying to convert a GraphQLSchema into a schema.graphql for uploading to Apollo Studio with rover (using apollo managed federation). I’ve tried using printSchema or printSubgraphSchema, but both strip any directives like @key() and also any extends. This causes issues when trying to extend an entity from another subgraph.

I need to print from a GraphQLSchema because I’m using a code-first schema that is split across many files.

Is there a way to print the schema and include the directives or is there another approach to uploading my schema to Apollo Studio with the directives included?

Thanks fo any help in this!

I’m doing something like this:

const unfederatedSchema = makeSchema(...);
const schema = transformSchemaFederation(unfederatedSchema, ...)

const sdl = printSubgraphSchema(schema);
const path = resolve(__dirname, './generated/schema.graphql');
writeFileSync(path, sdl);

I’m expecting this:

extend type Space @key(field: 'id') {
  id: ID! @external
}

What I actually get:

type Space {
  id: ID!
}

Hey @Curbol, printSubgraphSchema will print all of those correctly, provided the metadata is captured on the schema object correctly.

I’m not sure what transformSchemaFederation does here, but I can see that buildSubgraphSchema is missing from this equation (which captures the @key and other federation directives correctly on the schema object for printing). It’s likely that your code-first approach isn’t going to play nice with this though - buildSubgraphSchema currently only supports modules (SDL + resolvers). If you can programatically get the correct subgraph SDL somehow you should be able to make this work.

The buildSubgraphSchema fn is exported by the @apollo/subgraph package.

2 Likes

Sorry to necropost, but shouldn’t this be documented in the instructions for managed federation? If introspection is not an option for whatever reason you’ll need to generate a .gql file, and you’re much more likely to find out about printSchema than printSubgraphSchema. I only got here because I guessed the function name.

@Omar_Benmegdoul - buildSubgraphSchema provides a form of introspection for this reason. If you don’t have a file to provide rover, you can provide an endpoint instead. buildSubgraphSchema makes this query possible: { _service { sdl } }. The result of this query can be pushed to studio (all done automatically with rover) or can be used by the gateway’s IntrospectAndCompose supergraph manager for local composition.

Does that answer your question?

At the point in our pipeline where we want to publish the endpoint is not accessible, hence “if introspection is not an option”. Instead we have a simple script for generating the file before that step of the pipeline.

I assumed this was the reason why the two options are given in the managed federation documentation. In any case, seems like if you provide an alternative to introspection, that alternative shouldn’t rely on introspection. Maybe I just don’t understand what “a form of introspection” means.

@Omar_Benmegdoul I was having a similar issue where I wanted to write my schema to a file and not use the introspection, and i found that the @graphql-tools/utils npm package exports a function called printSchemaWithDirectives and that combined with buildSubgraphSchema from @apollo/subgraph, i was able to print to a file the same output as the result of rover introspect.

Here is a code example :

import { buildSubgraphSchema } from '@apollo/subgraph';
import { printSchemaWithDirectives } from '@graphql-tools/utils';
import * as fs from 'fs';
import { resolvers, schema } from './src/api/schema/schema';

fs.writeFileSync(
  './schema.graphql',
  printSchemaWithDirectives(
    buildSubgraphSchema({
      typeDefs: schema,
      resolvers
    })
  )
);

Yeah we did roughly the same thing in our pipeline, thanks :slight_smile: