apollographql / apollo-kotlin

:rocket:  A strongly-typed, caching GraphQL client for the JVM, Android, and Kotlin multiplatform.
https://www.apollographql.com/docs/kotlin
MIT License
3.76k stars 653 forks source link

Similarly named properties result in wrong object used in generated code #1156

Closed davidalbers closed 1 year ago

davidalbers commented 5 years ago

I have a query which I've simplified for this post:

info {
    amenityCategories {
        text
    }
    category
}

amenityCategories is a list of PropertyAmenityCategory Objects. category is an AmenityCategory which is an Enum.

Although named similarly, PropertyAmenityCategory is very different from AmenityCategory.

When the code is generated for it looks like this:

final @NotNull List<AmenityCategory> amenityCategories;
final com.apollographql.apollo.apollobug.type. @Nullable AmenityCategory category;

This causes an exception while building. The generated code should be something like:

final @NotNull List<PropertyAmenityCategory> amenityCategories;
final @Nullable com.apollographql.apollo.apollobug.type.AmenityCategory category;

apollo-android is incorrectly using List<AmenityCategory> for the field amenityCategories.

sav007 commented 5 years ago

pls check the lates snapshot version, I believe it was fixed recently

davidalbers commented 5 years ago

Hi @sav007, I updated to apollo-gradle-plugin:1.0.1-SNAPSHOT and still see the same compilation error

sav007 commented 5 years ago

If I am right you have 2 type definitions in your GraphQL schema that have name collision? One for enum another for object:

type PropertyAmenityCategory {
...
}

I'm trying to find the GraphQL specs if name in schema definition is unique or not, but that seems like not right, that schema has 2 types with the same name.

davidalbers commented 5 years ago

Each type definition has a unique name. However the names share the amenityCategory suffix which seems to cause a problem with apollo-android. Example schema.json:

"types": [ 
  {
    "kind": "OBJECT",
    "name": "PropertyAmenityCategory",
    ...
  },
  {
    "kind": "ENUM",
    "name": "AmenityCategory",
    ...
  },
  {
    "kind": "OBJECT",
    "name": "PropertyInfo",
    "fields": [
      {
        "name": "amenityCategories",
        "type": {
          "kind": "NON_NULL",
          "name": null,
          "ofType": {
            "kind": "LIST",
            "name": null,
            "ofType": {
              "kind": "NON_NULL",
              "name": null,
              "ofType": {
                "kind": "OBJECT",
                "name": "PropertyAmenityCategory",
                "ofType": null
              }
            }
          }
        }
      },
      {
        "name": "category",
        "type": {
          "kind": "ENUM",
          "name": "AmenityCategory",
          "ofType": null
        }
      }
    ]
  }
sav007 commented 5 years ago

agh, I see, so its field name causes this issue, well you can always use aliases https://graphql.github.io/learn/queries/#aliases but for sure we need to reserve enum type name and resolve name collision accordingly

davidalbers commented 5 years ago

That's a good workaround. Doing something like:

propertyAmenityCategories: amenityCategories {
...
}

will avoid the type mismatching and fixes the generated code errors.

sav007 commented 5 years ago

Yeah, the existing name conflict resolution in codegen is not straightforward, I thought it's easy fix but not really