Skip to content

Maven GraphQL Schema Truncation

dermakov edited this page Jan 14, 2026 · 3 revisions

Table of contents

GraphQL schema truncation

The main weakness of the Kobby plugin at the moment is the difficulty of working with giant GraphQL schemas. The schema can contain hundreds of types. And to work with these types, the Kobby plugin generates a huge number of classes. To compile these classes, Kotlin requires a lot of RAM and time. But the developer does not always need all the types in the GraphQL schema. Often he works with a small subset of types.

To simplify code generation in such cases, the Kobby plugin provides a mechanism for truncating the GraphQL schema. The truncation occurs in two stages:

  • The first stage preserves all GraphQL fields that match the truncation query in the schema and removes all other fields.
  • The second stage removes all GraphQL types from the schema that are not accessible from the schema root (Query, Mutation or Subscription types).

To write a schema truncation query, we use the GSEL query language, which allows us to search for fields in various GraphQL types based on a set of conditions.

Schema truncation configuration

To configure GraphQL schema truncation, use the truncate section in the schema section:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation=
                 "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <build>
        <plugins>
            <plugin>
                <groupId>io.github.ermadmi78</groupId>
                <artifactId>kobby-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate-kotlin</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <schema>
                        <!-- GraphQL schema truncation configuration -->
                        <truncate>
                            <!-- Print detailed schema truncation report to console -->
                            <reportEnabled>false</reportEnabled>

                            <!-- Is Regex enabled in GraphQL schema truncation query -->
                            <!-- By default, a simplified Kobby Pattern is used. -->
                            <regexEnabled>false</regexEnabled>

                            <!-- Are patterns used in a GraphQL schema truncation query -->
                            <!-- case sensitive -->
                            <caseSensitive>true</caseSensitive>

                            <!-- A query used to truncate the GraphQL schema -->
                            <!-- before generating code -->
                            <queries>
                                <!-- Schema truncation query (GSEL) -->
                            </queries>
                        </truncate>
                    </schema>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

A simple truncation configuration looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation=
                 "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <build>
        <plugins>
            <plugin>
                <groupId>io.github.ermadmi78</groupId>
                <artifactId>kobby-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate-kotlin</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <schema>
                        <truncate>
                            <reportEnabled>true</reportEnabled>
                            <queries>
                                <query>
                                    <type>__any</type>
                                    <exclude>
                                        <dependency>Film|Actor</dependency>
                                        <subTypeDependency>Film|Actor</subTypeDependency>
                                    </exclude>
                                </query>
                            </queries>
                        </truncate>
                    </schema>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

With this configuration, we remove all fields of type Film and Actor from the GraphQL schema.

Schema Truncation Strategies

Let's look at some GraphQL schema truncation strategies with examples.

Exclude unused fields strategy

The most obvious strategy is to explicitly exclude unused fields from GraphQL types. But, surprisingly, this strategy is the most labor-intensive and least efficient. Let's look at the Cinema schema from the example project. This schema allows you to work with three types - Country, Film and Actor. Let's say I only need the Country from the schema. Let exclude fields that return Film and Actor.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation=
                 "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <build>
        <plugins>
            <plugin>
                <groupId>io.github.ermadmi78</groupId>
                <artifactId>kobby-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate-kotlin</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <schema>
                        <truncate>
                            <reportEnabled>true</reportEnabled>
                            <queries>
                                <query>
                                    <type>__query</type>
                                    <exclude>
                                        <field>film|films|actor|actors</field>
                                    </exclude>
                                </query>
                                <query>
                                    <type>__mutation</type>
                                    <exclude>
                                        <field>createFilm|createActor|updateBirthday</field>
                                    </exclude>
                                </query>
                                <query>
                                    <type>__subscription</type>
                                    <exclude>
                                        <field>filmCreated|actorCreated</field>
                                    </exclude>
                                </query>
                                <query>
                                    <type>Country</type>
                                    <exclude>
                                        <field>film|films|actor|actors</field>
                                    </exclude>
                                </query>
                            </queries>
                        </truncate>
                    </schema>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

We build the project (mvn clean compile) and see in the report that the fields we selected were deleted, but the Film and Actor types were not deleted:

[kobby] GraphQL schema truncation enabled! (Kobby pattern case sensitive)
[kobby] Source schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

[kobby] Detailed truncation report ****************************************************

Excluded inputs:
  FilmInput
  ActorInput
  TagInput

Excluded object fields:

  Query:
    film
    films
    actor
    actors

  Mutation:
    createFilm
    createActor
    updateBirthday

  Subscription:
    filmCreated
    actorCreated

  Country:
    film
    films
    actor
    actors

[kobby] *******************************************************************************

[kobby] GraphQL schema truncation completed. 3 GraphQL types excluded (3 inputs).
[kobby] Truncated schema weight: 12 (7 objects, 2 interfaces, 1 unions, 2 enums).

Why did this happen? The thing is that the types we are deleting are accessible not only through direct dependencies, but also through hierarchical ones. Both Film and Actor types implement Taggable interface and are members of Native union. And there are fields in the schema that return these abstract types. Thus, Film and Actor types are implicitly accessible from the schema root. Let's exclude such fields too:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation=
                 "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <build>
        <plugins>
            <plugin>
                <groupId>io.github.ermadmi78</groupId>
                <artifactId>kobby-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate-kotlin</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <schema>
                        <truncate>
                            <reportEnabled>true</reportEnabled>
                            <queries>
                                <query>
                                    <type>__query</type>
                                    <exclude>
                                        <field>film|films|actor|actors|taggable</field>
                                    </exclude>
                                </query>
                                <query>
                                    <type>__mutation</type>
                                    <exclude>
                                        <field>createFilm|createActor|updateBirthday</field>
                                    </exclude>
                                </query>
                                <query>
                                    <type>__subscription</type>
                                    <exclude>
                                        <field>filmCreated|actorCreated</field>
                                    </exclude>
                                </query>
                                <query>
                                    <type>Country</type>
                                    <exclude>
                                        <field>film|films|actor|actors|taggable|native</field>
                                    </exclude>
                                </query>
                            </queries>
                        </truncate>
                    </schema>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

We rebuild the project and see in the final report that the Film and Actor types have been removed:

[kobby] GraphQL schema truncation enabled! (Kobby pattern case sensitive)
[kobby] Source schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

[kobby] Detailed truncation report ****************************************************

Excluded scalars:
    Date

Excluded objects:
  Film
  Actor
  Tag

Excluded interfaces:
  Taggable

Excluded unions:
  Native

Excluded enums:
  Genre
  Gender

Excluded inputs:
  FilmInput
  ActorInput
  TagInput

Excluded object fields:

  Query:
    film
    films
    actor
    actors
    taggable

  Mutation:
    createFilm
    createActor
    updateBirthday

  Subscription:
    filmCreated
    actorCreated

  Country:
    film
    films
    actor
    actors
    taggable
    native

[kobby] *******************************************************************************

Exclude unused types strategy

To remove just two types, we had to write complex and cumbersome queries listing all the fields through which these types are accessible. Is it possible to simply remove Film and Actor dependencies using GSEL? Of course we can! Let's do it:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation=
                 "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <build>
        <plugins>
            <plugin>
                <groupId>io.github.ermadmi78</groupId>
                <artifactId>kobby-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate-kotlin</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <schema>
                        <truncate>
                            <reportEnabled>true</reportEnabled>
                            <queries>
                                <query>
                                    <type>__any</type>
                                    <exclude>
                                        <dependency>Film|Actor</dependency>
                                        <subTypeDependency>Film|Actor</subTypeDependency>
                                    </exclude>
                                </query>
                            </queries>
                        </truncate>
                    </schema>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
  • The <dependency>Film|Actor</dependency> condition matches fields that return types that match the Film|Actor pattern.
  • The <subTypeDependency>Film|Actor</subTypeDependency> condition matches fields where one of the subtypes matches the Film|Actor pattern.

Detailed truncation report:

[kobby] GraphQL schema truncation enabled! (Kobby pattern case sensitive)
[kobby] Source schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

[kobby] Detailed truncation report ****************************************************

Excluded scalars:
    Date

Excluded objects:
  Film
  Actor
  Tag

Excluded interfaces:
  Taggable

Excluded unions:
  Native

Excluded enums:
  Genre
  Gender

Excluded inputs:
  FilmInput
  ActorInput
  TagInput

Excluded object fields:

  Query:
    film
    films
    actor
    actors
    taggable

  Mutation:
    createFilm
    createActor
    updateBirthday

  Subscription:
    filmCreated
    actorCreated

  Country:
    film
    films
    actor
    actors
    taggable
    native

[kobby] *******************************************************************************

[kobby] GraphQL schema truncation completed.
[kobby] 10 GraphQL types excluded (3 objects, 1 interfaces, 1 unions, 2 enums, 3 inputs).
[kobby] Truncated schema weight: 5 (4 objects, 1 interfaces).

Include used types strategy

Okay, the strategy of excluding unused types looks good, but our example schema is too small. It consists of only 3 objects. But what happens if we try to truncate a really large GraphQL schema? Let's take a look at the official GitHub GraphQL schema. It consists of 777 objects. Let's assume that we only need to work with 3 objects from this schema - User, Team and Organization. Should we write a GSEL query where we list the remaining 774 objects that we need to exclude? Of course not! Let's work only with those objects that we need to include in the resulting schema:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation=
                 "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <build>
        <plugins>
            <plugin>
                <groupId>io.github.ermadmi78</groupId>
                <artifactId>kobby-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate-kotlin</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <schema>
                        <truncate>
                            <queries>
                                <query>
                                    <type>__any</type>
                                    <include>
                                        <dependency>
                                            __anyScalar|__anyEnum|User|Team|Organization
                                        </dependency>
                                    </include>
                                </query>
                                <query>
                                    <type>__mutation</type>
                                    <include>
                                        <argumentDependency>
                                            *User*Input*|*Team*Input*|*Organization*Input*
                                        </argumentDependency>
                                    </include>
                                </query>
                            </queries>
                        </truncate>
                    </schema>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
  • The <dependency>__anyScalar|__anyEnum|User|Team|Organization</dependency> condition matches fields of scalar and enum types, as well as the User, Team, and Organization types.
  • The <argumentDependency>*User*Input*|*Team*Input*|*Organization*Input*</argumentDependency> condition matches fields where one of the argument types matches the *User*Input* pattern.

We use the argumentDependency condition to preserve fields in the Mutation, which takes input objects for User, Team, and Organization as arguments.

Truncation result:

[kobby] GraphQL schema truncation enabled! (Kobby pattern case sensitive)
[kobby] Source schema weight: 1313 (777 objects, 45 interfaces, 37 unions, 189 enums, 265 inputs).
[kobby] GraphQL schema truncation completed.
[kobby] 1219 GraphQL types excluded (748 objects, 30 interfaces, 21 unions, 178 enums, 242 inputs).
[kobby] Truncated schema weight: 94 (29 objects, 15 interfaces, 16 unions, 11 enums, 23 inputs).

Clone this wiki locally