Reputation: 2535
I am learning how to write GraphQL in asp.net core 5 project. I am using Hot Chocolate v5 and got an error when executing the following query:
query
{
platform
{
id
name,
commands
{
id
howTo
commandLine
}
}
}
Executing this query I got the following error:
{
"errors": [
{
"message": "There was no argument with the name platform
found on the field commands
.",
"locations": [
{
"line": 7,
"column": 5
}
],
"path": [
"platform",
4,
"commands"
],
"extensions": {
"fieldName": "commands",
"argumentName": "platform"
}
}, ...
If I execute the query where there the following queries then its working:
query
{
platform
{
id
name
}
}
query
{
command
{
id
howTo
commandLine
}
}
My code fragments that I think is relevant for this error are:
public class Command
{
/// <summary>
/// Represents the unique ID for the command.
/// </summary>
[Key]
public int Id { get; set; }
/// <summary>
/// Represents the how-to for the command.
/// </summary>
[Required]
public string HowTo { get; set; }
/// <summary>
/// Represents the command line.
/// </summary>
[Required]
public string CommandLine { get; set; }
/// <summary>
/// Represents the unique ID of the platform which the command belongs.
/// </summary>
[Required]
public int PlatformId { get; set; }
/// <summary>
/// This is the platform to which the command belongs.
/// </summary>
public Platform Platform { get; set; }
}
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions options) : base(options)
{
}
public DbSet<Platform> Platforms { get; set; }
public DbSet<Command> Commands { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Platform>()
.HasMany(x => x.Commands)
.WithOne(x => x.Platform!)
.HasForeignKey(x => x.PlatformId);
builder.Entity<Command>()
.HasOne(x => x.Platform)
.WithMany(x => x.Commands)
.HasForeignKey(x => x.PlatformId);
}
}
[GraphQLDescription("Represents the queries available.")]
public class Query
{
/// <summary>
/// Gets the queryable <see cref="Command"/>.
/// </summary>
/// <param name="context">The <see cref="AppDbContext"/>.</param>
/// <returns>The queryable <see cref="Command"/>.</returns>
[UseDbContext(typeof(AppDbContext))]
[UseFiltering]
[UseSorting]
[GraphQLDescription("Gets the queryable command.")]
public IQueryable<Command> GetCommand([ScopedService] AppDbContext context)
{
return context.Commands;
}
/// <summary>
/// Gets the queryable <see cref="Platform"/>.
/// </summary>
/// <param name="context">The <see cref="AppDbContext"/>.</param>
/// <returns>The queryable <see cref="Platform"/>.</returns>
[UseDbContext(typeof(AppDbContext))]
[UseFiltering]
[UseSorting]
[GraphQLDescription("Gets the queryable platform.")]
public IQueryable<Platform> GetPlatform([ScopedService] AppDbContext context)
{
return context.Platforms;
}
public class PlatformType : ObjectType<Platform>
{
protected override void Configure(IObjectTypeDescriptor<Platform> descriptor)
{
descriptor.Description("Represents any software or service that has a command line interface.");
descriptor.Field(p => p.Id)
.Description("Represents the unique ID for the platform.");
descriptor.Field(p => p.Name)
.Description("Represents the name for the platform.");
descriptor.Field(p => p.LicenceKey)
.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);
}
}
public class CommandType : ObjectType<Command>
{
protected override void Configure(IObjectTypeDescriptor<Command> descriptor)
{
descriptor.Description("Represents any executable command.");
descriptor.Field(c => c.Id)
.Description("Represents the unique ID for the command.");
descriptor.Field(c => c.HowTo)
.Description("Represents the how-to for the command.");
descriptor.Field(c => c.CommandLine)
.Description("Represents the command line.");
descriptor.Field(c => c.PlatformId)
.Description("Represents the unique ID of the platform which the command belongs.");
descriptor.Field(c => c.Platform)
.ResolveWith<Resolvers>(c => c.GetPlatform(default!, default!))
.UseDbContext<AppDbContext>()
.Description("This is the platform to which the command belongs.");
}
private class Resolvers
{
public Platform GetPlatform(Command command, [ScopedService] AppDbContext context)
{
return context.Platforms.FirstOrDefault(p => p.Id == command.PlatformId);
}
}
public class Startup
{
private IConfiguration Configuration { get; }
public Startup(IConfiguration collection)
{
Configuration = collection;
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureDbContext(Configuration);
services.ConfigureGraphQL();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseWebSockets();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGraphQL();
});
app.ConfigureGraphQL();
}
public static class ContexConfiguration
{
public static void ConfigureDbContext(this IServiceCollection services, IConfiguration configuration)
{
services.AddPooledDbContextFactory<AppDbContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));
}
}
public static class GraphQLConfiguration
{
/// <summary>
/// Configuration of the GrapQL server
/// </summary>
/// <param name="services"></param>
public static void ConfigureGraphQL(this IServiceCollection services)
{
services.AddGraphQLServer()
.AddQueryType<Query>()
.AddMutationType<Mutation>()
.AddSubscriptionType<Subscription>()
.AddType<PlatformType>()
.AddType<AddPlatformInputType>()
.AddType<AddPlatformPayloadType>()
.AddType<CommandType>()
.AddType<AddCommandInputType>()
.AddType<AddCommandPayloadType>()
.AddFiltering()
.AddSorting()
.AddInMemorySubscriptions();
}
/// <summary>
/// GraphQL Voyager UI configuration
/// </summary>
/// <param name="app"></param>
public static void ConfigureGraphQL(this IApplicationBuilder app)
{
app.UseGraphQLVoyager(
options: new VoyagerOptions()
{
GraphQLEndPoint = "/graphql"
},
path: "/graphql-voyager"
);
}
}
Upvotes: 1
Views: 2049