Reputation: 1577
I am using hot chocolate graphql. I have a scenario where I have two separate query type classes.
My Folder Structure
Here it is how I am configuring it
.AddAuthorization()
//for inmemory subscription
.AddInMemorySubscriptions()
.AddQueryType<PostQuery>()
.AddQueryType<UserQuery>()
.AddMutationType<Mutation>()
.AddSubscriptionType<Subscription>()
.AddGlobalObjectIdentification()
// Registers the filter convention of MongoDB
.AddMongoDbFiltering()
// Registers the sorting convention of MongoDB
.AddMongoDbSorting()
// Registers the projection convention of MongoDB
.AddMongoDbProjections()
// Registers the paging providers of MongoDB
.AddMongoDbPagingProviders();
However, i am getting the following error
System.ArgumentException: The root type `Query` has already been registered
Is there anyway it can be configured or else I have to places everything in a single class?
Upvotes: 10
Views: 7363
Reputation: 643
Just came across this post and have a slight variation on @sjokkogutten answer based on my implementation:
I am extending an existing service which already has a Query implementation:
public class TemplatesQuery
{
public async Task<IQueryable<Template>> GetTemplates(
[Service] ILogger<TemplatesQuery> logger,
[Service] ITemplatesService templatesService)
{
...
}
}
To do this I am treating my subsequent Queries as extensions:
[ExtendObjectType(typeof(TemplatesQuery))]
public class SignaturesQuery
{
public async Task<IQueryable<Signature>> GetSignatures(
[Service] ILogger<SignaturesQuery> logger,
[Service] ISignaturesService signaturesService)
{
...
}
}
and then registering the new service as a type extension:
builder.Services.AddGraphQLServer()
.AddQueryType<TemplatesQuery>()
.AddTypeExtension<SignaturesQuery>();
The result is the same as @sjokkogutten answer but it avoids having to define a "pretend" query type while maintaining separation of concerns for the different workflows. It also means if you have an existing service you want to extend that you don't have to mess with any existing code. Good old open close principal :)
Upvotes: 1
Reputation: 1593
First thanks to @sjokkogutten for his answer. I strongly disagree with his approach. As your application size gets larger your types will become more tedious to manage.
The better approach would be to define your queries in partial classes.
postQuery.cs
public partial class Query
{
public List<Post> GetAllPosts()
{
return List<Post>{...};
}
}
UserQuery.cs
public partial class Query
{
public List<User> GetAllUsers()
{
return List<User>{...};
}
}
Upvotes: 8
Reputation: 2095
You need to register the querytype "Query" and add resolvers to handle multiple schemas of type "Query"
builder.Services
.AddQueryType(q => q.Name("Query"))
.AddType<PostQuery>()
.AddType<UserQuery>()
And in your query classes:
[ExtendObjectType("Query")]
public class PostQuery
{
public List<Post> GetAllPosts()
{
return List<Post>{...};
}
}
[ExtendObjectType("Query")]
public class UserQuery
{
public List<User> GetAllUsers()
{
return List<User>{...};
}
}
Upvotes: 23