├── .gitignore
├── GraphQL.Middleware.xproj
├── GraphQL.Middleware.xproj.user
├── GraphQLMiddleware.cs
├── GraphQLOptions.cs
├── GraphQLRequest.cs
├── GraphiQLMiddleware.cs
├── GraphiQLOptions.cs
├── IApplicationBuilderExtensions.cs
├── LICENSE
├── README.md
├── project.json
└── project.lock.json
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | bin
--------------------------------------------------------------------------------
/GraphQL.Middleware.xproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 14.0
5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
6 |
7 |
8 |
9 |
10 | 9f18d386-a242-4696-97f1-20a892540ce4
11 | GraphQL.Middleware
12 | .\obj
13 | .\bin\
14 | v4.5.2
15 |
16 |
17 |
18 | 2.0
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/GraphQL.Middleware.xproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Start
5 |
6 |
--------------------------------------------------------------------------------
/GraphQLMiddleware.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Threading.Tasks;
4 | using GraphQL.Http;
5 | using GraphQL.Types;
6 | using Microsoft.AspNetCore.Http;
7 | using Microsoft.Extensions.Options;
8 | using Newtonsoft.Json;
9 |
10 | namespace GraphQL.Middleware
11 | {
12 | ///
13 | /// Provides middleware for hosting GraphQL.
14 | ///
15 | public sealed class GraphQLMiddleware
16 | {
17 | private readonly string graphqlPath;
18 | private readonly RequestDelegate next;
19 | private readonly ISchema schema;
20 |
21 | ///
22 | /// Initializes a new instance of the class.
23 | ///
24 | ///
25 | /// The next request delegate.
26 | ///
27 | ///
28 | /// The GraphQL options.
29 | ///
30 | ///
31 | /// Throws if or is null.
32 | ///
33 | public GraphQLMiddleware(RequestDelegate next , IOptions options)
34 | {
35 | if (next == null)
36 | {
37 | throw new ArgumentNullException(nameof(next));
38 | }
39 | if (options == null)
40 | {
41 | throw new ArgumentNullException(nameof(options));
42 | }
43 | if (options.Value?.Schema == null)
44 | {
45 | throw new ArgumentException("Schema is null");
46 | }
47 |
48 | this.next = next;
49 | var optionsValue = options.Value;
50 | graphqlPath = string.IsNullOrEmpty(optionsValue?.GraphQLPath) ? GraphQLOptions.DefaultGraphQLPath : optionsValue.GraphQLPath;
51 | schema = optionsValue?.Schema;
52 | }
53 |
54 | ///
55 | /// Invokes the middleware with the specified context.
56 | ///
57 | ///
58 | /// The context.
59 | ///
60 | ///
61 | /// A representing the middleware invocation.
62 | ///
63 | ///
64 | /// Throws if .
65 | ///
66 | public async Task Invoke(HttpContext context)
67 | {
68 | if (context == null)
69 | {
70 | throw new ArgumentNullException(nameof(context));
71 | }
72 |
73 | if (ShouldRespondToRequest(context.Request))
74 | {
75 | var executionResult = await ExecuteAsync(context.Request).ConfigureAwait(true);
76 | await WriteResponseAsync(context.Response , executionResult).ConfigureAwait(true);
77 | return;
78 | }
79 |
80 | await next(context).ConfigureAwait(true);
81 | }
82 |
83 | private async Task ExecuteAsync(HttpRequest request)
84 | {
85 | string requestBodyText;
86 | using (var streamReader = new StreamReader(request.Body))
87 | {
88 | requestBodyText = await streamReader.ReadToEndAsync().ConfigureAwait(true);
89 | }
90 | var graphqlRequest = JsonConvert.DeserializeObject(requestBodyText);
91 | return await new DocumentExecuter().ExecuteAsync(schema , null , graphqlRequest.Query , graphqlRequest.OperationName , graphqlRequest.Variables.ToInputs()).ConfigureAwait(true);
92 | }
93 |
94 | private bool ShouldRespondToRequest(HttpRequest request)
95 | {
96 | bool a = string.Equals(request.Method , "POST" , StringComparison.OrdinalIgnoreCase);
97 | bool b = request.Path.Equals(graphqlPath);
98 | return a && b;
99 | }
100 |
101 | private static Task WriteResponseAsync(HttpResponse response , ExecutionResult executionResult)
102 | {
103 | response.ContentType = "application/json";
104 | response.StatusCode = (executionResult.Errors?.Count ?? 0) == 0 ? 200 : 400;
105 | var graphqlResponse = new DocumentWriter().Write(executionResult);
106 | return response.WriteAsync(graphqlResponse);
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/GraphQLOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using GraphQL.Types;
6 |
7 | namespace GraphQL.Middleware
8 | {
9 | ///
10 | /// Options for the .
11 | ///
12 | public sealed class GraphQLOptions
13 | {
14 | ///
15 | /// The default GraphQL path.
16 | ///
17 | public const string DefaultGraphQLPath = "/graphql";
18 |
19 | ///
20 | /// Create an instance with the default options settings.
21 | ///
22 | public GraphQLOptions()
23 | {
24 | GraphQLPath = DefaultGraphQLPath;
25 | }
26 |
27 | ///
28 | /// Provides the path to GraphQL endpoint.
29 | ///
30 | ///
31 | /// Include leading forward slash. Defaults to "/graphql".
32 | ///
33 | public string GraphQLPath { get; set; }
34 |
35 | ///
36 | /// Provides the schema instance.
37 | ///
38 | public ISchema Schema { get; set; }
39 | }
40 |
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/GraphQLRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace GraphQL.Middleware
7 | {
8 | internal sealed class GraphQLRequest
9 | {
10 | public string OperationName { get; set; }
11 |
12 | public string Query { get; set; }
13 |
14 | public string Variables { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/GraphiQLMiddleware.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore.Http;
7 | using Microsoft.Extensions.Options;
8 |
9 | namespace GraphQL.Middleware
10 | {
11 | ///
12 | /// Provides middleware to display GraphiQL.
13 | ///
14 | public sealed class GraphiQLMiddleware
15 | {
16 | private static readonly string Template = ReadTemplate();
17 | private readonly string graphiqlPath;
18 | private readonly string graphqlPath;
19 | private readonly RequestDelegate next;
20 |
21 | ///
22 | /// Initializes a new instance of the class.
23 | ///
24 | ///
25 | /// The next request delegate.
26 | ///
27 | ///
28 | /// The GraphiQL options.
29 | ///
30 | ///
31 | /// Throws if or is null.
32 | ///
33 | public GraphiQLMiddleware(RequestDelegate next , IOptions options)
34 | {
35 | if (next == null)
36 | {
37 | throw new ArgumentNullException(nameof(next));
38 | }
39 | if (options == null)
40 | {
41 | throw new ArgumentNullException(nameof(options));
42 | }
43 |
44 | this.next = next;
45 | var optionsValue = options.Value;
46 | graphiqlPath = string.IsNullOrEmpty(optionsValue?.GraphiQLPath) ? GraphiQLOptions.DefaultGraphiQLPath : optionsValue.GraphiQLPath;
47 | graphqlPath = string.IsNullOrEmpty(optionsValue?.GraphQLPath) ? GraphiQLOptions.DefaultGraphQLPath : optionsValue.GraphQLPath;
48 | }
49 |
50 | ///
51 | /// Invokes the middleware with the specified context.
52 | ///
53 | ///
54 | /// The context.
55 | ///
56 | ///
57 | /// A representing the middleware invocation.
58 | ///
59 | ///
60 | /// Throws if .
61 | ///
62 | public async Task Invoke(HttpContext context)
63 | {
64 | if (context == null)
65 | {
66 | throw new ArgumentNullException(nameof(context));
67 | }
68 |
69 | if (ShouldRespondToRequest(context.Request))
70 | {
71 | await WriteResponseAsync(context.Response).ConfigureAwait(true);
72 | return;
73 | }
74 |
75 | await next(context).ConfigureAwait(true);
76 | }
77 |
78 | private static string ReadTemplate()
79 | {
80 | return @"
81 |
89 |
90 |
91 |
92 |
104 | GraphiQL
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | Loading...
113 |
199 |
200 |
201 | ";
202 | //var assembly = typeof(IApplicationBuilderExtensions).GetTypeInfo().Assembly;
203 | //var a = assembly.GetManifestResourceNames();
204 | //using (var stream = assembly.GetManifestResourceStream("index.html"))
205 | //using (var streamReader = new StreamReader(stream , Encoding.UTF8))
206 | //{
207 | // return streamReader.ReadToEnd();
208 | //}
209 | }
210 |
211 | private bool ShouldRespondToRequest(HttpRequest request)
212 | {
213 | return string.Equals(request.Method , "GET" , StringComparison.OrdinalIgnoreCase) && request.Path.Equals(graphiqlPath);
214 | }
215 |
216 | private Task WriteResponseAsync(HttpResponse response)
217 | {
218 | response.ContentType = "text/html";
219 | response.StatusCode = 200;
220 |
221 | // TODO: use RazorPageGenerator when ASP.NET Core 1.1 is out...?
222 | var builder = new StringBuilder(Template);
223 | builder.Replace("@{GraphQLPath}" , graphqlPath);
224 |
225 | var data = Encoding.UTF8.GetBytes(builder.ToString());
226 | return response.Body.WriteAsync(data , 0 , data.Length);
227 | }
228 | }
229 | }
230 |
--------------------------------------------------------------------------------
/GraphiQLOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace GraphQL.Middleware
7 | {
8 | ///
9 | /// Options for the .
10 | ///
11 | public sealed class GraphiQLOptions
12 | {
13 | public const string DefaultGraphiQLPath = "/graphiql";
14 | public const string DefaultGraphQLPath = "/graphql";
15 |
16 | ///
17 | /// Create an instance with the default options settings.
18 | ///
19 | public GraphiQLOptions()
20 | {
21 | GraphiQLPath = DefaultGraphiQLPath;
22 | GraphQLPath = DefaultGraphQLPath;
23 | }
24 |
25 | ///
26 | /// Provides the path to GraphiQL.
27 | ///
28 | ///
29 | /// Include leading forward slash. Defaults to "/graphiql".
30 | ///
31 | public string GraphiQLPath { get; set; }
32 |
33 | ///
34 | /// Provides the path to GraphQL endpoint.
35 | ///
36 | ///
37 | /// Include leading forward slash. Defaults to "/graphql".
38 | ///
39 | public string GraphQLPath { get; set; }
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/IApplicationBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Builder;
6 | //using Microsoft.AspNetCore.Builder;
7 | using Microsoft.Extensions.Options;
8 |
9 | namespace GraphQL.Middleware
10 | {
11 | ///
12 | /// Extension methods for using GraphiQL with .
13 | ///
14 | public static class IApplicationBuilderExtensions
15 | {
16 | ///
17 | /// Uses GraphiQL with the specified options.
18 | ///
19 | ///
20 | /// The application builder.
21 | ///
22 | ///
23 | /// The options for the GraphiQL middleware.
24 | ///
25 | ///
26 | /// The modified application builder.
27 | ///
28 | ///
29 | /// Thrown if or is null.
30 | ///
31 | public static IApplicationBuilder UseGraphQL(this IApplicationBuilder app , GraphQLOptions options)
32 | {
33 | if (app == null)
34 | {
35 | throw new ArgumentNullException(nameof(app));
36 | }
37 | if (options == null)
38 | {
39 | throw new ArgumentNullException(nameof(options));
40 | }
41 | return app.UseMiddleware(Options.Create(options));
42 | }
43 |
44 | ///
45 | /// Uses GraphiQL with default options.
46 | ///
47 | ///
48 | /// The application builder.
49 | ///
50 | ///
51 | /// The modified application builder.
52 | ///
53 | ///
54 | /// Thrown if is null.
55 | ///
56 | public static IApplicationBuilder UseGraphiQL(this IApplicationBuilder app)
57 | {
58 | if (app == null)
59 | {
60 | throw new ArgumentNullException(nameof(app));
61 | }
62 | return app.UseMiddleware();
63 | }
64 |
65 | ///
66 | /// Uses GraphiQL with the specified options.
67 | ///
68 | ///
69 | /// The application builder.
70 | ///
71 | ///
72 | /// The options for the GraphiQL middleware.
73 | ///
74 | ///
75 | /// The modified application builder.
76 | ///
77 | ///
78 | /// Thrown if or is null.
79 | ///
80 | public static IApplicationBuilder UseGraphiQL(this IApplicationBuilder app , GraphiQLOptions options)
81 | {
82 | if (app == null)
83 | {
84 | throw new ArgumentNullException(nameof(app));
85 | }
86 | if (options == null)
87 | {
88 | throw new ArgumentNullException(nameof(options));
89 | }
90 | return app.UseMiddleware(Options.Create(options));
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Wesam
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ASP.Net-Core-GraphQL-Middleware
2 | ASP.Net Core GraphQL Middleware
3 |
4 | usage:
5 | in your Startup.cs in the Configure() Method
6 |
7 | ```cs
8 | app.UseGraphQL(new GraphQLOptions
9 | {
10 | GraphQLPath = "/graphql" ,
11 | Schema = new Schema { Query = new StarWarsQuery() }
12 | });
13 |
14 | app.UseGraphiQL(new GraphiQLOptions()
15 | {
16 | GraphiQLPath = "/graphiql"
17 | });
18 |
19 | ```
--------------------------------------------------------------------------------
/project.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0-*",
3 |
4 | "dependencies": {
5 | "Microsoft.AspNetCore.Http.Abstractions": "1.1.0-alpha1-22011",
6 | "Microsoft.Extensions.Options": "1.1.0-alpha1-22011",
7 | "NETStandard.Library": "1.6.0",
8 | "Newtonsoft.Json": "9.0.1",
9 | "GraphQL": "0.12.1-alpha-545"
10 | },
11 |
12 | "frameworks": {
13 | "netstandard1.6": {
14 | "imports": "dnxcore50"
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------