Skip to content

Commit

Permalink
Add a .NET Core middleware example
Browse files Browse the repository at this point in the history
Issue: #338
  • Loading branch information
joemcbride committed Jul 7, 2017
1 parent e982fd4 commit 93a5c71
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 1 deletion.
20 changes: 20 additions & 0 deletions src/GraphQL.GraphiQLCore/GraphQL.GraphiQLCore.csproj
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\GraphQL\GraphQL.csproj" />
<ProjectReference Include="..\GraphQL.StarWars\GraphQL.StarWars.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
</ItemGroup>

<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>

</Project>
79 changes: 79 additions & 0 deletions src/GraphQL.GraphiQLCore/GraphQLMiddleware.cs
@@ -0,0 +1,79 @@
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using GraphQL.Http;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;

namespace GraphQL.GraphiQLCore
{
public class GraphQLMiddleware
{
private readonly RequestDelegate _next;
private readonly GraphQLSettings _settings;
private readonly IDocumentExecuter _executer;
private readonly IDocumentWriter _writer;

public GraphQLMiddleware(
RequestDelegate next,
GraphQLSettings settings,
IDocumentExecuter executer,
IDocumentWriter writer)
{
_next = next;
_settings = settings;
_executer = executer;
_writer = writer;
}

public async Task Invoke(HttpContext context)
{
if (!IsGraphQLRequest(context))
{
await _next(context).ConfigureAwait(false);
return;
}

await ExecuteAsync(context);
}

private bool IsGraphQLRequest(HttpContext context)
{
return context.Request.Path.StartsWithSegments(_settings.Path)
&& string.Equals(context.Request.Method, "POST", StringComparison.OrdinalIgnoreCase);
}

private async Task ExecuteAsync(HttpContext context)
{
string body;
using (var streamReader = new StreamReader(context.Request.Body))
{
body = await streamReader.ReadToEndAsync().ConfigureAwait(true);
}

var request = JsonConvert.DeserializeObject<GraphQLRequest>(body);

var result = await _executer.ExecuteAsync(_ =>
{
_.Schema = _settings.Schema;
_.Query = request.Query;
_.OperationName = request.OperationName;
_.Inputs = request.Variables.ToInputs();
});

await WriteResponseAsync(context, result);
}

private async Task WriteResponseAsync(HttpContext context, ExecutionResult result)
{
var json = _writer.Write(result);

context.Response.ContentType = "application/json";
context.Response.StatusCode = result.Errors?.Any() == true ? (int)HttpStatusCode.BadRequest : (int)HttpStatusCode.OK;

await context.Response.WriteAsync(json);
}
}
}
9 changes: 9 additions & 0 deletions src/GraphQL.GraphiQLCore/GraphQLRequest.cs
@@ -0,0 +1,9 @@
namespace GraphQL.GraphiQLCore
{
public class GraphQLRequest
{
public string OperationName { get; set; }
public string Query { get; set; }
public string Variables { get; set; }
}
}
11 changes: 11 additions & 0 deletions src/GraphQL.GraphiQLCore/GraphQLSettings.cs
@@ -0,0 +1,11 @@
using GraphQL.Types;
using Microsoft.AspNetCore.Http;

namespace GraphQL.GraphiQLCore
{
public class GraphQLSettings
{
public PathString Path { get; set; } = "/graphql";
public ISchema Schema { get; set; }
}
}
20 changes: 20 additions & 0 deletions src/GraphQL.GraphiQLCore/Program.cs
@@ -0,0 +1,20 @@
using System.IO;
using Microsoft.AspNetCore.Hosting;

namespace GraphQL.GraphiQLCore
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();

host.Run();
}
}
}
27 changes: 27 additions & 0 deletions src/GraphQL.GraphiQLCore/Properties/launchSettings.json
@@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:49816/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"GraphQL.GraphiQLCore": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:49817"
}
}
}
42 changes: 42 additions & 0 deletions src/GraphQL.GraphiQLCore/Startup.cs
@@ -0,0 +1,42 @@
using GraphQL.Http;
using GraphQL.StarWars;
using GraphQL.StarWars.Types;
using GraphQL.Types;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace GraphQL.GraphiQLCore
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IDocumentExecuter, DocumentExecuter>();
services.AddSingleton<IDocumentWriter, DocumentWriter>();

services.AddSingleton<StarWarsData>();
services.AddSingleton<StarWarsQuery>();
services.AddSingleton<HumanType>();
services.AddSingleton<DroidType>();
services.AddSingleton<CharacterInterface>();
services.AddSingleton<ISchema>(s => new StarWarsSchema(type => (GraphType) s.GetService(type)));
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();

if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseMiddleware<GraphQLMiddleware>(new GraphQLSettings
{
Schema = app.ApplicationServices.GetService<ISchema>()
});
}
}
}
15 changes: 14 additions & 1 deletion src/GraphQL.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26403.3
VisualStudioVersion = 15.0.26430.6
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C1C3FFFD-3369-42B1-BE2E-CA10AD9E2ADA}"
ProjectSection(SolutionItems) = preProject
Expand All @@ -19,6 +19,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphQL.StarWars", "GraphQL
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphQL.Tests", "GraphQL.Tests\GraphQL.Tests.csproj", "{65E750AC-4701-45A8-97C0-822B1CC42C1E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphQL.GraphiQLCore", "GraphQL.GraphiQLCore\GraphQL.GraphiQLCore.csproj", "{487A7A85-31E1-4B1E-BAAA-F8E723AFEE89}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{F515FCA3-BD5F-485A-8BDE-E3E5E1FE33B6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -41,8 +45,17 @@ Global
{65E750AC-4701-45A8-97C0-822B1CC42C1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65E750AC-4701-45A8-97C0-822B1CC42C1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65E750AC-4701-45A8-97C0-822B1CC42C1E}.Release|Any CPU.Build.0 = Release|Any CPU
{487A7A85-31E1-4B1E-BAAA-F8E723AFEE89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{487A7A85-31E1-4B1E-BAAA-F8E723AFEE89}.Debug|Any CPU.Build.0 = Debug|Any CPU
{487A7A85-31E1-4B1E-BAAA-F8E723AFEE89}.Release|Any CPU.ActiveCfg = Release|Any CPU
{487A7A85-31E1-4B1E-BAAA-F8E723AFEE89}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{EE557888-1CD2-4E87-BD87-06834C988B23} = {F515FCA3-BD5F-485A-8BDE-E3E5E1FE33B6}
{AE243087-3A7F-4BB3-9CE7-D95B2379C397} = {F515FCA3-BD5F-485A-8BDE-E3E5E1FE33B6}
{487A7A85-31E1-4B1E-BAAA-F8E723AFEE89} = {F515FCA3-BD5F-485A-8BDE-E3E5E1FE33B6}
EndGlobalSection
EndGlobal

0 comments on commit 93a5c71

Please sign in to comment.