package gql import ( "html/template" "net/http" ) // GraphiQL is an in-browser IDE for exploring GraphiQL APIs. // This handler returns GraphiQL when requested. // // For more information, see https://github.com/graphql/graphiql. func PlaygroundHandler(apiURL string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { http.Error(w, "only GET requests are supported", http.StatusMethodNotAllowed) return } w.Header().Set("Content-Type", "text/html") err := page.Execute(w, map[string]interface{}{ "apiURL": apiURL, }) if err != nil { panic(err) } } } // https://github.com/graphql/graphiql/blob/main/examples/graphiql-cdn/index.html var page = template.Must(template.New("graphiql").Parse(` <!DOCTYPE html> <html lang="en"> <head> <title>GraphiQL</title> <style> body { height: 100%; margin: 0; width: 100%; overflow: hidden; } #graphiql { height: 100vh; } </style> <!-- This GraphiQL example depends on Promise and fetch, which are available in modern browsers, but can be "polyfilled" for older browsers. GraphiQL itself depends on React DOM. If you do not want to rely on a CDN, you can host these files locally or include them directly in your favored resource bundler. --> <script src="https://unpkg.com/react@17/umd/react.development.js" integrity="sha512-Vf2xGDzpqUOEIKO+X2rgTLWPY+65++WPwCHkX2nFMu9IcstumPsf/uKKRd5prX3wOu8Q0GBylRpsDB26R6ExOg==" crossorigin="anonymous" ></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" integrity="sha512-Wr9OKCTtq1anK0hq5bY3X/AvDI5EflDSAh0mE9gma+4hl+kXdTJPKZ3TwLMBcrgUeoY0s3dq9JjhCQc7vddtFg==" crossorigin="anonymous" ></script> <!-- These two files can be found in the npm module, however you may wish to copy them directly into your environment, or perhaps include them in your favored resource bundler. --> <link rel="stylesheet" href="https://unpkg.com/graphiql/graphiql.min.css" /> </head> <body> <div id="graphiql">Loading...</div> <script src="https://unpkg.com/graphiql/graphiql.min.js" type="application/javascript" ></script> <script> // https://github.com/graphql/graphiql/blob/main/packages/graphiql/resources/renderExample.js // Parse the search string to get url parameters. var search = window.location.search; var parameters = {}; search .substr(1) .split('&') .forEach(function (entry) { var eq = entry.indexOf('='); if (eq >= 0) { parameters[decodeURIComponent(entry.slice(0, eq))] = decodeURIComponent( entry.slice(eq + 1), ); } }); // When the query and variables string is edited, update the URL bar so // that it can be easily shared. function onEditQuery(newQuery) { parameters.query = newQuery; updateURL(); } function onEditVariables(newVariables) { parameters.variables = newVariables; updateURL(); } function onEditHeaders(newHeaders) { parameters.headers = newHeaders; updateURL(); } function onTabChange(tabsState) { const activeTab = tabsState.tabs[tabsState.activeTabIndex]; parameters.query = activeTab.query; parameters.variables = activeTab.variables; parameters.headers = activeTab.headers; updateURL(); } function updateURL() { var newSearch = '?' + Object.keys(parameters) .filter(function (key) { return Boolean(parameters[key]); }) .map(function (key) { return ( encodeURIComponent(key) + '=' + encodeURIComponent(parameters[key]) ); }) .join('&'); history.replaceState(null, null, newSearch); } // Render <GraphiQL /> into the body. // See the README in the top level of this module to learn more about // how you can customize GraphiQL by providing different values or // additional child elements. ReactDOM.render( React.createElement(GraphiQL, { fetcher: GraphiQL.createFetcher({ url: {{.apiURL}} }), query: parameters.query, variables: parameters.variables, headers: parameters.headers, defaultHeaders: parameters.defaultHeaders, onEditQuery: onEditQuery, onEditVariables: onEditVariables, onEditHeaders: onEditHeaders, defaultEditorToolsVisibility: true, isHeadersEditorEnabled: true, shouldPersistHeaders: true, onTabChange, }), document.getElementById('graphiql'), ); </script> </body> </html> `))