GraphQL for .NET - Subscription Transport WebSockets






GraphQL ASP.NET Core server on top of GraphQL.NET.
Transport compatible with Apollo subscription protocol.
Provides the following packages:
| GraphQL.Server.All |  |  |
| GraphQL.Server.Core |  |  |
| GraphQL.Server.Transports.AspNetCore |  |  |
| GraphQL.Server.Transports.AspNetCore.NewtonsoftJson |  |  |
| GraphQL.Server.Transports.AspNetCore.SystemTextJson |  |  |
| GraphQL.Server.Transports.Subscriptions.Abstractions |  |  |
GraphQL.Server.Transports.Subscriptions.WebSockets formerly known as GraphQL.Server.Transports.WebSockets |  |  |
| GraphQL.Server.Ui.Altair |  |  |
| GraphQL.Server.Ui.Playground |  |  |
| GraphQL.Server.Ui.GraphiQL |  |  |
| GraphQL.Server.Ui.Voyager |  |  |
| GraphQL.Server.Authorization.AspNetCore |  |  |
You can install the latest stable versions via NuGet.
Also you can get all preview versions from GitHub Packages.
Note that GitHub requires authentication to consume the feed. See more information here.
Getting started
TL;DR
Install GraphQL.Server.All meta package with all the packages you need to get started.
1. HTTP middleware for GraphQL
For just the HTTP middleware:
> dotnet add package GraphQL.Server.Transports.AspNetCore
The HTTP middleware needs an IGraphQLRequestDeserializer implementation.
.NET Core 3+:
> dotnet add package GraphQL.Server.Transports.AspNetCore.SystemTextJson
Legacy (prior to .NET Core 3):
> dotnet add package GraphQL.Server.Transports.AspNetCore.NewtonsoftJson
Or you can use your own IGraphQLRequestDeserializer implementation.
For more information on how to migrate from Newtonsoft.Json to System.Text.Json see
this article.
2. WebSockets transport for subscriptions
For the WebSocket subscription protocol (depends on above) middleware:
> dotnet add package GraphQL.Server.Transports.Subscriptions.WebSockets
3. Authorization
For integration of GraphQL.NET validation subsystem into ASP.NET Core:
> dotnet add package GraphQL.Server.Authorization.AspNetCore
4. UI integration
For the UI middlewares:
> dotnet add package GraphQL.Server.Ui.Altair
> dotnet add package GraphQL.Server.Ui.GraphiQL
> dotnet add package GraphQL.Server.Ui.Playground
> dotnet add package GraphQL.Server.Ui.Voyager
public void Configure(IApplicationBuilder app)
{
app.[Use|Map]GraphQLAltair();
app.[Use|Map]GraphQLGraphiQL();
app.[Use|Map]GraphQLPlayground();
app.[Use|Map]GraphQLVoyager();
}
Also each middleware accepts options to configure its behavior and UI.
Configure
See the sample project's Startup.cs or StartupWithRouting.cs for full details.
More information about ASP.NET Core routing here.
public void ConfigureServices(IServiceCollection services)
{
services
.AddSingleton<IChat, Chat>()
.AddSingleton<ChatSchema>();
MicrosoftDI.GraphQLBuilderExtensions.AddGraphQL(services)
.AddServer(true)
.ConfigureExecution(options =>
{
options.EnableMetrics = Environment.IsDevelopment();
var logger = options.RequestServices.GetRequiredService<ILogger<Startup>>();
options.UnhandledExceptionDelegate = ctx => logger.LogError("{Error} occurred", ctx.OriginalException.Message);
})
.AddSystemTextJson()
.AddNewtonsoftJson()
.AddErrorInfoProvider(opt => opt.ExposeExceptionStackTrace = Environment.IsDevelopment())
.AddWebSockets()
.AddDataLoader()
.AddGraphTypes(typeof(ChatSchema).Assembly)
}
public void Configure(IApplicationBuilder app)
{
app.UseWebSockets();
app.UseGraphQLWebSockets<ChatSchema>();
app.UseGraphQL<ChatSchema>();
app.UseGraphQLGraphiQL();
app.UseGraphQLPlayground();
app.UseGraphQLAltair();
app.UseGraphQLVoyager();
}
public void ConfigureServices(IServiceCollection services)
{
services
.AddRouting()
.AddSingleton<IChat, Chat>()
.AddSingleton<ChatSchema>();
MicrosoftDI.GraphQLBuilderExtensions.AddGraphQL(services)
.AddServer(true)
.ConfigureExecution(options =>
{
options.EnableMetrics = Environment.IsDevelopment();
var logger = options.RequestServices.GetRequiredService<ILogger<Startup>>();
options.UnhandledExceptionDelegate = ctx => logger.LogError("{Error} occurred", ctx.OriginalException.Message);
})
.AddDefaultEndpointSelectorPolicy()
.AddSystemTextJson()
.AddNewtonsoftJson()
.AddErrorInfoProvider(opt => opt.ExposeExceptionStackTrace = Environment.IsDevelopment())
.AddWebSockets()
.AddDataLoader()
.AddGraphTypes(typeof(ChatSchema).Assembly);
}
public void Configure(IApplicationBuilder app)
{
app.UseWebSockets();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGraphQLWebSockets<ChatSchema>();
endpoints.MapGraphQL<ChatSchema, GraphQLHttpMiddlewareWithLogs<ChatSchema>>();
endpoints.MapGraphQLPlayground();
endpoints.MapGraphQLGraphiQL();
endpoints.MapGraphQLAltair();
endpoints.MapGraphQLVoyager();
}
UserContext and resolvers
UserContext of your resolver will be type of MessageHandlingContext. You can
access the properties including your actual UserContext by using the
Get<YourContextType>("UserContext") method. This will read the context from the properties of
MessageHandlingContext. You can add any other properties as to the context in
IOperationMessageListeners. See the sample for example of injecting ClaimsPrincipal.
Sample
Samples.Server shows a simple Chat example demonstrating the subscription transport.
It supports various GraphQL client IDEs (by default opening GraphQL Playground).
Here are some example queries to get started. Use three browser tabs or better yet windows
to view the changes.
Subscription 1
Query:
subscription MessageAddedByUser($id:String!) {
messageAddedByUser(id: $id) {
from { id displayName }
content
}
}
Variables:
{
"id": "1"
}
Subscription 2
subscription MessageAdded {
messageAdded {
from { id displayName }
content
}
}
Mutation
Query:
mutation AddMessage($message: MessageInputType!) {
addMessage(message: $message) {
from {
id
displayName
}
content
}
}
Variables:
{
"message": {
"content": "Message",
"fromId": "1"
}
}
API changes
You can see the changes in public APIs using fuget.org.