Code first schema configuration with AddGraphQL() #1190
-
I am trying to configure my GraphQL server with code first schema and minimal API. I have followed the sample and this is what my API looks like currently:
I am trying to change this to use the built in GraphQLHttpMiddleware. I followed the docs and this is what my new API looks like:
The docs specify that this doesn't require UseGraphQL() or MapGraphQL() in the application startup. However. the sample uses builder.Services.AddGraphQL(). How do I invoke AddGraphQL() for the code first approach? I tried to do this:
which results in a compilation error System.ArgumentException: Cannot instantiate implementation type 'GraphQL.Types.ISchema' for service type 'GraphQL.Types.ISchema'. Is it possible to get the behavior I am expecting by invoking AddGraphQL() without AddSchema()? Any direction you could provide would be helpful, thanks. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 8 replies
-
I think you have to register a Dummy schema here and then you can later replace it with the actual schema. I have something similar to support dynamic schemas |
Beta Was this translation helpful? Give feedback.
-
Code first implies that you have a class that inherits from public class StarWarsSchema : Schema
{
public StarWarsSchema(IServiceProvider serviceProvider)
: base(serviceProvider)
{
Query = serviceProvider.GetRequiredService<StarWarsQuery>();
Mutation = serviceProvider.GetRequiredService<StarWarsMutation>();
Description = "Example StarWars universe schema";
}
} To register your code-first schema, just use something like this: builder.Services.AddGraphQL(b => b
// add your code-first schema class
.AddSchema<StarWarsSchema>()
// add the serialization engine to use
.AddSystemTextJson()
// auto-identify and register all graph types in the specified assembly and register them in the DI provider
.AddGraphTypes(typeof(StarWarsSchema).Assembly)
); However, if you are attempting to use schema-first, you will have code like this: private static ISchema BuildSchema(IServiceProvider serviceProvider)
{
// load the schema-first SDL from an embedded resource
var filename = "MyProject.MySchema.gql";
var assembly = Assembly.GetExecutingAssembly();
var stream = assembly.GetManifestResourceStream(filename)
?? throw new InvalidOperationException("Could not read schema definitions from embedded resource.");
var reader = new StreamReader(stream);
var schemaString = reader.ReadToEnd();
// create the schema
var schemaBuilder = new SchemaBuilder
{
ServiceProvider = serviceProvider,
};
schemaBuilder.Types.Include<Query>();
schemaBuilder.Types.Include<Category>();
// other configuration code for the schema goes here
// build the schema
return schemaBuilder.Build(schemaString);
} To register it, use code like this: builder.Services.AddGraphQL(b => b
.AddSchema(provider => BuildSchema(provider))
.AddSystemTextJson()
); Either way, there are many other methods available for configuring GraphQL.NET within the AddGraphQL method. See this link for a complete list of methods: The most common methods besides those noted above, I would say, would be:
Please note that the above instructions assume a singleton schema. If you need a scoped schema, use the overload of Once you have GraphQL configured within your DI provider, you can use this code to configure GraphQL at an endpoint: app.UseGraphQL("/graphql", opts => {
opts.ValidationErrorsReturnBadRequest = true;
}); The GraphQL.NET Server readme covers other ways to use the HTTP middleware; the code you supplied probably works just fine as well. There's also extensive documentation for authentication, authorization, CORS and other relevant information there also. |
Beta Was this translation helpful? Give feedback.
-
This error is caused by the use of
The GraphQL.NET Server ASP.NET Core middleware is expecting to pull
Based on your sample code, it would seem that you are using schema-first currently, with |
Beta Was this translation helpful? Give feedback.
-
Hi @Shane32, thanks for the detailed response. You are correct that I am using schema first. I mixed up the terminologies a bit.
I noticed from debugging is that ExecuteResultAsync() in GraphQLExecutionActionResult never gets invoked, and therefore the middleware doesn't get added to the pipeline. I think this is because I am using minimal API whose framework handles the execution of IResult and not IActionResult which is appropriate for controller based APIs. Perhaps I have to go with the custom middleware approach to add the middleware to the request pipeline. I am going to investigate this further on my end, thanks! |
Beta Was this translation helpful? Give feedback.
Code first implies that you have a class that inherits from
GraphQL.Types.Schema
- for example like this:To register your code-first schema, just use something like this: