ardatan/graphql-import

Import all graphql files from a directory

stephenh opened this issue · 9 comments

I'm looking at graphqlgen that defers to importSchema to load its schemas.

Right now we just have *.graphql files in a data/schemas directory without any of the # import * from ... comments.

What I'd like to do is just importSchema('data/schemas') and have it realize its a directory and just pull in all the .graphql files recursively and combine them together.

Does that seem reasonable?

I'm on the same situation

Hi @stephenh and @didaquis !
In 1.0.0 beta release, we introduced a lot of changes including glob expressions support;
Could you install graphql-import@beta to try new changes? Don't forget to modify your code regarding to the migration notes in README.
https://github.com/ardatan/graphql-import#updating-from-07x

So you can load your files like below;

const loadedSchema = await importSchema(join(__dirname, './data/schemas/**/*.graphql'));

@ardatan awesome, thanks!

I just tried the beta and got this type error:

Error:(11, 5) TS2322: Type 'string | GraphQLSchema | DocumentNode' is not assignable to type 'string | string[] | DocumentNode | DocumentNode[] | undefined'.
  Type 'GraphQLSchema' is not assignable to type 'string | string[] | DocumentNode | DocumentNode[] | undefined'.
    Type 'GraphQLSchema' is missing the following properties from type 'DocumentNode[]': length, pop, push, concat, and 28 more.

When doing:

export async function createServer(context: AppContext): Promise<ApolloServer> {
  const typeDefs = await importSchema(join(__dirname, "schema/**/*.graphql"));
  return new ApolloServer({
    typeDefs,
    resolvers,
...

I.e. it looks like importSchema has a type called GraphQLSchema in its union result that apollo server (I'm using apollo-server-express) doesn't like/expect in its union type.

(I'm on apollo-server-express 2.9.15 and graphql 14.5.8, both of which are latest afaiu.)

@stephenh Could you try this version?
graphql-import@1.0.0-9642d32.0

Yep, that is working now.

Personally I had to turn off forceGraphQLImport b/c historically we've not been using the import statement, and instead assuming all of the files shared a global namespace.

Without forceGraphQLImport: false, somehow types were getting dropped, i.e. around this bit of code:

                if (options.forceGraphQLImport || (!options.skipGraphQLImport && /^\#.*import /i.test(resultSource.rawSDL.trimLeft()))) {
                    await processImportSyntax(resultSource, options);
                }
                if (resultSource.document.definitions && resultSource.document.definitions.length > 0) {
                    foundValid.push(resultSource);
                }

When processImportSyntax returned, resultSource would be a file for, say, fooEntity.graphql, but resultSource would suddenly only have definitions for some other .graphql file, and the fooEntity types would be dropped / not present in the resulting typeDefs string.

I'm not sure if this is on purpose, like the only definitions that seemed to not get dropped where from a fully self-contained file (say bar.graphql), and processImportSyntax seemed to leak bar.graphql's types into literally every other *.graphql file's resultSource.

I'm not an expert on the import syntax functionality or implementation, but this really seems pretty odd, and like a bug? Not sure, but disabling it:

  const typeDefs = await importSchema(join(__dirname, "../schema/*.graphql"), {
    forceGraphQLImport: false,
    skipGraphQLImport: true,
  });

Returned it to the behavior I wanted, of "just glob everything together sans imports".

@stephenh GraphQL Import's behavior is to drop unused stuff because it is not a regular schema loader. If you don't use import statement, using GraphQL Import would be overkill.
You can check the better alternatives;
https://github.com/Urigo/merge-graphql-schemas#import-everything-from-a-specified-folder
https://github.com/ardatan/graphql-toolkit#file-loading-for-both-schema-and-resolvers

@ardatan ah great, thanks for the links!

@ardatan maybe add an FAQ/readme section on the graphql-import page with links to those? When I was first setting this up, googling for "graphql import" turns out a lot of things :-), and I picked graphql-import as the "most official sounding / looking" library and assumed it would/should support most of the common use cases. What you describe now, that this is very specifically for "if you want to use the import syntax" makes sense, but just wasn't super clear to me as a new user, nor what I should be using instead. Thanks again!

Available in 1.0.0!