We have a GraphQL dotnet implementation sitting on top of our existing app database.
<PackageReference Include="GraphQL" Version="3.3.2" />
<PackageReference Include="GraphQL.SystemTextJson" Version="3.3.2" />
<PackageReference Include="GraphQL.Server.Transports.AspNetCore" Version="4.4.1" />
<PackageReference Include="GraphQL.Server.Transports.WebSockets" Version="4.4.1" />
<PackageReference Include="GraphQL.Server.Transports.AspNetCore.SystemTextJson" Version="4.4.1" />
<PackageReference Include="GraphQL.Server.Ui.Playground" Version="4.4.1" />
<PackageReference Include="GraphQL.Server.Authorization.AspNetCore" Version="4.4.1" />
We have a fairly intertwined data structure, so when querying from some of our top level fields, and including some of their sub fields, we could be joining on a large number of tables. However, not every query would need all those joins.
I was hoping to be able to manually parse the context.Arguments in our Query ObjectGraphType when I am resolving it to eliminate the joins if a particular sub-field is not queried.
A very simple high level version of this would be as follows:
Field<ListGraphType<OrganisationType>>(
"organisations",
resolve: context =>
{
var retVal = database.Organisations();
//Are we joining on employers?
if(context.SubFields.ContainsKey("employers"))
{
retVal.Include(x => x.Employers.Where(x => x.Deleted != true))
.ThenInclude(x => x.Departments.Where(x => x.Deleted != true));
}
return retVal;
}
Where we only join on employers, if the user has queried that. However, the issue is that employers can have departments, employees, managers etc etc... and those themselves can have a large number of sub-properties.
Currently our query joins on pretty much every permutation of the query, producing a really hefty SQL query. Which is a lot of heavy lifting if the user only wants, the organisation name, and each employers name.
Filtering on the very top level is easy enough (as shown above) but I can't figure out how to query from that point onwards, I just seem to end up in an infinite loop of Children... for example:
var employerSubField = context.SubFields["employers"];
var otherJoins = employerSubField.SelectionSet.Children.Where(x => x.Children)
I can't seem to get a where name == "Employees" or anything like that. Do I need to cast the GraphQL.Language.AST.INode to something at some point? When I inspect the values at debug time it looks like I should be able to see the values I am after. But this won't compile.
var deptsField = employerSubField.SelectionSet.Selections.Where(x => x.Name == "departments");
I have found the following way to get the basic information out that I can then easily parse myself and add my own custom logic.
var query = context.Document.OriginalQuery.Substring(context.Document.OriginalQuery.IndexOf("{")).RemoveWhitespace();
returns:
{organisations{id,name,employers{id,name,clientNotes,departments{id,name}}}}