github.com/99designs/gqlgen@v0.17.45/graphql/playground/playground.go (about) 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 // Handler responsible for setting up the playground 88 func Handler(title string, endpoint string) http.HandlerFunc { 89 return HandlerWithHeaders(title, endpoint, nil, nil) 90 } 91 92 // HandlerWithHeaders sets up the playground. 93 // fetcherHeaders are used by the playground's fetcher instance and will not be visible in the UI. 94 // uiHeaders are default headers that will show up in the UI headers editor. 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 // endpointHasScheme checks if the endpoint has a scheme. 118 func endpointHasScheme(endpoint string) bool { 119 u, err := url.Parse(endpoint) 120 return err == nil && u.Scheme != "" 121 } 122 123 // getSubscriptionEndpoint returns the subscription endpoint for the given 124 // endpoint if it is parsable as a URL, or an empty string. 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 }