From 49ffbc37162b4accb62d5ab0c1fc2ab52d01033d Mon Sep 17 00:00:00 2001 From: "radoslaw.kowalski" Date: Fri, 31 Jul 2020 16:57:59 +0200 Subject: [PATCH 1/7] Add headers support to GraphiQL * add GRAPHIQL_HEADER_EDITOR_ENABLED setting with False default * use GRAPHIQL_HEADER_EDITOR_ENABLED to set headerEditorEnabled GraphiQL option * update graphQLFetcher and httpClient in static/graphiql.js to support custom query/mutation headers --- graphene_django/settings.py | 4 +++ .../static/graphene_django/graphiql.js | 31 +++++++++++++------ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/graphene_django/settings.py b/graphene_django/settings.py index 52cca8907..4116ee17e 100644 --- a/graphene_django/settings.py +++ b/graphene_django/settings.py @@ -41,6 +41,10 @@ "DJANGO_CHOICE_FIELD_ENUM_CUSTOM_NAME": None, # Use a separate path for handling subscriptions. "SUBSCRIPTION_PATH": None, + # Set to True to enable GraphiQL headers editor tab + # This sets headerEditorEnabled GraphiQL option, for details go to + # https://github.com/graphql/graphiql/tree/main/packages/graphiql#options + "GRAPHIQL_HEADER_EDITOR_ENABLED": False, } if settings.DEBUG: diff --git a/graphene_django/static/graphene_django/graphiql.js b/graphene_django/static/graphene_django/graphiql.js index 45f8ad741..fb878ae30 100644 --- a/graphene_django/static/graphene_django/graphiql.js +++ b/graphene_django/static/graphene_django/graphiql.js @@ -61,17 +61,29 @@ var fetchURL = locationQuery(otherParams); // Defines a GraphQL fetcher using the fetch API. - function httpClient(graphQLParams) { - var headers = { - Accept: "application/json", - "Content-Type": "application/json", - }; + function httpClient(graphQLParams, opts = { headers: {} }) { + let headers = opts.headers; + // Convert headers to an object. + if (typeof headers === 'string') { + headers = JSON.parse(opts.headers); + } if (csrftoken) { - headers["X-CSRFToken"] = csrftoken; + Object.assign( + { + 'X-CSRFToken': csrftoken + }, + headers, + ) } return fetch(fetchURL, { method: "post", - headers: headers, + headers: Object.assign( + { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + headers, + ), body: JSON.stringify(graphQLParams), credentials: "include", }) @@ -108,7 +120,7 @@ var activeSubscription = null; // Define a GraphQL fetcher that can intelligently route queries based on the operation type. - function graphQLFetcher(graphQLParams) { + function graphQLFetcher(graphQLParams, opts = { headers: {} }) { var operationType = getOperationType(graphQLParams); // If we're about to execute a new operation, and we have an active subscription, @@ -126,7 +138,7 @@ }, }; } else { - return httpClient(graphQLParams); + return httpClient(graphQLParams, opts); } } @@ -173,6 +185,7 @@ onEditQuery: onEditQuery, onEditVariables: onEditVariables, onEditOperationName: onEditOperationName, + headerEditorEnabled: GRAPHENE_SETTINGS.graphiqlHeaderEditorEnabled || false, query: parameters.query, }; if (parameters.variables) { From 29f28bc91b703b81ee64285a9b2c1d3156488206 Mon Sep 17 00:00:00 2001 From: "radoslaw.kowalski" Date: Mon, 3 Aug 2020 09:16:58 +0200 Subject: [PATCH 2/7] ES5 compatibility --- .../static/graphene_django/graphiql.js | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/graphene_django/static/graphene_django/graphiql.js b/graphene_django/static/graphene_django/graphiql.js index fb878ae30..1903f80d2 100644 --- a/graphene_django/static/graphene_django/graphiql.js +++ b/graphene_django/static/graphene_django/graphiql.js @@ -61,29 +61,19 @@ var fetchURL = locationQuery(otherParams); // Defines a GraphQL fetcher using the fetch API. - function httpClient(graphQLParams, opts = { headers: {} }) { - let headers = opts.headers; - // Convert headers to an object. - if (typeof headers === 'string') { - headers = JSON.parse(opts.headers); + function httpClient(graphQLParams, opts) { + if (typeof opts === 'undefined') { + opts = {}; } + var headers = opts.headers || {}; + headers['Accept'] = headers['Accept'] || 'application/json'; + headers['Content-Type'] = headers['Content-Type'] || 'application/json'; if (csrftoken) { - Object.assign( - { - 'X-CSRFToken': csrftoken - }, - headers, - ) + headers['X-CSRFToken'] = csrftoken } return fetch(fetchURL, { method: "post", - headers: Object.assign( - { - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - headers, - ), + headers: headers, body: JSON.stringify(graphQLParams), credentials: "include", }) @@ -120,7 +110,7 @@ var activeSubscription = null; // Define a GraphQL fetcher that can intelligently route queries based on the operation type. - function graphQLFetcher(graphQLParams, opts = { headers: {} }) { + function graphQLFetcher(graphQLParams, opts) { var operationType = getOperationType(graphQLParams); // If we're about to execute a new operation, and we have an active subscription, From ca115f53818f22fdcf399af006aa63854912a405 Mon Sep 17 00:00:00 2001 From: "radoslaw.kowalski" Date: Mon, 3 Aug 2020 09:26:29 +0200 Subject: [PATCH 3/7] Docs note on GraphiQL headers setting --- docs/settings.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/settings.rst b/docs/settings.rst index c2f86005a..587e8b54f 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -186,3 +186,24 @@ Default: ``None`` GRAPHENE = { 'SUBSCRIPTION_PATH': "/ws/graphql" } + + +``GRAPHIQL_HEADER_EDITOR_ENABLED`` +--------------------- + +GraphiQL starting from version 1.0.0 allows setting custom headers in similar fashion to query variables. + +Set to ``True`` to enable GraphiQL headers editor tab. + +This setting is passed to ``headerEditorEnabled`` GraphiQL options, for details refer to GraphiQLDocs_. + +.. _GraphiQLDocs: https://github.com/graphql/graphiql/tree/main/packages/graphiql#options + + +Default: ``False`` + +.. code:: python + + GRAPHENE = { + 'GRAPHIQL_HEADER_EDITOR_ENABLED': True, + } From ea10c33c0a72096eecf31514e2beb939efe39f5c Mon Sep 17 00:00:00 2001 From: "radoslaw.kowalski" Date: Tue, 4 Aug 2020 18:00:04 +0200 Subject: [PATCH 4/7] Inject GraphiQL header setting to graphiql.html template --- graphene_django/templates/graphene/graphiql.html | 3 +++ graphene_django/views.py | 2 ++ 2 files changed, 5 insertions(+) diff --git a/graphene_django/templates/graphene/graphiql.html b/graphene_django/templates/graphene/graphiql.html index abc4b5262..8e71a69a8 100644 --- a/graphene_django/templates/graphene/graphiql.html +++ b/graphene_django/templates/graphene/graphiql.html @@ -45,6 +45,9 @@ {% if subscription_path %} subscriptionPath: "{{subscription_path}}", {% endif %} + {% if header_editor_enabled %} + graphiqlHeaderEditorEnabled: "{{ graphiql_header_editor_enabled}}", + {% endif %} }; diff --git a/graphene_django/views.py b/graphene_django/views.py index 59084e8eb..5ee02972e 100644 --- a/graphene_django/views.py +++ b/graphene_django/views.py @@ -167,6 +167,8 @@ def dispatch(self, request, *args, **kwargs): subscriptions_transport_ws_sri=self.subscriptions_transport_ws_sri, # The SUBSCRIPTION_PATH setting. subscription_path=self.subscription_path, + # GraphiQL headers tab, + graphiql_header_editor_enabled=graphene_settings.GRAPHIQL_HEADER_EDITOR_ENABLED, ) if self.batch: From 9f8fd4346b0e9da70109c4d575e06ed6fea6ca4b Mon Sep 17 00:00:00 2001 From: "radoslaw.kowalski" Date: Thu, 6 Aug 2020 21:36:07 +0200 Subject: [PATCH 5/7] Enable headers editor in GraphiQL by default --- docs/settings.rst | 4 ++-- graphene_django/settings.py | 4 ++-- graphene_django/static/graphene_django/graphiql.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/settings.rst b/docs/settings.rst index 587e8b54f..1e82e70de 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -193,14 +193,14 @@ Default: ``None`` GraphiQL starting from version 1.0.0 allows setting custom headers in similar fashion to query variables. -Set to ``True`` to enable GraphiQL headers editor tab. +Set to ``False`` if you want to disable GraphiQL headers editor tab for some reason. This setting is passed to ``headerEditorEnabled`` GraphiQL options, for details refer to GraphiQLDocs_. .. _GraphiQLDocs: https://github.com/graphql/graphiql/tree/main/packages/graphiql#options -Default: ``False`` +Default: ``True`` .. code:: python diff --git a/graphene_django/settings.py b/graphene_django/settings.py index 4116ee17e..71b791c29 100644 --- a/graphene_django/settings.py +++ b/graphene_django/settings.py @@ -41,10 +41,10 @@ "DJANGO_CHOICE_FIELD_ENUM_CUSTOM_NAME": None, # Use a separate path for handling subscriptions. "SUBSCRIPTION_PATH": None, - # Set to True to enable GraphiQL headers editor tab + # By default GraphiQL headers editor tab is enabled, set to False to hide it # This sets headerEditorEnabled GraphiQL option, for details go to # https://github.com/graphql/graphiql/tree/main/packages/graphiql#options - "GRAPHIQL_HEADER_EDITOR_ENABLED": False, + "GRAPHIQL_HEADER_EDITOR_ENABLED": True, } if settings.DEBUG: diff --git a/graphene_django/static/graphene_django/graphiql.js b/graphene_django/static/graphene_django/graphiql.js index 1903f80d2..42366a8ac 100644 --- a/graphene_django/static/graphene_django/graphiql.js +++ b/graphene_django/static/graphene_django/graphiql.js @@ -175,7 +175,7 @@ onEditQuery: onEditQuery, onEditVariables: onEditVariables, onEditOperationName: onEditOperationName, - headerEditorEnabled: GRAPHENE_SETTINGS.graphiqlHeaderEditorEnabled || false, + headerEditorEnabled: GRAPHENE_SETTINGS.graphiqlHeaderEditorEnabled || true, query: parameters.query, }; if (parameters.variables) { From f9ff320f48bdc51870d3626b68188d69aed3c4ea Mon Sep 17 00:00:00 2001 From: "radoslaw.kowalski" Date: Thu, 6 Aug 2020 21:53:28 +0200 Subject: [PATCH 6/7] Fix boolean injection to graphiql.html template --- graphene_django/templates/graphene/graphiql.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphene_django/templates/graphene/graphiql.html b/graphene_django/templates/graphene/graphiql.html index 8e71a69a8..bcdb348e1 100644 --- a/graphene_django/templates/graphene/graphiql.html +++ b/graphene_django/templates/graphene/graphiql.html @@ -46,7 +46,7 @@ subscriptionPath: "{{subscription_path}}", {% endif %} {% if header_editor_enabled %} - graphiqlHeaderEditorEnabled: "{{ graphiql_header_editor_enabled}}", + graphiqlHeaderEditorEnabled: {{ graphiql_header_editor_enabled}}, {% endif %} }; From eece5f9f830adf53f95b1b3b4f077f088bc1673e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Kowalski?= Date: Fri, 7 Aug 2020 11:09:11 +0200 Subject: [PATCH 7/7] Fix setting injection with suggestions from CR Co-authored-by: Jonathan Kim --- graphene_django/static/graphene_django/graphiql.js | 2 +- graphene_django/templates/graphene/graphiql.html | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/graphene_django/static/graphene_django/graphiql.js b/graphene_django/static/graphene_django/graphiql.js index 42366a8ac..8c3b5ced4 100644 --- a/graphene_django/static/graphene_django/graphiql.js +++ b/graphene_django/static/graphene_django/graphiql.js @@ -175,7 +175,7 @@ onEditQuery: onEditQuery, onEditVariables: onEditVariables, onEditOperationName: onEditOperationName, - headerEditorEnabled: GRAPHENE_SETTINGS.graphiqlHeaderEditorEnabled || true, + headerEditorEnabled: GRAPHENE_SETTINGS.graphiqlHeaderEditorEnabled, query: parameters.query, }; if (parameters.variables) { diff --git a/graphene_django/templates/graphene/graphiql.html b/graphene_django/templates/graphene/graphiql.html index bcdb348e1..cec48930b 100644 --- a/graphene_django/templates/graphene/graphiql.html +++ b/graphene_django/templates/graphene/graphiql.html @@ -45,9 +45,7 @@ {% if subscription_path %} subscriptionPath: "{{subscription_path}}", {% endif %} - {% if header_editor_enabled %} - graphiqlHeaderEditorEnabled: {{ graphiql_header_editor_enabled}}, - {% endif %} + graphiqlHeaderEditorEnabled: {{ graphiql_header_editor_enabled|yesno:"true,false" }}, };