GraphQL clean schema generation

I’m currently setting up an Apollo federation that federates Dgraph.
One of the first step is to fetch the Dgraph’s GraphQL schema to serve as federated schema.
To dump the Dgraph Schema I’m using the NPM graphql package and more precisely the printSchema method.

It does the job and I’m able to fetch the schema, write it in a file and serve that file from Apollo.
The problem is that the Schema is full of dead code and Dgraph specific directives.

Dead code

Thanks to the @generate directive it is possible to avoid the generation of some operations in the served GraphQL schema. Unfortunately, it does not avoid the generation of the inputs:
Disabling the mutation generation of a type, Dgraph still generates the input needed for the mutation, even if it won’t be used anywhere in the Schema.
I need therefore to remove manually all the inputs to reduce the size of the served schema (my Dgraph schema is about 1000 line length, which generates a ~10k line GraphQL schema and ~2-3k lines are just dead input types)

Dgraph specific directives

Fetching the schema, I get also the directives used by Dgraph to actually define the schema (@generate, @id, @lambda, …) and I have once again to manually clean it up because the Federation requires all the services to implement the same set of directives.


Since GraphQL schema is subject to changes and it is likely to fetch a new schema periodically from Dgraph to serve it thought an Apollo server, is there a better way to fetch a ready-to-apollo schema? Maybe using the /admin endpoint?
And also, is there any plan to improve the auto generation of the GraphQL schema pruning all useless input and *Ref types?

Is there any specific reason that you want to remove dead code. Does Apollo Federation enforce any size limit on schema size ? We can look into removing dead code generation if there is a valid use case.

This is not true. We do have checks inside code which don’t generate unwanted Payload and Input. Can you share a small schema with example where this is happening.

Example where generate directive prevents writing of Input and Payload types:
The input schema does not generate AddPersonInput and AddPersonPayload in output schema as it has been disabled using generate directive.

The generated GraphQL schema can be queried using the following query on /admin endpoint.

query{
  getGQLSchema{
    generatedSchema
  }
}

@rajas Thank you for the suggestion, using the Dgraph admin endpoint i was able to pull a clean schema.
It seems that graphql-js/utils generates some garbage (all input **Ref types for example) and fetches the directives as well.

Querying /admin directly is possible to fetch a ready-to-apollo schema

Regarding the first answer, no there is not an Apollo costraint which limits the schema size, but since The apolllo Server has to add some directives (@cost, @ratelimits) to protect dgraph, i’m still thinking of the best way to handle and keep synced this 2 schemas (one coming from Dgraph, and the second served by Apollo)… And having thousand of lines of useless inputs was not helping at all.

EDIT 1
Hitting the Admin endpoint, Dgraph returns the schema still tagged with the Dgraph specific directives (@generate, @search, …) making it not usable in apollo without manual work;

Yes, the generated schema will contain Dgraph directives like @generate and @search .

Why do you need to remove Dgraph directives like @search and @generate. I do understand that they are Dgraph specific and may not add value while using the schema with other tools. But, my understanding is that they are harmless and don’t need to be removed while using with other tools like Apollo Federation.

We can look into having an endpoint with removed Dgraph specific directives if there is a valid use case for it.

Also linking a somewhat related post for reference.

The problem is that Apollo Federation requires all federated services to implement the same set of directives.

This generates quite a lot of manual work and a non-maintainable environment for Apollo Federation since each federated service has to implement - or at least declare- the digraph directives in their own schema.

Secondly, it seems that Apollo Federation itself, which seems to not be production ready, doesn’t like directives declaration using non-scalar types as parameters (like @custom which uses CustomHTTP type) and simply rejects the schema.
^ This issue is not Dgraph fault, but still, it is blocking

Can you compare with the steps in the recap at Dgraph Directives reference (for other tools)? - #4 by trka?

What that returns for me is spotless - no directives at all, only types and fields from my model. It’s possible that we have a version mismatch or something, of course, but it’s worth a double-check

1 Like

@Luscha, we have recently added support for Apollo Federation in master branch. This will be available in our next release, 21.03 scheduled for March.

The schema with (@custom and @auth removed) can be obtained by running the following the query,

query {
    _service{
        sdl
    }
}

We are in the process of adding documentation for Apollo Federation Support.

You may find example in the TestApolloServiceResolver test of the following code commit, feat(GraphQL): Extend Support For Apollo Federation (#7275) · dgraph-io/dgraph@1e6af7e · GitHub .

1 Like