Skip to content

Maven GraphQL Schema Analysis Tool

dermakov edited this page Jan 14, 2026 · 3 revisions

Table of contents

GraphQL schema analysis tool

Sometimes choosing an effective GraphQL schema truncation strategy is a difficult task. And the Kobby schema analysis tool can help us solve it.

To run the analysis tool, use the schema-analyze mojo:

mvn io.github.ermadmi78:kobby-maven-plugin:schema-analyze

By default, the analysis tool prints a report for the root of the GraphQL schema - the Query, Mutation, and Subscription types:

[kobby] GraphQL schema ready to analyze! (Kobby pattern case sensitive)
[kobby] Analyzed schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

Query (weight: 10)
  country: Country (weight: 9)
  countries: Country (weight: 9)
  film: Film (weight: 9)
  films: Film (weight: 9)
  actor: Actor (weight: 9)
  actors: Actor (weight: 9)
  taggable: Taggable (weight: 9)
Mutation (weight: 13)
  createCountry: Country (weight: 9)
  createFilm: Film (weight: 11)
  createActor: Actor (weight: 11)
  updateBirthday: Actor (weight: 9)
  associate: Boolean
  tagFilm: Boolean
  tagActor: Boolean
Subscription (weight: 10)
  countryCreated: Country (weight: 9)
  filmCreated: Film (weight: 9)
  actorCreated: Actor (weight: 9)

Analysis tool configuration

To configure analysis tool, use the analyze 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>
                        <!-- Configuration of schema-analyze mojo -->
                        <!-- to print a report to the console -->
                        <!-- with all GraphQL types and fields that match the query. -->
                        <analyze>
                            <!-- true - use a truncated GraphQL schema for analysis. -->
                            <!-- false - use the original GraphQL schema for analysis. -->
                            <truncatedSchema>true</truncatedSchema>

                            <!-- GraphQL schema analysis depth. -->
                            <!-- Use -1 to analyse a schema with unlimited depth. -->
                            <depth>1</depth>

                            <!-- GraphQL schema analysis report length limit. -->
                            <!-- Use -1 to print a report with unlimited length. -->
                            <reportLengthLimit>10000</reportLengthLimit>

                            <!-- The minimum weight of a GraphQL type -->
                            <!-- that should be printed in the report. -->
                            <printMinWeight>2</printMinWeight>

                            <!-- Print "override sign" (`^`) in report -->
                            <!-- for overridden GraphQL type fields. -->
                            <printOverride>false</printOverride>

                            <!-- Print GraphQL field argument types in a report. -->
                            <printArgumentTypes>false</printArgumentTypes>

                            <!-- Print GraphQL field supertypes in report -->
                            <!-- (`<-` followed by a list of supertypes). -->
                            <printSuperTypes>false</printSuperTypes>

                            <!-- Print GraphQL field subtypes in report -->
                            <!-- (`->` followed by a list of subtypes). -->
                            <printSubTypes>false</printSubTypes>

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

                            <!-- Are patterns used in a GraphQL schema analysis query -->
                            <!-- case sensitive. -->
                            <caseSensitive>false</caseSensitive>

                            <!-- A query used to analyze the GraphQL schema. -->
                            <!-- The schema-analyze mojo prints a report to the console -->
                            <!-- with the GraphQL types and fields matches to the given query. -->
                            <queries>
                                <!-- Schema analysis query (GSEL) -->
                            </queries>
                        </analyze>
                    </schema>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

You can select the GraphQL types and fields to analyze using a GSEL query (see queries section) and customize how the report is displayed when printed using the printXXX properties.

Examples of use

Let's look at some examples of using the schema analysis tool to select a truncation strategy. In our examples, we will analyze the Cinema schema from the kobby-maven-example project.

Finding direct dependencies

Let's find all the fields of type Actor in our 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>
                        <analyze>
                            <queries>
                                <query>
                                    <type>__any</type>
                                    <include>
                                        <dependency>Actor</dependency>
                                    </include>
                                </query>
                            </queries>
                        </analyze>
                    </schema>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Analysis report:

[kobby] GraphQL schema ready to analyze! (Kobby pattern case sensitive)
[kobby] Analyzed schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

Query (weight: 10)
  actor: Actor (weight: 9)
  actors: Actor (weight: 9)
Mutation (weight: 13)
  createActor: Actor (weight: 11)
  updateBirthday: Actor (weight: 9)
Subscription (weight: 10)
  actorCreated: Actor (weight: 9)
Country (weight: 9)
  actor: Actor (weight: 9)
  actors: Actor (weight: 9)
Film (weight: 9)
  actors: Actor (weight: 9)

[kobby] Analyzed schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

Finding transitive dependencies

Okay, but how is the Actor type accessible from the root of the GraphQL schema? This is important to know in order to choose an adequate schema truncation strategy. Let's find all transitive dependencies of the Actor type from the root of the GraphQL 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>
                        <analyze>
                            <queries>
                                <query>
                                    <type>__root</type>
                                    <include>
                                        <transitiveDependency>Actor</transitiveDependency>
                                    </include>
                                </query>
                            </queries>
                        </analyze>
                    </schema>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Analysis report:

[kobby] GraphQL schema ready to analyze! (Kobby pattern case sensitive)
[kobby] Analyzed schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

Query (weight: 10)
  country: Country (weight: 9)
  countries: Country (weight: 9)
  film: Film (weight: 9)
  films: Film (weight: 9)
  actor: Actor (weight: 9)
  actors: Actor (weight: 9)
  taggable: Taggable (weight: 9)
Mutation (weight: 13)
  createCountry: Country (weight: 9)
  createFilm: Film (weight: 11)
  createActor: Actor (weight: 11)
  updateBirthday: Actor (weight: 9)
Subscription (weight: 10)
  countryCreated: Country (weight: 9)
  filmCreated: Film (weight: 9)
  actorCreated: Actor (weight: 9)

[kobby] Analyzed schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

Selecting the report depth

As we can see, the Actor type is accessible from almost all fields of the schema root. But how can we find out more details about the access paths to the Actor type from the schema root? Let's increase the report depth. By default, the depth is 1. Let's make it 2:

<?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>
                        <analyze>
                            <depth>2</depth>
                            <queries>
                                <query>
                                    <type>__root</type>
                                    <include>
                                        <transitiveDependency>Actor</transitiveDependency>
                                    </include>
                                </query>
                            </queries>
                        </analyze>
                    </schema>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Analysis report:

[kobby] GraphQL schema ready to analyze! (Kobby pattern case sensitive)
[kobby] Analyzed schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

Query (weight: 10)
  country: Country (weight: 9)
    film: Film (weight: 9)
    films: Film (weight: 9)
    actor: Actor (weight: 9)
    actors: Actor (weight: 9)
    taggable: Taggable (weight: 9)
    native: Native (weight: 9)
  countries: Country (weight: 9)
    film: Film (weight: 9)
    films: Film (weight: 9)
    actor: Actor (weight: 9)
    actors: Actor (weight: 9)
    taggable: Taggable (weight: 9)
    native: Native (weight: 9)
  film: Film (weight: 9)
    country: Country (weight: 9)
    actors: Actor (weight: 9)
  films: Film (weight: 9)
    country: Country (weight: 9)
    actors: Actor (weight: 9)
  actor: Actor (weight: 9)
    country: Country (weight: 9)
    films: Film (weight: 9)
  actors: Actor (weight: 9)
    country: Country (weight: 9)
    films: Film (weight: 9)
  taggable: Taggable (weight: 9)
    Film (weight: 9)
      country: Country (weight: 9)
      actors: Actor (weight: 9)
    Actor (weight: 9)
      country: Country (weight: 9)
      films: Film (weight: 9)
Mutation (weight: 13)
  createCountry: Country (weight: 9)
    film: Film (weight: 9)
    films: Film (weight: 9)
    actor: Actor (weight: 9)
    actors: Actor (weight: 9)
    taggable: Taggable (weight: 9)
    native: Native (weight: 9)
  createFilm: Film (weight: 11)
    country: Country (weight: 9)
    actors: Actor (weight: 9)
  createActor: Actor (weight: 11)
    country: Country (weight: 9)
    films: Film (weight: 9)
  updateBirthday: Actor (weight: 9)
    country: Country (weight: 9)
    films: Film (weight: 9)
Subscription (weight: 10)
  countryCreated: Country (weight: 9)
    film: Film (weight: 9)
    films: Film (weight: 9)
    actor: Actor (weight: 9)
    actors: Actor (weight: 9)
    taggable: Taggable (weight: 9)
    native: Native (weight: 9)
  filmCreated: Film (weight: 9)
    country: Country (weight: 9)
    actors: Actor (weight: 9)
  actorCreated: Actor (weight: 9)
    country: Country (weight: 9)
    films: Film (weight: 9)

[kobby] Analyzed schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

To output a report with infinite depth, set the report depth to -1. This way, you will see the full dependency paths in the report (except for infinite dependency loops - they are artificially broken). But the report can be very large.

Estimating the weight of GraphQL type fields

Okay, so what about the weight in the report? What is it? It's the number of GraphQL types (excluding scalars) that are reachable for a query on a field that returns the given type. Using weights, we can estimate which fields contribute the most to the number of data types generated by the Kobby plugin. Let's find fields with a given weight range:

<?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>
                        <analyze>
                            <queries>
                                <query>
                                    <type>__root</type>
                                    <include>
                                        <minWeight>10</minWeight>
                                        <maxWeight>20</maxWeight>
                                    </include>
                                </query>
                            </queries>
                        </analyze>
                    </schema>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Analysis report:

[kobby] GraphQL schema ready to analyze! (Kobby pattern case sensitive)
[kobby] Analyzed schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

Mutation (weight: 13)
  createFilm: Film (weight: 11)
  createActor: Actor (weight: 11)

[kobby] Analyzed schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

Customizing the report appearance

Okay. What other details can we see in the report? Let's enable all available options:

<?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>
                        <analyze>
                            <truncatedSchema>true</truncatedSchema>
                            <depth>1</depth>
                            <reportLengthLimit>10000</reportLengthLimit>
                            <printMinWeight>0</printMinWeight>
                            <printOverride>true</printOverride>
                            <printArgumentTypes>true</printArgumentTypes>
                            <printSuperTypes>true</printSuperTypes>
                            <printSubTypes>true</printSubTypes>
                            <regexEnabled>false</regexEnabled>
                            <caseSensitive>true</caseSensitive>
                            <queries>
                                <query>
                                    <type>Country</type>
                                </query>
                            </queries>
                        </analyze>
                    </schema>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Analysis report:

[kobby] GraphQL schema ready to analyze! (Kobby pattern case sensitive)
[kobby] Analyzed schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).

Country (weight: 9) <- Entity
  id^: ID (weight: 0)
  fields(String)^: JSON (weight: 0)
  name: String (weight: 0)
  film(ID): Film (weight: 9) <- Entity, Taggable, Native
  films(String, Genre, Int): Film (weight: 9) <- Entity, Taggable, Native
  actor(ID): Actor (weight: 9) <- Entity, Taggable, Native
  actors(String, Date, Gender, Int): Actor (weight: 9) <- Entity, Taggable, Native
  taggable(String): Taggable (weight: 9) <- Entity -> Film, Actor
  native: Native (weight: 9) -> Film, Actor

[kobby] Analyzed schema weight: 15 (7 objects, 2 interfaces, 1 unions, 2 enums, 3 inputs).
  • truncatedSchema - Use a truncated or original schema for analysis (default true - truncated schema).
  • depth - GraphQL schema analysis depth. Use -1 to analyse a schema with unlimited depth. (default 1).
  • reportLengthLimit - GraphQL schema analysis report length limit. Use -1 to print a report with unlimited length ( default 10000).
  • printMinWeight - The minimum weight of a GraphQL type that should be printed in the report (default 2).
  • printOverride - Print "override sign" (^) in report for overridden GraphQL type fields.
  • printArgumentTypes - Print GraphQL field argument types in a report.
  • printSuperTypes - Print GraphQL field supertypes in report (<- followed by a list of supertypes).
  • printSubTypes - Print GraphQL field subtypes in report (-> followed by a list of subtypes).
  • regexEnabled - Is Regex enabled in GraphQL schema analyze query (by default uses Kobby Pattern).
  • caseSensitive - Are patterns used in a GraphQL schema analyze query case sensitive (default true).

Clone this wiki locally