Remove field from schema

Hi! Is there a way to remove a field from the schema based on an environment variable? I’m working with a whitelabel GraphQL API and need to exclude a specific field during application startup. Would that be possible?

I have two clients and one server for each one

It’s definitely possible to conditionally exclude fields using a custom directive, but the implementation differs slightly depending on whether you’re using a monolithic GraphQL server or an GraphQL Federation architecture. Since you didn’t specify your setup, I’ll cover both cases.

Monolithic GraphQL Server

In a monolithic setup, you can create a custom directive (e.g., @exclude) to remove fields based on an environment variable. Use @graphql-tools/schema to transform the schema and return null for fields that should be excluded.

directive @exclude(for: Client!) on FIELD_DEFINITION

enum Client {
  CLIENT_1
  CLIENT_2
}

type Foo {
  bar: String!
  baz: String! @exclude(for: CLIENT_1)
}

type Query {
  foo: Foo!
}

GraphQL Federation

In a Federation setup, the process is similar, but there’s a catch: the Router uses the _service { sdl } query to compose the supergraph schema, not the __schema introspection. If you apply a directive transformation using buildSubgraphSchema, the transformed schema (with fields removed) is reflected in the subgraph’s introspection (__schema), but the schema sent to the router (_service { sdl }) won’t include these changes.

Additionally, makeExecutableSchema doesn’t recognize Federation directives like @link, @key, etc., which causes errors. To fix this, you need to:

  1. Explicitly declare Federation directives in your schema.
  2. Apply the directive transformation before passing the schema to buildSubgraphSchema.

I’m not sure, but maybe you can solve this problem in Federation using @tag directive and Managed Federation

If you are using Federation and have one server for each client, consequently, one router for each, you could use the @inaccessible directive, it’s much easier than the previous one. But if you need to exclude a specific field based on environment variable during the startup, this directive will not help you.

EDIT: I’m not sure, but maybe you can use the @exclude directive to add the @inaccessible directive to the field if condition is true instead of return null

1 Like

That answer fit perfectly into what I needed. Really appreciate the clarity and precision. Thank you!