Using aliases


When generating code, Apollo Kotlin uses the name of your fields to generate matching typesafe models using a flat hierarchy. The following query:

GraphQL
GetContact.graphql
1query GetContact {
2  contact(name: "Byron") {
3    # The generated model will be named `HomeAddress`
4    homeAddress {
5      street
6    }
7    # The generated model will be named `WorkAddress`
8    workAddress {
9      country
10    }
11  }
12}

will generate models like this:

Kotlin
1class GetContact {
2  class Data { ... }
3  class Contact { ... }
4  class HomeAddress { ... }
5  class WorkAddress { ... }
6}

The driving principles behind the naming conventions are:

  • Use the field name for model names: we considered using the schema type name instead but that would make a lot of conflicts. In the example above, for an example, we would have two different Address classes.

  • Keep a flat hierarchy of classes: we considered using nested classes but that can lead to very long names and a flat hierarchy is easier to read.

  • Singularize the field name when it is a list: if your query contains a List fields, such as nodes for an example, it makes more sense to generate a List<Node> than a List<Nodes>.

These principles work great for the vast majority of cases but can't account for name clashes or peculiar singularization rules. To workaround these, you can use GraphQL aliases.

Using aliases to avoid name clashes

Since the class hierarchy is flat, having two fields with the same name in two different parts of the query tree could lead to name clashes. Having relay-style pagination with lots of nodes or edges fields, might typically trigger name clashes. To avoid them, Apollo Kotlin will append a numeric suffix to your models:

GraphQL
GetContact.graphql
1query GetContacts {
2  contact(name: "Byron") {
3    # The generated model will be named `HomeAddress`
4    homeAddress {
5      street
6    }
7  }
8  emergencyContact {
9    # The generated model will be named `HomeAddress1` by default
10    homeAddress {
11      street
12    }
13  }
14}

Suffixing avoids the name clash but feels a bit out of place and it's hard to remember what HomeAddress1 is about. To workaround this issue, you can alias the field:

GraphQL
GetContact.graphql
1query GetContacts {
2  contact(name: "Byron") {
3    # The generated model will be named `HomeAddress`
4    homeAddress {
5      street
6    }
7  }
8  emergencyContact {
9    # With an alias, the generated model will be named `EmergencyAddress`
10    emergencyAddress: homeAddress {
11      street
12    }
13  }
14}

Using aliases to fix singularization rules

The singularization code works most of the time but does not contain all the exceptions in the English dictionary.

If you encounter one, please let us know so we can put a valid example here (we usually fix those issues as we go but there certainly are a few left in the wild). Until we fix it in the singularization code, you can use an alias to control the name of the model in your code.

Feedback

Edit on GitHub

Forums