Search code examples
c#asp.net-coregraphqlhotchocolate

Issue with adding Object Type in GraphQL API using HotChocolate library in ASP.NET Core 7


I'm developing a GraphQL API in my ASP.NET Core 7 project using the HotChocolate library. I'm facing an issue while adding a new Object Type to the schema. Specifically, when I add my PlatformType class, the API requests stop processing correctly.

Here's my Query class where GetPlatform and GetCommand are defined:

using CommanderGQL.Data;
using CommanderGQL.Models;

namespace CommanderGQL.GraphQL
{
    public class Query
    {
        [UseDbContext(typeof(AppDbContext))]
        [UseProjection]
        public IQueryable<Platform> GetPlatform([ScopedService] AppDbContext context)
        {
            return context.Platforms;
        }

        [UseDbContext(typeof(AppDbContext))]
        [UseProjection]
        public IQueryable<Command> GetCommand([ScopedService] AppDbContext context)
        {
            return context.Commands;
        }
    }
}

And here are my Platform class:

using System.ComponentModel.DataAnnotations;

namespace CommanderGQL.Models
{
    public class Platform
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string Name { get; set; } = string.Empty;
        public string LicenseKey { get; set; } = string.Empty;
        public ICollection<Command> Commands { get; set; } = new List<Command>();
    }
}

This one is my Command class:

using System.ComponentModel.DataAnnotations;

namespace CommanderGQL.Models
{
    public class Command
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string HowTo { get; set; }
        [Required]
        public string CommandLine { get; set; }
        [Required]
        public int PlatformId { get; set; }
        public Platform Platform { get; set; }
    }
}

Now, this is my PlatformType code that seems to be causing the issue:

using CommanderGQL.Data;
using CommanderGQL.Models;

namespace CommanderGQL.GraphQL.Platforms
{
    public class PlatformType : ObjectType<Platform>
    {
        protected override void Configure(IObjectTypeDescriptor<Platform> descriptor)
        {
            descriptor.Description("Represents any software that has a command line interface");

            descriptor
                .Field(p => p.LicenseKey).Ignore();

            descriptor
                .Field(p => p.Commands)
                .ResolveWith<Resolvers>(p => p.GetCommands(default!, default!))
                .UseDbContext<AppDbContext>()
                .Description("This is the list of available commands for this platform");
        }

        private class Resolvers
        {
            public IQueryable<Command> GetCommands(Platform platform, [ScopedService] AppDbContext context) 
            {
                return context.Commands.Where(p => p.PlatformId == platform.Id);
            }
        }
    }
}

When I include the PlatformType class, API requests are no longer processed, and an error occurs. I added this configuration to Program.cs:

builder.Services
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .AddType<PlatformType>()
    .AddType<CommandType>()
    .AddFiltering()
    .AddSorting()
    .AddProjections();

So when I try to execute the following request:

query {
  platform {
    id
    name
    commands {
      howTo
      commandLine
      platformId
    }
  }
}

I get this responce:

{
  "errors": [
    {
      "message": "There was no argument with the name `platform` found on the field `commands`.",
      "locations": [
        {
          "line": 6,
          "column": 5
        }
      ],
      "path": [
        "platform",
        2,
        "commands"
      ],
      "extensions": {
        "fieldName": "commands",
        "argumentName": "platform"
      }
    },
    {
      "message": "There was no argument with the name `platform` found on the field `commands`.",
      "locations": [
        {
          "line": 6,
          "column": 5
        }
      ],
      "path": [
        "platform",
        1,
        "commands"
      ],
      "extensions": {
        "fieldName": "commands",
        "argumentName": "platform"
      }
    },
    {
      "message": "There was no argument with the name `platform` found on the field `commands`.",
      "locations": [
        {
          "line": 6,
          "column": 5
        }
      ],
      "path": [
        "platform",
        0,
        "commands"
      ],
      "extensions": {
        "fieldName": "commands",
        "argumentName": "platform"
      }
    }
  ]
}

How can I correctly add a new type to my GraphQL schema using the HotChocolate library? What might be causing this issue?


Solution

  • I finally found the solution; I needed to add the [Parent] attribute to the parameters of the methods in the PlatformType.Resolvers and CommandType.Resolvers classes. Here's how the updated methods should look:

    In PlatformType.Resolvers:

    public IQueryable<Command> GetCommands([Parent] Platform platform, [ScopedService] AppDbContext context)
    

    In CommandType.Resolvers:

    public Platform GetPlatform([Parent] Command command, [ScopedService] AppDbContext context)