HotChocolate v.13 [UseProjections] attribute does not work with DataLoaders

HotChocolate v.13 [UseProjections] attribute does not work with DataLoaders


0

I have the following GrapqhQL query:

query {
  listTenants {
    totalCount
    items {
      tenantId
      name
      sites {
        totalCount
        items {
          siteId
          cmxName
          cmxState
          hosts(
            order: { hostId: ASC }
            where: { hostName: { neq: "ans" } }
            skip: 4
            take: 2
          ) {
            totalCount
            items {
              hostId
              hostName
              siteId
            }
          }
        }
      }
    }
  }
}

I want to use projections for the host object – I want to extract from the database only the hostId, hostName and siteId for each host. I extend the Site object type as follows:

namespace dataGraphAPI.Types.Nodes
{
    [ExtendObjectType<Site>]
    public static class SiteNode
    {
        [GraphQLName(SchemaConstants.Hosts)]
        [ListQueries]
        public static async Task<IEnumerable<Host>> GetHostsAsync(
            [Parent] Site site,
            IHostsBySiteIdDataLoader dataLoader,
            CancellationToken ct)
            =>  await dataLoader.LoadAsync(site.SiteId.ToString(), ct);
    }
}

My [ListQueries] attribute contains the following attributes:

using HotChocolate.Types.Descriptors;
using System.Reflection;

namespace dataGraphAPI.Types
{
    public sealed class ListQueriesAttribute : ObjectFieldDescriptorAttribute
    {
        protected override void OnConfigure(IDescriptorContext context, IObjectFieldDescriptor descriptor, MemberInfo member)
        {
            ApplyAttribute(
                context, 
                descriptor, 
                member, 
                new UseOffsetPagingAttribute() 
                { 
                    IncludeTotalCount = true,
                });

            ApplyAttribute(
                context,
                descriptor,
                member,
                new UseProjectionAttribute());

            ApplyAttribute(
                context,
                descriptor,
                member,
                new UseFilteringAttribute());

            ApplyAttribute(
                context,
                descriptor,
                member,
                new UseSortingAttribute());
        }
    }
}

My data loader is as follows:

[DataLoader]
internal static async Task<ILookup<string, Host>> GetHostsBySiteIdAsync(IReadOnlyList<string> siteIds, CmxDbContext dbContext, CancellationToken ct)
        {
            var hosts = dbContext.Hosts
                .Where(x => siteIds.Contains(x.SiteId.ToString()));

            return hosts.ToLookup(x => x.SiteId.ToString()!);
        }

My Program.cs is as follows:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<CmxDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("CMXContext"))
           .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
           .LogTo(Console.WriteLine, LogLevel.Information));

builder.Services
                .AddGraphQLServer()
                .AddTypes()
                .AddType<AggregateResult>()
                .AddType<CountResult>()
                .AddType<DistinctResult>()
                .AddDirectiveType<AggregateDirectiveType>()
                .AddDirectiveType<CountDirectiveType>()
                .AddDirectiveType<DistinctDirectiveType>()
                .AddFiltering()
                .AddSorting()
                .AddProjections()
                .RegisterDbContext<CmxDbContext>();

var app = builder.Build();

app.MapGraphQL();

app.Run();

The problem is that when I extract the hosts from the database the UseProjectionAttribute which is set in the ListQueriesAttribute does not work and I retrieve all the columns for each host from the database, not only the hostId, hostName and siteId. I am kind of new to data loaders and HotChocolate, so I may be doing something wrong. I understand that [UseProjection] works for IQueryable, but it seems to me that there is no way to return IQueryable with data loaders, hence I cannot apply the attribute to the data loader. Any suggestions how I can make this work with projections?

Share


Load 6 more related questions


Show fewer related questions

0

Reset to default



Browse other questions tagged

or ask your own question.

Leave a Reply

Your email address will not be published. Required fields are marked *