I am building a Quarkus app that queries the Linear GraphQL API at: https://api.linear.app/graphql
When I use the dynamic query like the following it builds the correct query and returns the correct result:
@Inject
@GraphQLClient("linear")
DynamicGraphQLClient dynamicClient;
@GET
@Path("/dynamicteams")
@Produces(MediaType.APPLICATION_JSON)
@Blocking
public JsonObject getTeams() throws Exception {
Document query = document(
operation(
field("teams",
field("nodes",
field("id"),
field("name")
)
)
)
);
Log.info("Query: " + query.build());
// ie Query: query { teams { nodes { id name } } }
Response response = dynamicClient.executeSync(query);
return response.getData();
}
sample response (anonymised):
{"teams":{"nodes":[{"id":"my-id-1","name":"Team 1"},{"id":"my-id-2","name":"Team 2"}]}}
But when I try the same thing using the TypeSafe variant , it builds a query that looks like the following. Note that the correct query is now nested inside a "teams" property.
query teams { teams { nodes { id name } } }
@Inject
LinearClientApi typesafeClient;
@GET
@Path("/safeteams")
@Produces(MediaType.APPLICATION_JSON)
@Blocking
public TeamsResponse getSafeTeams() {
TeamsResponse resp = typesafeClient.getTeams();
Log.info("Response: " + resp.toString());
return resp;
}
and the relevant classes are:
@GraphQLClientApi(configKey = "linear-typesafe")
public interface LinearClientApi {
TeamsResponse getTeams();
}
public class TeamsResponse {
private List<TeamNode> nodes;
public List<TeamNode> getNodes() {
return nodes;
}
public void setNodes(List<TeamNode> nodes) {
this.nodes = nodes;
}
}
public class TeamNode {
private String id;
private String name;
// Getters and setters
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The "teams" label is coming from the TeamsResponse getTeams();
. If I override the name using the @Query
annotation:
@Query(value="XXX")
TeamsResponse getTeams();
the query is built as:
query XXX { XXX {nodes {id name}} }
So, how am I generating that "nesting"? It must be obvious but I cannot see it.
Thanks, Murray
That's not 'nesting' your query into another query, that is just a feature of the GraphQL language. The typesafe client automatically wraps your query into a named operation (and it uses the name of the query
as the name of the operation, hence the 'duplication'), whereas dynamic client, unless you specify a name, wraps it into an unnamed operation. So, generally, you get query OPERATION_NAME { QUERY_NAME { nodes { id name } } }
,
but in the dynamic client case, because you didn't specify a name, the OPERATION_NAME
is omitted.