Created
May 5, 2018 13:58
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
* 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… | |
</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