Question re: N+1 and Authorization
Closed this issue · 4 comments
Hi,
First off thanks for the awesome work, looks like this might work for me. But first I have a few questions to get my head around this.
Am I right in saying that your library effectively maps graphql queries to dapper/SQL queries in a way that avoids the n+1 problem when one:many relationships are involved?
If so, is it doing this by effectively resolving the data for all the fields down the graph by the entry resolver, i.e. the resolver that the query is rooted at? Would this still work with the graphql-net's authorization toolset?
Thanks, Ben
Yep, it avoids the n+1 problem by growing query results horizontally rather than vertically. There's a point where this payoff starts to fade, but for most use cases you'll see a big performance increase.
I haven't used graphql-net's authorization toolset, but based on what I'm seeing browsing through their code, it shouldn't interfere with this library. Essentially, you build _QueryBuilder_s that are used by a single QueryBuilder that's rooted at the top of your schema. Each type resolves the same way it always has, this library just gets really critical about what information it retrieves on each object (preferably getting all data in one or two queries) before resolving.
I see what you mean, I did even more looking into it yesterday and my understanding is that if you do the following:
Field<ListGraphType<EmailType>>(
"emails",
description: "A list of email addresses for the person.",
resolve: context => context.Source.Emails
);
you're resolver function is just grabbing the value off the already constructed/populated entity, which you're saying is populated by executing the root-level query builder's generated SQL and the subsequent entity mapper.
Does that sound right? If so, then I guess the Authorization library should still play nice as it will intercept the resolver function call (e.g. context => context.Source.Emails
), apply the Authorization logic and approve/deny that field resolution.
Thanks, I think this is exactly what I need. GraphQL is great in principle, but without a really sensible layer to map the query to the data storage system easily, effectively and optimally it's very easy to run into trouble I can imagine.
@benmccallum Yes, that sounds right.
Thanks mate, will close.