GraphQL with .NET Core (Part - II: Middleware)
source link: https://www.fiyazhasan.me/graphql-with-net-core-part-ii-middleware/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
GraphQL with .NET Core (Part - II: Middleware)
We will start by creating a blank ASP.Net Core App. Gradually we will create a middleware that can handle GraphQL requests.
dotnet new web
If you are familiar with ASP.NET Core middleware, you may have noticed in Startup.cs
, that it responses back "Hello World!" on application start-up. Here, UseEndpoints
is a middleware that executes an endpoint associated with the current request.
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello World!");
});
});
Startup.csPractically a middleware is a delegate or more precisely; a request delegate
. As the name suggests, it handles an incoming request and decides whether or not to delegate it to the next middleware in the pipeline. In our case, we configured a request delegate using the Run()
(extension) method of IApplicationBuilder
. Between three extension methods (Use
, Run
, Map
), Run()
terminates the request for further modifications in the request pipeline.
The code in our console application was very simple and can only respond to a result of a hardcoded static query. However, in a real-world scenario, the query should be dynamic hence we must read it from the incoming request.
It's a rule of thumb that all GraphQL requests (either query/mutation/subscription) should be posted over HTTP POST
method. So, we change the MapGet
method to MapPost
. We also update the endpoint to a more specific one rather than the default root path ("/"
).
app.UseEndpoints(endpoints =>
{
endpoints.MapPost("/graphql", async context => {});
});
Startup.csA request body can contain a whole lot of fields, but let's say the passed in query comes within a field named query
. So we can parse out the JSON string content of the body
into a complex type that contains a Query
property,
public class GraphQLRequest
{
public string Query { get; set; }
}
GraphQLRequest.csEvery request delegate accepts a HttpContext
. If the query is posted over an HTTP request, you can easily read the request body as JSON using the following code and parse it to GraphQLRequest
,
var request = await JsonSerializer
.DeserializeAsync<GraphQLRequest>(
context.Request.Body,
new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
We are following the code-first approach for creating a schema. So, we have a Query class as follows,
public class GameStoreQuery : ObjectGraphType
{
public GameStoreQuery()
{
Field<StringGraphType>(
name: "name",
resolve: context => "Steam"
);
}
}
GameStoreQuery.csFinally, we use DocumentExecuter
to execute the query. It returns a ExecutionResult
. We use the DocumentWriter
to write the ExecutionResult
to the context response body.
var schema = new Schema { Query = new GameStoreQuery() };
var result = await new DocumentExecuter()
.ExecuteAsync(doc =>
{
doc.Schema = schema;
doc.Query = request.Query;
}).ConfigureAwait(false);
await new DocumentWriter(indent: true).WriteAsync(context.Response.Body, result);
Startup.csDocumentExecuter
is available inGraphQL
namespaceDocumentWriter
is available inGraphQL.NewtonsoftJson
namespace
So, after all the modifications, code in the UseEndpoints
method of Startup.cs
looks as follows,
app.UseEndpoints(endpoints =>
{
endpoints.MapPost("/graphql", async context =>
{
var request = await JsonSerializer
.DeserializeAsync<GraphQLRequest>(
context.Request.Body,
new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
var schema = new Schema { Query = new GameStoreQuery() };
var result = await new DocumentExecuter()
.ExecuteAsync(doc =>
{
doc.Schema = schema;
doc.Query = request.Query;
}).ConfigureAwait(false);
await new DocumentWriter(indent: true).WriteAsync(context.Response.Body, result);
});
});
Startup.csNow you make a POST
request containing the query field using any rest client (Postman/Insomnia),
In Insomnia, you can send structured graphql query like we are used to from our previous console app,
query {
name
}
We are pretty much done with this post. But you can see that we have a lot of newing
ups of objects like the new DocumentExecuter()
, new Schema()
, new DocumentWriter()
, etc. In the next post, we will see how we can use the built-in dependency system of ASP.NET Core
and make them injectable.
Repository Link:
Important Links:
Share: Twitter Facebook LinkedIn
Comments
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK