dgs-codegen
dgs-codegen copied to clipboard
Parsing of response to generated query to generated type fails when encountering an enum
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>