...
1 package playground
2
3 import (
4 "html/template"
5 "net/http"
6 "net/url"
7 )
8
9 var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
10 <html>
11 <head>
12 <meta charset="utf-8">
13 <title>{{.title}}</title>
14 <style>
15 body {
16 height: 100%;
17 margin: 0;
18 width: 100%;
19 overflow: hidden;
20 }
21
22 #graphiql {
23 height: 100vh;
24 }
25 </style>
26 <script
27 src="https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js"
28 integrity="{{.reactSRI}}"
29 crossorigin="anonymous"
30 ></script>
31 <script
32 src="https://cdn.jsdelivr.net/npm/react-dom@18.2.0/umd/react-dom.production.min.js"
33 integrity="{{.reactDOMSRI}}"
34 crossorigin="anonymous"
35 ></script>
36 <link
37 rel="stylesheet"
38 href="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.css"
39 integrity="{{.cssSRI}}"
40 crossorigin="anonymous"
41 />
42 </head>
43 <body>
44 <div id="graphiql">Loading...</div>
45
46 <script
47 src="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.js"
48 integrity="{{.jsSRI}}"
49 crossorigin="anonymous"
50 ></script>
51
52 <script>
53 {{- if .endpointIsAbsolute}}
54 const url = {{.endpoint}};
55 const subscriptionUrl = {{.subscriptionEndpoint}};
56 {{- else}}
57 const url = location.protocol + '//' + location.host + {{.endpoint}};
58 const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:';
59 const subscriptionUrl = wsProto + '//' + location.host + {{.endpoint}};
60 {{- end}}
61 {{- if .fetcherHeaders}}
62 const fetcherHeaders = {{.fetcherHeaders}};
63 {{- else}}
64 const fetcherHeaders = undefined;
65 {{- end}}
66 {{- if .uiHeaders}}
67 const uiHeaders = {{.uiHeaders}};
68 {{- else}}
69 const uiHeaders = undefined;
70 {{- end}}
71
72 const fetcher = GraphiQL.createFetcher({ url, subscriptionUrl, headers: fetcherHeaders });
73 ReactDOM.render(
74 React.createElement(GraphiQL, {
75 fetcher: fetcher,
76 isHeadersEditorEnabled: true,
77 shouldPersistHeaders: true,
78 headers: JSON.stringify(uiHeaders, null, 2)
79 }),
80 document.getElementById('graphiql'),
81 );
82 </script>
83 </body>
84 </html>
85 `))
86
87
88 func Handler(title string, endpoint string) http.HandlerFunc {
89 return HandlerWithHeaders(title, endpoint, nil, nil)
90 }
91
92
93
94
95 func HandlerWithHeaders(title string, endpoint string, fetcherHeaders map[string]string, uiHeaders map[string]string) http.HandlerFunc {
96 return func(w http.ResponseWriter, r *http.Request) {
97 w.Header().Add("Content-Type", "text/html; charset=UTF-8")
98 err := page.Execute(w, map[string]interface{}{
99 "title": title,
100 "endpoint": endpoint,
101 "fetcherHeaders": fetcherHeaders,
102 "uiHeaders": uiHeaders,
103 "endpointIsAbsolute": endpointHasScheme(endpoint),
104 "subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
105 "version": "3.0.6",
106 "cssSRI": "sha256-wTzfn13a+pLMB5rMeysPPR1hO7x0SwSeQI+cnw7VdbE=",
107 "jsSRI": "sha256-eNxH+Ah7Z9up9aJYTQycgyNuy953zYZwE9Rqf5rH+r4=",
108 "reactSRI": "sha256-S0lp+k7zWUMk2ixteM6HZvu8L9Eh//OVrt+ZfbCpmgY=",
109 "reactDOMSRI": "sha256-IXWO0ITNDjfnNXIu5POVfqlgYoop36bDzhodR6LW5Pc=",
110 })
111 if err != nil {
112 panic(err)
113 }
114 }
115 }
116
117
118 func endpointHasScheme(endpoint string) bool {
119 u, err := url.Parse(endpoint)
120 return err == nil && u.Scheme != ""
121 }
122
123
124
125 func getSubscriptionEndpoint(endpoint string) string {
126 u, err := url.Parse(endpoint)
127 if err != nil {
128 return ""
129 }
130
131 switch u.Scheme {
132 case "https":
133 u.Scheme = "wss"
134 default:
135 u.Scheme = "ws"
136 }
137
138 return u.String()
139 }
140
View as plain text