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:
query GetContact {contact(name: "Byron") {# The generated model will be named `HomeAddress`homeAddress {street}# The generated model will be named `WorkAddress`workAddress {country}}}
will generate models like this:
class GetContact {class Data { ... }class Contact { ... }class HomeAddress { ... }class WorkAddress { ... }}
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 aList<Node>
than aList<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:
query GetContacts {contact(name: "Byron") {# The generated model will be named `HomeAddress`homeAddress {street}}emergencyContact {# The generated model will be named `HomeAddress1` by defaulthomeAddress {street}}}
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:
query GetContacts {contact(name: "Byron") {# The generated model will be named `HomeAddress`homeAddress {street}}emergencyContact {# With an alias, the generated model will be named `EmergencyAddress`emergencyAddress: homeAddress {street}}}
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.