dgs-codegen icon indicating copy to clipboard operation
dgs-codegen copied to clipboard

Parsing of response to generated query to generated type fails when encountering an enum

Open hmolinari-attentive opened this issue 3 years ago • 0 comments

I use the schema found here (also attached as txt) schema.txt

Using codegen, I generate this request:

query {
  site {
    settings {
      url {
        vanityUrl
      }
    }
    products(first: 10) {
      pageInfo {
        hasNextPage
        endCursor
      }
      edges {
        node {
          entityId
          name
          plainTextDescription(characterLimit: 1024)
          brand {
            name
          }
          availabilityV2 {
            status
          }
          inventory {
            hasVariantInventory
            aggregated {
              availableToSell
            }
          }
          path
          categories(first: 10) {
            pageInfo {
              hasNextPage
              endCursor
            }
            edges {
              node {
                name
              }
            }
          }
          images(first: 50) {
            pageInfo {
              hasNextPage
              endCursor
            }
            edges {
              node {
                urlOriginal
                altText
              }
            }
          }
          prices {
            price {
              value
              currencyCode
            }
            basePrice {
              value
              currencyCode
            }
            salePrice {
              value
              currencyCode
            }
          }
          productOptions(first: 3) {
            pageInfo {
              hasNextPage
              endCursor
            }
            edges {
              node {
                displayName
                ... on MultipleChoiceOption {
                  __typename
                  values {
                    pageInfo {
                      hasNextPage
                      endCursor
                    }
                    edges {
                      node {
                        label
                      }
                    }
                  }
                }
              }
            }
          }
          variants(first: 200) {
            pageInfo {
              hasNextPage
              endCursor
            }
            edges {
              node {
                inventory {
                  aggregated {
                    availableToSell
                  }
                }
                entityId
                productOptions(first: 3) {
                  pageInfo {
                    hasNextPage
                    endCursor
                  }
                  edges {
                    node {
                      entityId
                      displayName
                      ... on MultipleChoiceOption {
                        __typename
                        values {
                          pageInfo {
                            hasNextPage
                            endCursor
                          }
                          edges {
                            node {
                              label
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

I get this response:

{
  "data" : {
    "site" : {
      "settings" : {
        "url" : {
          "vanityUrl" : "https://shop.soapboxus.com"
        }
      },
      "products" : {
        "pageInfo" : {
          "hasNextPage" : false,
          "endCursor" : "YXJyYXljb25uZWN0aW9uOjA="
        },
        "edges" : [ {
          "node" : {
            "entityId" : 175,
            "name" : "Tide ReLoad Compatible Detergent",
            "plainTextDescription" : "\n\nThis Box Contains\nOne Tide ReLoad™ tray and Detergent\nTide ReLoad™ tray works with multiple types of detergent, shipped directly from us with free shipping. Just choose the type of Tide you like best – Tide PODS Original, Tide PODS Spring Meadow, or Tide Eco-Box Original. Please note that Tide ReLoad™ tray will not work with Tide products purchased elsewhere.\n",
            "brand" : null,
            "availabilityV2" : {
              "status" : "Available"
            },
            "inventory" : {
              "hasVariantInventory" : false,
              "aggregated" : null
            },
            "path" : "/tide-smart-tray-detergent/",
            "categories" : {
              "pageInfo" : {
                "hasNextPage" : false,
                "endCursor" : null
              },
              "edges" : [ ]
            },
            "images" : {
              "pageInfo" : {
                "hasNextPage" : false,
                "endCursor" : "YXJyYXljb25uZWN0aW9uOjY="
              },
              "edges" : [ {
                "node" : {
                  "urlOriginal" : "https://cdn11.bigcommerce.com/s-v1a6036467/images/stencil/original/products/175/800/Image_1_-_Delivered__03950.1633532989.jpg",
                  "altText" : ""
                }
              }, {
                "node" : {
                  "urlOriginal" : "https://cdn11.bigcommerce.com/s-v1a6036467/images/stencil/original/products/175/802/Image_2_-_Free_Shipping__53500.1633532989.jpg",
                  "altText" : ""
                }
              }, {
                "node" : {
                  "urlOriginal" : "https://cdn11.bigcommerce.com/s-v1a6036467/images/stencil/original/products/175/815/Image_3_-_Never_run_out_copy__63238.1633532989.jpg",
                  "altText" : ""
                }
              }, {
                "node" : {
                  "urlOriginal" : "https://cdn11.bigcommerce.com/s-v1a6036467/images/stencil/original/products/175/799/Image_4_-_Cancel_Anytime__26398.1633532989.jpg",
                  "altText" : ""
                }
              }, {
                "node" : {
                  "urlOriginal" : "https://cdn11.bigcommerce.com/s-v1a6036467/images/stencil/original/products/175/798/Image_5_-_Set_up__06965.1633532989.jpg",
                  "altText" : ""
                }
              }, {
                "node" : {
                  "urlOriginal" : "https://cdn11.bigcommerce.com/s-v1a6036467/images/stencil/original/products/175/803/Image_6_-_Skip_the_trip_to_the_store__76617.1633532989.jpg",
                  "altText" : ""
                }
              }, {
                "node" : {
                  "urlOriginal" : "https://cdn11.bigcommerce.com/s-v1a6036467/images/stencil/original/products/175/801/Image_7_-_Comes_with__54036.1633532989.jpg",
                  "altText" : ""
                }
              } ]
            },
            "prices" : {
              "price" : {
                "value" : 19.99,
                "currencyCode" : "USD"
              },
              "basePrice" : {
                "value" : 19.99,
                "currencyCode" : "USD"
              },
              "salePrice" : null
            },
            "productOptions" : {
              "pageInfo" : {
                "hasNextPage" : false,
                "endCursor" : "YXJyYXljb25uZWN0aW9uOjA="
              },
              "edges" : [ {
                "node" : {
                  "displayName" : "Your detergent selection",
                  "__typename" : "MultipleChoiceOption",
                  "values" : {
                    "pageInfo" : {
                      "hasNextPage" : false,
                      "endCursor" : "YXJyYXljb25uZWN0aW9uOjI="
                    },
                    "edges" : [ {
                      "node" : {
                        "label" : "Original"
                      }
                    }, {
                      "node" : {
                        "label" : "Spring Meadow"
                      }
                    }, {
                      "node" : {
                        "label" : "Tide Eco Box"
                      }
                    } ]
                  }
                }
              } ]
            },
            "variants" : {
              "pageInfo" : {
                "hasNextPage" : false,
                "endCursor" : "YXJyYXljb25uZWN0aW9uOjI="
              },
              "edges" : [ {
                "node" : {
                  "inventory" : {
                    "aggregated" : null
                  },
                  "entityId" : 170,
                  "productOptions" : {
                    "pageInfo" : {
                      "hasNextPage" : false,
                      "endCursor" : "YXJyYXljb25uZWN0aW9uOjA="
                    },
                    "edges" : [ {
                      "node" : {
                        "entityId" : 21,
                        "displayName" : "Your detergent selection",
                        "__typename" : "MultipleChoiceOption",
                        "values" : {
                          "pageInfo" : {
                            "hasNextPage" : false,
                            "endCursor" : "YXJyYXljb25uZWN0aW9uOjA="
                          },
                          "edges" : [ {
                            "node" : {
                              "label" : "Original"
                            }
                          } ]
                        }
                      }
                    } ]
                  }
                }
              }, {
                "node" : {
                  "inventory" : {
                    "aggregated" : null
                  },
                  "entityId" : 171,
                  "productOptions" : {
                    "pageInfo" : {
                      "hasNextPage" : false,
                      "endCursor" : "YXJyYXljb25uZWN0aW9uOjA="
                    },
                    "edges" : [ {
                      "node" : {
                        "entityId" : 21,
                        "displayName" : "Your detergent selection",
                        "__typename" : "MultipleChoiceOption",
                        "values" : {
                          "pageInfo" : {
                            "hasNextPage" : false,
                            "endCursor" : "YXJyYXljb25uZWN0aW9uOjA="
                          },
                          "edges" : [ {
                            "node" : {
                              "label" : "Spring Meadow"
                            }
                          } ]
                        }
                      }
                    } ]
                  }
                }
              }, {
                "node" : {
                  "inventory" : {
                    "aggregated" : null
                  },
                  "entityId" : 172,
                  "productOptions" : {
                    "pageInfo" : {
                      "hasNextPage" : false,
                      "endCursor" : "YXJyYXljb25uZWN0aW9uOjA="
                    },
                    "edges" : [ {
                      "node" : {
                        "entityId" : 21,
                        "displayName" : "Your detergent selection",
                        "__typename" : "MultipleChoiceOption",
                        "values" : {
                          "pageInfo" : {
                            "hasNextPage" : false,
                            "endCursor" : "YXJyYXljb25uZWN0aW9uOjA="
                          },
                          "edges" : [ {
                            "node" : {
                              "label" : "Tide Eco Box"
                            }
                          } ]
                        }
                      }
                    } ]
                  }
                }
              } ]
            }
          }
        } ]
      }
    }
  }
}

I then attempt to parse the response to the proper generated type

GraphQLResponse graphQLResponse =
                graphQLClient.executeQuery(graphQLQueryRequest.serialize());

        Optional<JsonNode> dataOptional =
                Optional.of(objectMapper.readTree(graphQLResponse.getJson()));

        System.out.println(dataOptional.get().toPrettyString());

        Optional<JsonNode> siteOptional =
                dataOptional.map(json -> json.get("data")).map(data -> data.get("site"));

        if (siteOptional.isEmpty()) {
            throw new NullPointerException();
        }

        com.attentivemobile.syncprocessor.model.bigcommerce.types.Site site =
                objectMapper.treeToValue(siteOptional.get(), Site.class);

then I get this

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type, class com.attentivemobile.syncprocessor.model.bigcommerce.types.ProductAvailability]: missing type id property '__typename' (for POJO property 'availabilityV2')
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: com.attentivemobile.syncprocessor.model.bigcommerce.types.Site["products"]->com.attentivemobile.syncprocessor.model.bigcommerce.types.ProductConnection["edges"]->java.util.ArrayList[0]->com.attentivemobile.syncprocessor.model.bigcommerce.types.ProductEdge["node"]->com.attentivemobile.syncprocessor.model.bigcommerce.types.Product["availabilityV2"])

I'm using the following configuration via the community maven port

<plugin>
                <groupId>io.github.deweyjose</groupId>
                <artifactId>graphqlcodegen-maven-plugin</artifactId>
                <version>1.16</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <schemaPaths>
                                <param>
                                    src/main/resources/api/bigcommerce/schema.graphql
                                </param>
                            </schemaPaths>
                            <packageName>com.attentivemobile.syncprocessor.model.bigcommerce</packageName>

                            <!--                            Required because scalars chosen by BigCommerce impose graphql-java scalar mappings-->
                            <typeMapping>
                                <BigDecimal>java.math.BigDecimal</BigDecimal>
                                <Long>java.lang.Long</Long>
                                <PageInfo>
                                    com.attentivemobile.syncprocessor.model.bigcommerce.GraphQLConnection.PageInfo
                                </PageInfo>
                            </typeMapping>

                            <generateClient>true</generateClient>

                            <includeQueries>site</includeQueries>
                            <includeSubscriptions>[]</includeSubscriptions>
                            <includeMutations>[]</includeMutations>

                            <omitNullInputFields>true</omitNullInputFields>

                            <maxProjectionDepth>20</maxProjectionDepth>

                            <outputDir>${project.build.directory}/generated-sources/graphqlcodegen</outputDir>

                            <kotlinAllFieldsOptional>true</kotlinAllFieldsOptional>
                            <language>java</language>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

The PageInfo mapping is a circumvention of this issue

The versions of libraries I'm using:

<!-- https://mvnrepository.com/artifact/com.netflix.graphql.dgs.codegen/graphql-dgs-codegen-client-core -->
        <dependency>
            <groupId>com.netflix.graphql.dgs.codegen</groupId>
            <artifactId>graphql-dgs-codegen-client-core</artifactId>
            <version>5.1.16</version>
        </dependency>

        <dependency>
            <groupId>com.netflix.graphql.dgs</groupId>
            <artifactId>graphql-dgs-client</artifactId>
            <version>4.9.20</version>
        </dependency>

hmolinari-attentive avatar Mar 05 '22 23:03 hmolinari-attentive