Skip to content

Instantly share code, notes, and snippets.

@diversit
Created May 5, 2018 13:58
Show Gist options
  • Save diversit/6a3d220d498ef12879be37f59a7c50f1 to your computer and use it in GitHub Desktop.
Save diversit/6a3d220d498ef12879be37f59a7c50f1 to your computer and use it in GitHub Desktop.
Single page GraphiQL editor with JWT token and working auto-complete and documentation
<!--
* Copyright (c) Facebook, Inc.
* All rights reserved.
*
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
-->
<!-- Custom graphiql with jwt header
Based on idea: https://gist.github.com/sasso/3c3d728e0049d5b66a2c19b349b7f164
However, there auto-complete and documentation does not work.
Took page source of Grapiql try-out page: http://graphql.org/swapi-graphql/
and:
- copied fetch function from gist page
- added 'jwt-token'
- render graphql in 'div' and not in body otherwise jwt-token is not displayed
- hide splash after loading
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex" />
<meta name="referrer" content="origin" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>SWAPI GraphQL API</title>
<style>
body {
height: 100%;
margin: 0;
overflow: hidden;
}
#splash {
color: #333;
display: flex;
flex-direction: column;
font-family: system, -apple-system, "San Francisco", ".SFNSDisplay-Regular", "Segoe UI", Segoe, "Segoe WP", "Helvetica Neue", helvetica, "Lucida Grande", arial, sans-serif;
height: 100vh;
justify-content: center;
text-align: center;
}
#graphiql {
height: 100vh;
}
.jwt-token {
background: linear-gradient(#f7f7f7, #e2e2e2);
border-bottom: 1px solid #d0d0d0;
font-family: system, -apple-system, 'San Francisco', '.SFNSDisplay-Regular', 'Segoe UI', Segoe, 'Segoe WP', 'Helvetica Neue', helvetica, 'Lucida Grande', arial, sans-serif;
padding: 7px 14px 6px;
font-size: 14px;
}
</style>
<link rel="icon" href="favicon.ico">
<link href="//cdn.jsdelivr.net/npm/[email protected]/graphiql.css" rel="stylesheet" />
</head>
<body>
<div class="jwt-token">JWT Token <input id="jwt-token" placeholder="JWT Token goes here"></div>
<div id="splash">
Loading&hellip;
</div>
<div id="graphiql"></div>
<script src="//cdn.jsdelivr.net/es6-promise/4.0.5/es6-promise.auto.min.js"></script>
<script src="//cdn.jsdelivr.net/react/15.4.2/react.min.js"></script>
<script src="//cdn.jsdelivr.net/react/15.4.2/react-dom.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/[email protected]/graphiql.min.js"></script>
<!--<script src="schema.js"></script>-->
<script>
// Parse the search string to get url parameters.
var search = window.location.search;
var parameters = {};
document.getElementById('jwt-token').value = localStorage.getItem('graphiql:jwtToken');
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));
}
});
// if variables was provided, try to format it.
if (parameters.variables) {
try {
parameters.variables =
JSON.stringify(JSON.parse(parameters.variables), null, 2);
} catch (e) {
// Do nothing, we want to display the invalid JSON as a string, rather
// than present an error.
}
}
// 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 onEditOperationName(newOperationName) {
parameters.operationName = newOperationName;
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);
}
function graphQLFetcher(graphQLParams) {
const jwtToken = document.getElementById('jwt-token').value;
let headers = {
'Accept': 'application/json',
'Content-Type': 'application/json'
};
if (jwtToken) {
localStorage.setItem('graphiql:jwtToken', jwtToken);
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': jwtToken ? `Bearer ${jwtToken}` : null
};
}
return fetch('/graphql', {
method: 'post',
headers,
body: JSON.stringify(graphQLParams),
credentials: 'include',
}).then(function (response) {
// hide splash
document.getElementById('splash').style.display = "none";
return response.text();
}).then(function (responseBody) {
try {
return JSON.parse(responseBody);
} catch (error) {
return responseBody;
}
});
}
// Render <GraphiQL /> into the body.
ReactDOM.render(
React.createElement(GraphiQL, {
fetcher: graphQLFetcher,
query: parameters.query,
// GraphQL Schema
// If `undefined` is provided, an introspection query is executed using the fetcher.
schema: undefined,
variables: parameters.variables,
operationName: parameters.operationName,
onEditQuery: onEditQuery,
onEditVariables: onEditVariables,
onEditOperationName: onEditOperationName
}),
document.getElementById('graphiql'),
);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment