Skip to content

Commit 420e3da

Browse files
committed
Add GraphQL Playground extension point
1 parent 09ea3aa commit 420e3da

File tree

5 files changed

+78
-55
lines changed

5 files changed

+78
-55
lines changed

src/Our.Umbraco.GraphQL/CompositionExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public static void RegisterGraphQLServices(this Composition composition)
1919
composition.Register<IDocumentExecuter, DocumentExecuter>(Lifetime.Singleton);
2020
composition.Register<IDocumentWriter, DocumentWriter>(Lifetime.Singleton);
2121

22-
composition.Register<GraphQLPlaygroundMiddleware>(Lifetime.Singleton);
22+
composition.Register<GraphQLPlaygroundMiddleware>(Lifetime.Scope);
2323
composition.Register<GraphQLRequestParserMiddleware>(Lifetime.Singleton);
2424
composition.Register<GraphQLMiddleware>(Lifetime.Singleton);
2525

Original file line numberDiff line numberDiff line change
@@ -1,54 +1,66 @@
11
<!DOCTYPE html>
2+
23
<html>
34

45
<head>
5-
<meta charset=utf-8/>
6-
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
7-
<title>GraphQL Playground</title>
8-
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/css/index.css" />
9-
<link rel="shortcut icon" href="//cdn.jsdelivr.net/npm/graphql-playground-react/build/favicon.png" />
10-
<script src="//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/js/middleware.js"></script>
6+
<meta charset="utf-8" />
7+
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
8+
<title>GraphQL Playground</title>
9+
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/css/index.css" />
10+
<link rel="shortcut icon" href="//cdn.jsdelivr.net/npm/graphql-playground-react/build/favicon.png" />
11+
<script src="//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/js/middleware.js"></script>
12+
1113
</head>
1214

1315
<body>
14-
<div id="root">
15-
<style>
16-
body {
17-
background-color: rgb(23, 42, 58);
18-
font-family: Open Sans, sans-serif;
19-
height: 90vh;
20-
}
21-
#root {
22-
height: 100%;
23-
width: 100%;
24-
display: flex;
25-
align-items: center;
26-
justify-content: center;
27-
}
28-
.loading {
29-
font-size: 32px;
30-
font-weight: 200;
31-
color: rgba(255, 255, 255, .6);
32-
margin-left: 20px;
33-
}
34-
img {
35-
width: 78px;
36-
height: 78px;
37-
}
38-
.title {
39-
font-weight: 400;
40-
}
41-
</style>
42-
<img src='//cdn.jsdelivr.net/npm/graphql-playground-react/build/logo.png' alt=''>
43-
<div class="loading"> Loading
44-
<span class="title">GraphQL Playground</span>
45-
</div>
46-
</div>
47-
<script>window.addEventListener('load', function (event) {
48-
GraphQLPlayground.init(document.getElementById('root'), {
49-
// options as 'endpoint' belong here
50-
})
51-
})</script>
52-
</body>
16+
<div id="root">
17+
<style>
18+
body {
19+
background-color: rgb(23, 42, 58);
20+
font-family: Open Sans, sans-serif;
21+
height: 90vh;
22+
}
23+
24+
#root {
25+
height: 100%;
26+
width: 100%;
27+
display: flex;
28+
align-items: center;
29+
justify-content: center;
30+
}
5331

32+
.loading {
33+
font-size: 32px;
34+
font-weight: 200;
35+
color: rgba(255, 255, 255, .6);
36+
margin-left: 20px;
37+
}
38+
39+
img {
40+
width: 78px;
41+
height: 78px;
42+
}
43+
44+
.title {
45+
font-weight: 400;
46+
}
47+
</style>
48+
<img src='//cdn.jsdelivr.net/npm/graphql-playground-react/build/logo.png' alt=''>
49+
<div class="loading">
50+
Loading
51+
<span class="title">GraphQL Playground</span>
52+
</div>
53+
</div>
54+
<script>
55+
window.addEventListener('load', function (event) {
56+
GraphQLPlayground.init(document.getElementById('root'), {
57+
setTitle: true,
58+
endpoint: window.location.protocol + "//" + window.location.host + "{{GraphQLEndPoint}}",
59+
subscriptionEndpoint: (window.location.protocol === "http:" ? "ws://" : "wss://") + window.location.host + "{{GraphQLEndPoint}}",
60+
config: {{GraphQLConfig}},
61+
settings: {{PlaygroundSettings}}
62+
});
63+
});
64+
</script>
65+
</body>
5466
</html>

src/Our.Umbraco.GraphQL/Web/AppBuilderExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static IAppBuilder UseUmbracoGraphQL(this IAppBuilder app, string rootPat
2929

3030
subApp.UseCors(corsOptions)
3131
.Use<FactoryMiddleware>(factory)
32-
.Use((ctx, next) => ctx.Get<IFactory>("umbraco:factory").GetInstance<GraphQLPlaygroundMiddleware>().Invoke(ctx, next))
32+
.Use((ctx, next) => options.EnablePlayground ? ctx.Get<IFactory>("umbraco:factory").CreateInstance<GraphQLPlaygroundMiddleware>(options).Invoke(ctx, next) : next())
3333
.Use((ctx, next) => ctx.Get<IFactory>("umbraco:factory").GetInstance<GraphQLRequestParserMiddleware>().Invoke(ctx, next))
3434
.Use((ctx, next) => ctx.Get<IFactory>("umbraco:factory").GetInstance<GraphQLMiddleware>().Invoke(ctx, options));
3535
});

src/Our.Umbraco.GraphQL/Web/GraphQLServerOptions.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
using System;
1+
using System.Collections.Generic;
22
using System.Web.Cors;
33
using Microsoft.Owin.Cors;
4-
using Umbraco.Core.Models;
54
using Task = System.Threading.Tasks.Task;
65

76
namespace Our.Umbraco.GraphQL.Web
@@ -46,9 +45,10 @@ public GraphQLServerOptions(ICorsPolicyProvider corsPolicyProvder)
4645
public ICorsPolicyProvider CorsPolicyProvder { get; }
4746
//public ComplexityConfiguration ComplexityConfiguration { get; set; }
4847
public bool Debug { get; set; }
49-
//public bool ExposeGraphiQL { get; set; } = true;
5048
//public bool EnableLogin { get; set; } = false;
5149
public bool EnableMetrics { get; set; } = false;
52-
//public bool ExposeSchema { get; set; } = true;
50+
public bool EnablePlayground { get; set; } = false;
51+
public Dictionary<string, object> GraphQLConfig { get; set; }
52+
public Dictionary<string, object> PlaygroundSettings { get; set; }
5353
}
5454
}

src/Our.Umbraco.GraphQL/Web/Middleware/GraphQLPlaygroundMiddleware.cs

+15-4
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,41 @@
22
using System;
33
using System.IO;
44
using System.Threading.Tasks;
5+
using Newtonsoft.Json;
56

67
namespace Our.Umbraco.GraphQL.Web.Middleware
78
{
89
internal class GraphQLPlaygroundMiddleware
910
{
10-
private readonly string _html;
11+
private static readonly string Html;
12+
private readonly GraphQLServerOptions _options;
1113

12-
public GraphQLPlaygroundMiddleware()
14+
static GraphQLPlaygroundMiddleware()
1315
{
1416
using (var stream = typeof(AppBuilderExtensions).Assembly.GetManifestResourceStream("Our.Umbraco.GraphQL.Resources.playground.html"))
1517
{
1618
using (var reader = new StreamReader(stream))
1719
{
18-
_html = reader.ReadToEnd(); //.Replace("${endpointURL}", graphQLPath);
20+
Html = reader.ReadToEnd();
1921
}
2022
}
2123
}
2224

25+
public GraphQLPlaygroundMiddleware(GraphQLServerOptions options)
26+
{
27+
_options = options ?? throw new ArgumentNullException(nameof(options));
28+
}
29+
2330
public async Task Invoke(IOwinContext context, Func<Task> next)
2431
{
2532
if (context.Request.Method == "GET")
2633
{
2734
context.Response.ContentType = "text/html";
28-
await context.Response.WriteAsync(_html);
35+
await context.Response.WriteAsync(
36+
Html.Replace("{{GraphQLEndPoint}}", context.Request.Uri.LocalPath)
37+
.Replace("{{GraphQLConfig}}", JsonConvert.SerializeObject(_options.GraphQLConfig))
38+
.Replace("{{PlaygroundSettings}}", JsonConvert.SerializeObject(_options.PlaygroundSettings))
39+
);
2940
}
3041
else
3142
{

0 commit comments

Comments
 (0)