Skip to content

Commit 3faa1ac

Browse files
connorsheaacao
andauthored
feat: Add Headers Editor to GraphiQL (#1543)
Co-authored-by: Rikki Schulte <[email protected]>
1 parent 4d79f2c commit 3faa1ac

File tree

12 files changed

+607
-52
lines changed

12 files changed

+607
-52
lines changed

packages/graphiql/README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ GraphiQL supports customization in UI and behavior by accepting React props and
167167

168168
- `variables`: an optional GraphQL string to use as the initial displayed query variables, if `undefined` is provided, the stored variables will be used.
169169

170+
- `headers`: an optional GraphQL string to use as the initial displayed request headers, if `undefined` is provided, the stored headers will be used.
171+
170172
- `operationName`: an optional name of which GraphQL operation should be executed.
171173

172174
- `response`: an optional JSON string to use as the initial displayed response. If not provided, no response will be initially shown. You might provide this if illustrating the result of the initial query.
@@ -175,12 +177,16 @@ GraphiQL supports customization in UI and behavior by accepting React props and
175177

176178
- `defaultQuery`: an optional GraphQL string to use when no query is provided and no stored query exists from a previous session. If `undefined` is provided, GraphiQL will use its own default query.
177179

178-
- `defaultVariableEditorOpen`: an optional boolean that sets whether or not to show the variables pane on startup. If not defined, it will be based off whether or not variables are present.
180+
- `defaultVariableEditorOpen`: an optional boolean that sets whether or not to show the variables pane on startup. If not defined, it will be based off whether or not variables are present. (**deprecated** in favor of `defaultSecondaryEditorOpen`)
181+
182+
- `defaultSecondaryEditorOpen`: an optional boolean that sets whether or not to show the variables/headers pane on startup. If not defined, it will be based off whether or not variables and/or headers are present.
179183

180184
- `onEditQuery`: an optional function which will be called when the Query editor changes. The argument to the function will be the query string.
181185

182186
- `onEditVariables`: an optional function which will be called when the Query variable editor changes. The argument to the function will be the variables string.
183187

188+
- `onEditHeaders`: an optional function which will be called when the request headers editor changes. The argument to the function will be the headers string.
189+
184190
- `onEditOperationName`: an optional function which will be called when the operation name to be executed changes.
185191

186192
- `onToggleDocs`: an optional function which will be called when the docs will be toggled. The argument to the function will be a boolean whether the docs are now open or closed.
@@ -193,6 +199,8 @@ GraphiQL supports customization in UI and behavior by accepting React props and
193199

194200
- `docExplorerOpen`: an optional boolean which when `true` will ensure the `DocExplorer` is open by default when the user first renders the component. If the user has toggled the doc explorer on/off following this, however, the persisted UI state will override this default flag.
195201

202+
- `headerEditorEnabled`: an optional boolean which enables the header editor when `true`. Defaults to `false`.
203+
196204
### Children (dropped as of 1.0.0-rc.2)
197205

198206
- `<GraphiQL.Logo>`: Replace the GraphiQL logo with your own.
@@ -236,6 +244,7 @@ class CustomGraphiQL extends React.Component {
236244
// GraphQL artifacts
237245
query: '',
238246
variables: '',
247+
headers: '',
239248
response: '',
240249

241250
// GraphQL Schema
@@ -252,6 +261,7 @@ class CustomGraphiQL extends React.Component {
252261
// Custom Event Handlers
253262
onEditQuery: null,
254263
onEditVariables: null,
264+
onEditHeaders: null,
255265
onEditOperationName: null,
256266

257267
// GraphiQL automatically fills in leaf nodes when the query

packages/graphiql/resources/renderExample.js

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,20 @@ if (parameters.variables) {
3636
}
3737
}
3838

39+
// If headers was provided, try to format it.
40+
if (parameters.headers) {
41+
try {
42+
parameters.headers = JSON.stringify(
43+
JSON.parse(parameters.headers),
44+
null,
45+
2,
46+
);
47+
} catch (e) {
48+
// Do nothing, we want to display the invalid JSON as a string, rather
49+
// than present an error.
50+
}
51+
}
52+
3953
// When the query and variables string is edited, update the URL bar so
4054
// that it can be easily shared.
4155
function onEditQuery(newQuery) {
@@ -48,6 +62,11 @@ function onEditVariables(newVariables) {
4862
updateURL();
4963
}
5064

65+
function onEditHeaders(newHeaders) {
66+
parameters.headers = newHeaders;
67+
updateURL();
68+
}
69+
5170
function onEditOperationName(newOperationName) {
5271
parameters.operationName = newOperationName;
5372
updateURL();
@@ -72,20 +91,30 @@ function updateURL() {
7291
// Defines a GraphQL fetcher using the fetch API. You're not required to
7392
// use fetch, and could instead implement graphQLFetcher however you like,
7493
// as long as it returns a Promise or Observable.
75-
function graphQLFetcher(graphQLParams) {
94+
function graphQLFetcher(graphQLParams, opts = { headers: {} }) {
7695
// When working locally, the example expects a GraphQL server at the path /graphql.
7796
// In a PR preview, it connects to the Star Wars API externally.
7897
// Change this to point wherever you host your GraphQL server.
7998
const isDev = window.location.hostname.match(/localhost$/);
8099
const api = isDev
81100
? '/graphql'
82101
: 'https://swapi-graphql.netlify.app/.netlify/functions/index';
102+
103+
let headers = opts.headers;
104+
// Convert headers to an object.
105+
if (typeof headers === 'string') {
106+
headers = JSON.parse(opts.headers);
107+
}
108+
83109
return fetch(api, {
84110
method: 'post',
85-
headers: {
86-
Accept: 'application/json',
87-
'Content-Type': 'application/json',
88-
},
111+
headers: Object.assign(
112+
{
113+
Accept: 'application/json',
114+
'Content-Type': 'application/json',
115+
},
116+
headers,
117+
),
89118
body: JSON.stringify(graphQLParams),
90119
credentials: 'omit',
91120
})
@@ -110,11 +139,14 @@ ReactDOM.render(
110139
fetcher: graphQLFetcher,
111140
query: parameters.query,
112141
variables: parameters.variables,
142+
headers: parameters.headers,
113143
operationName: parameters.operationName,
114144
onEditQuery: onEditQuery,
115145
onEditVariables: onEditVariables,
146+
onEditHeaders: onEditHeaders,
116147
defaultVariableEditorOpen: true,
117148
onEditOperationName: onEditOperationName,
149+
headerEditorEnabled: true,
118150
}),
119151
document.getElementById('graphiql'),
120152
);

0 commit comments

Comments
 (0)