Skip to content

Commit 9f25e7c

Browse files
committed
GraphQL: upgrade graphql clients
- igraphql - graphql-playground
1 parent 692b342 commit 9f25e7c

File tree

4 files changed

+224
-113
lines changed

4 files changed

+224
-113
lines changed

modules/jooby-graphiql/package.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@
44
"private": true,
55
"license": "ASF",
66
"dependencies": {
7-
"es6-promise": "^4.2.8",
8-
"fetch-min": "^1.0.0",
9-
"react": "^17.0.2",
10-
"react-dom": "^17.0.2",
117
"graphql": "^16.3.0",
12-
"graphiql": "^1.6.0"
8+
"graphiql": "^1.8.3"
139
}
1410
}

modules/jooby-graphiql/pom.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,6 @@
5454
<target>
5555
<property name="output" value="${project.build.outputDirectory}${file.separator}graphiql${file.separator}" />
5656

57-
<copy failonerror="true" file="node_modules${file.separator}es6-promise${file.separator}dist${file.separator}es6-promise.auto.min.js" tofile="${output}es6-promise.auto.min.js"/>
58-
<copy failonerror="true" file="node_modules${file.separator}fetch-min${file.separator}index.js" tofile="${output}fetch.min.js"/>
59-
<copy failonerror="true" file="node_modules${file.separator}react${file.separator}umd${file.separator}react.production.min.js" tofile="${output}react.min.js"/>
60-
<copy failonerror="true" file="node_modules${file.separator}react-dom${file.separator}umd${file.separator}react-dom.production.min.js" tofile="${output}react-dom.min.js"/>
61-
6257
<copy failonerror="true" file="node_modules${file.separator}graphiql${file.separator}graphiql.css" tofile="${output}graphiql.css"/>
6358
<copy failonerror="true" file="node_modules${file.separator}graphiql${file.separator}graphiql.js" tofile="${output}graphiql.min.js"/>
6459
</target>

modules/jooby-graphiql/src/main/java/io/jooby/graphql/GraphiQLModule.java

Lines changed: 222 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
*/
66
package io.jooby.graphql;
77

8+
import javax.annotation.Nonnull;
9+
810
import io.jooby.Extension;
911
import io.jooby.Jooby;
1012
import io.jooby.MediaType;
1113

12-
import javax.annotation.Nonnull;
13-
1414
/**
1515
* GraphiQL module: https://github.com/graphql/graphiql.
1616
*
@@ -31,13 +31,10 @@
3131
*/
3232
public class GraphiQLModule implements Extension {
3333

34-
private static final String RESOURCES =
35-
" <link href=\"{{contextPath}}/graphql/static/graphiql.css\" rel=\"stylesheet\" />\n"
36-
+ " <script src=\"{{contextPath}}/graphql/static/es6-promise.auto.min.js\"></script>\n"
37-
+ " <script src=\"{{contextPath}}/graphql/static/fetch.min.js\"></script>\n"
38-
+ " <script src=\"{{contextPath}}/graphql/static/react.min.js\"></script>\n"
39-
+ " <script src=\"{{contextPath}}/graphql/static/react-dom.min.js\"></script>\n"
40-
+ " <script src=\"{{contextPath}}/graphql/static/graphiql.min.js\"></script>\n";
34+
private static final String RESOURCES_CSS =
35+
" <link href=\"{{contextPath}}/graphql/static/graphiql.css\" rel=\"stylesheet\" />\n";
36+
37+
private static final String RESOURCES_JS = " <script src=\"{{contextPath}}/graphql/static/graphiql.min.js\"></script>\n";
4138

4239
@Override public void install(@Nonnull Jooby application) throws Exception {
4340
String cpath = application.getContextPath();
@@ -51,122 +48,245 @@ public class GraphiQLModule implements Extension {
5148
application.get(graphqlPath, ctx -> ctx.setResponseType(MediaType.html).send(index));
5249
}
5350

54-
private static final String INDEX = "<!--\n"
55-
+ "The request to this GraphQL server provided the header \"Accept: text/html\"\n"
56-
+ "and as a result has been presented GraphiQL - an in-browser IDE for\n"
57-
+ "exploring GraphQL.\n"
58-
+ "\n"
59-
+ "If you wish to receive JSON, provide the header \"Accept: application/json\" or\n"
60-
+ "add \"&raw\" to the end of the URL within a browser.\n"
61-
+ "-->\n"
51+
private static final String INDEX = "\n"
6252
+ "<!DOCTYPE html>\n"
63-
+ "<html>\n"
53+
+ "<html lang=\"en\">\n"
6454
+ "<head>\n"
6555
+ " <meta charset=\"utf-8\" />\n"
66-
+ " <title>GraphiQL</title>\n"
6756
+ " <meta name=\"robots\" content=\"noindex\" />\n"
6857
+ " <meta name=\"referrer\" content=\"origin\" />\n"
6958
+ " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n"
59+
+ " <title>SWAPI GraphQL API</title>\n"
7060
+ " <style>\n"
7161
+ " body {\n"
62+
+ " height: 100vh;\n"
7263
+ " margin: 0;\n"
7364
+ " overflow: hidden;\n"
7465
+ " }\n"
75-
+ " #graphiql {\n"
66+
+ " #splash {\n"
67+
+ " color: #333;\n"
68+
+ " display: flex;\n"
69+
+ " flex-direction: column;\n"
70+
+ " font-family: system, -apple-system, \"San Francisco\", \".SFNSDisplay-Regular\", \"Segoe UI\", Segoe, \"Segoe WP\", \"Helvetica Neue\", helvetica, \"Lucida Grande\", arial, sans-serif;\n"
7671
+ " height: 100vh;\n"
72+
+ " justify-content: center;\n"
73+
+ " text-align: center;\n"
7774
+ " }\n"
7875
+ " </style>\n"
79-
+ RESOURCES
76+
+ " <link rel=\"icon\" href=\"favicon.ico\">\n"
77+
+ RESOURCES_CSS
8078
+ "</head>\n"
8179
+ "<body>\n"
82-
+ "<div id=\"graphiql\">Loading...</div>\n"
83-
+ "<script>\n"
84-
+ " // Collect the URL parameters\n"
85-
+ " var parameters = {};\n"
86-
+ " window.location.search.substr(1).split('&').forEach(function (entry) {\n"
87-
+ " var eq = entry.indexOf('=');\n"
88-
+ " if (eq >= 0) {\n"
89-
+ " parameters[decodeURIComponent(entry.slice(0, eq))] =\n"
90-
+ " decodeURIComponent(entry.slice(eq + 1));\n"
91-
+ " }\n"
92-
+ " });\n"
93-
+ "\n"
94-
+ " // Produce a Location query string from a parameter object.\n"
95-
+ " function locationQuery(params) {\n"
96-
+ " return '?' + Object.keys(params).filter(function (key) {\n"
97-
+ " return Boolean(params[key]);\n"
98-
+ " }).map(function (key) {\n"
99-
+ " return encodeURIComponent(key) + '=' +\n"
100-
+ " encodeURIComponent(params[key]);\n"
101-
+ " }).join('&');\n"
102-
+ " }\n"
80+
+ " <div id=\"splash\">\n"
81+
+ " Loading&hellip;\n"
82+
+ " </div>\n"
83+
+ " <script src=\"//cdn.jsdelivr.net/es6-promise/4.0.5/es6-promise.auto.min.js\"></script>\n"
84+
+ " <script src=\"https://cdn.jsdelivr.net/npm/react/umd/react.production.min.js\"></script>\n"
85+
+ " <script src=\"https://cdn.jsdelivr.net/npm/react-dom/umd/react-dom.production.min.js\"></script>\n"
86+
+ RESOURCES_JS
87+
+ " <script>\n"
88+
+ " // Parse the search string to get url parameters.\n"
89+
+ " var search = window.location.search;\n"
90+
+ " var parameters = {};\n"
91+
+ " search.substr(1).split('&').forEach(function (entry) {\n"
92+
+ " var eq = entry.indexOf('=');\n"
93+
+ " if (eq >= 0) {\n"
94+
+ " parameters[decodeURIComponent(entry.slice(0, eq))] =\n"
95+
+ " decodeURIComponent(entry.slice(eq + 1));\n"
96+
+ " }\n"
97+
+ " });\n"
10398
+ "\n"
104-
+ " // Derive a fetch URL from the current URL, sans the GraphQL parameters.\n"
105-
+ " var graphqlParamNames = {\n"
106-
+ " query: true,\n"
107-
+ " variables: true,\n"
108-
+ " operationName: true\n"
109-
+ " };\n"
99+
+ " // if variables was provided, try to format it.\n"
100+
+ " if (parameters.variables) {\n"
101+
+ " try {\n"
102+
+ " parameters.variables =\n"
103+
+ " JSON.stringify(JSON.parse(parameters.variables), null, 2);\n"
104+
+ " } catch (e) {\n"
105+
+ " // Do nothing, we want to display the invalid JSON as a string, rather\n"
106+
+ " // than present an error.\n"
107+
+ " }\n"
108+
+ " }\n"
110109
+ "\n"
111-
+ " var otherParams = {};\n"
112-
+ " for (var k in parameters) {\n"
113-
+ " if (parameters.hasOwnProperty(k) && graphqlParamNames[k] !== true) {\n"
114-
+ " otherParams[k] = parameters[k];\n"
115-
+ " }\n"
116-
+ " }\n"
117-
+ " var fetchURL = locationQuery(otherParams);\n"
110+
+ " // When the query and variables string is edited, update the URL bar so\n"
111+
+ " // that it can be easily shared\n"
112+
+ " function onEditQuery(newQuery) {\n"
113+
+ " parameters.query = newQuery;\n"
114+
+ " updateURL();\n"
115+
+ " }\n"
116+
+ " function onEditVariables(newVariables) {\n"
117+
+ " parameters.variables = newVariables;\n"
118+
+ " updateURL();\n"
119+
+ " }\n"
120+
+ " function onEditOperationName(newOperationName) {\n"
121+
+ " parameters.operationName = newOperationName;\n"
122+
+ " updateURL();\n"
123+
+ " }\n"
124+
+ " function updateURL() {\n"
125+
+ " var newSearch = '?' + Object.keys(parameters).filter(function (key) {\n"
126+
+ " return Boolean(parameters[key]);\n"
127+
+ " }).map(function (key) {\n"
128+
+ " return encodeURIComponent(key) + '=' +\n"
129+
+ " encodeURIComponent(parameters[key]);\n"
130+
+ " }).join('&');\n"
131+
+ " history.replaceState(null, null, newSearch);\n"
132+
+ " }\n"
118133
+ "\n"
119-
+ " // Defines a GraphQL fetcher using the fetch API.\n"
120-
+ " function graphQLFetcher(graphQLParams) {\n"
121-
+ " return fetch(fetchURL, {\n"
122-
+ " method: 'post',\n"
123-
+ " headers: {\n"
124-
+ " 'Accept': 'application/json',\n"
125-
+ " 'Content-Type': 'application/json'\n"
126-
+ " },\n"
127-
+ " body: JSON.stringify(graphQLParams),\n"
128-
+ " credentials: 'include',\n"
129-
+ " }).then(function (response) {\n"
130-
+ " return response.json();\n"
131-
+ " });\n"
132-
+ " }\n"
134+
+ " function graphQLFetcher(graphQLParams) {\n"
135+
+ " // This example expects a GraphQL server at the path /graphql.\n"
136+
+ " // Change this to point wherever you host your GraphQL server.\n"
137+
+ " return fetch(parameters.fetchURL || 'https://swapi-graphql.netlify.app/.netlify/functions/index', {\n"
138+
+ " method: 'post',\n"
139+
+ " headers: {\n"
140+
+ " 'Accept': 'application/json',\n"
141+
+ " 'Content-Type': 'application/json'\n"
142+
+ " },\n"
143+
+ " body: JSON.stringify(graphQLParams),\n"
144+
+ " }).then(function (response) {\n"
145+
+ " return response.text();\n"
146+
+ " }).then(function (responseBody) {\n"
147+
+ " try {\n"
148+
+ " return JSON.parse(responseBody);\n"
149+
+ " } catch (error) {\n"
150+
+ " return responseBody;\n"
151+
+ " }\n"
152+
+ " });\n"
153+
+ " }\n"
133154
+ "\n"
134-
+ " // When the query and variables string is edited, update the URL bar so\n"
135-
+ " // that it can be easily shared.\n"
136-
+ " function onEditQuery(newQuery) {\n"
137-
+ " parameters.query = newQuery;\n"
138-
+ " updateURL();\n"
139-
+ " }\n"
155+
+ " // Render <GraphiQL /> into the body.\n"
156+
+ " ReactDOM.render(\n"
157+
+ " React.createElement(GraphiQL, {\n"
158+
+ " fetcher: graphQLFetcher,\n"
159+
+ " query: parameters.query,\n"
160+
+ " variables: parameters.variables,\n"
161+
+ " operationName: parameters.operationName,\n"
162+
+ " onEditQuery: onEditQuery,\n"
163+
+ " onEditVariables: onEditVariables,\n"
164+
+ " onEditOperationName: onEditOperationName\n"
165+
+ " }),\n"
166+
+ " document.body,\n"
167+
+ " );\n"
168+
+ " </script>\n"
169+
+ "</body>\n"
170+
+ "</html>\n"
171+
+ "\n\n"
172+
+ "<!DOCTYPE html>\n"
173+
+ "<html lang=\"en\">\n"
174+
+ "<head>\n"
175+
+ " <meta charset=\"utf-8\" />\n"
176+
+ " <meta name=\"robots\" content=\"noindex\" />\n"
177+
+ " <meta name=\"referrer\" content=\"origin\" />\n"
178+
+ " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n"
179+
+ " <title>SWAPI GraphQL API</title>\n"
180+
+ " <style>\n"
181+
+ " body {\n"
182+
+ " height: 100vh;\n"
183+
+ " margin: 0;\n"
184+
+ " overflow: hidden;\n"
185+
+ " }\n"
186+
+ " #splash {\n"
187+
+ " color: #333;\n"
188+
+ " display: flex;\n"
189+
+ " flex-direction: column;\n"
190+
+ " font-family: system, -apple-system, \"San Francisco\", \".SFNSDisplay-Regular\", \"Segoe UI\", Segoe, \"Segoe WP\", \"Helvetica Neue\", helvetica, \"Lucida Grande\", arial, sans-serif;\n"
191+
+ " height: 100vh;\n"
192+
+ " justify-content: center;\n"
193+
+ " text-align: center;\n"
194+
+ " }\n"
195+
+ " </style>\n"
196+
+ " <link rel=\"icon\" href=\"favicon.ico\">\n"
197+
+ " <link type=\"text/css\" href=\"//unpkg.com/graphiql/graphiql.min.css\" rel=\"stylesheet\" />\n"
198+
+ "</head>\n"
199+
+ "<body>\n"
200+
+ " <div id=\"splash\">\n"
201+
+ " Loading&hellip;\n"
202+
+ " </div>\n"
203+
+ " <script src=\"//cdn.jsdelivr.net/es6-promise/4.0.5/es6-promise.auto.min.js\"></script>\n"
204+
+ " <script src=\"https://cdn.jsdelivr.net/npm/react/umd/react.production.min.js\"></script>\n"
205+
+ " <script src=\"https://cdn.jsdelivr.net/npm/react-dom/umd/react-dom.production.min.js\"></script>\n"
206+
+ " <script src=\"//unpkg.com/graphiql/graphiql.min.js\"></script>\n"
207+
+ " <script>\n"
208+
+ " // Parse the search string to get url parameters.\n"
209+
+ " var search = window.location.search;\n"
210+
+ " var parameters = {};\n"
211+
+ " search.substr(1).split('&').forEach(function (entry) {\n"
212+
+ " var eq = entry.indexOf('=');\n"
213+
+ " if (eq >= 0) {\n"
214+
+ " parameters[decodeURIComponent(entry.slice(0, eq))] =\n"
215+
+ " decodeURIComponent(entry.slice(eq + 1));\n"
216+
+ " }\n"
217+
+ " });\n"
140218
+ "\n"
141-
+ " function onEditVariables(newVariables) {\n"
142-
+ " parameters.variables = newVariables;\n"
143-
+ " updateURL();\n"
144-
+ " }\n"
219+
+ " // if variables was provided, try to format it.\n"
220+
+ " if (parameters.variables) {\n"
221+
+ " try {\n"
222+
+ " parameters.variables =\n"
223+
+ " JSON.stringify(JSON.parse(parameters.variables), null, 2);\n"
224+
+ " } catch (e) {\n"
225+
+ " // Do nothing, we want to display the invalid JSON as a string, rather\n"
226+
+ " // than present an error.\n"
227+
+ " }\n"
228+
+ " }\n"
145229
+ "\n"
146-
+ " function onEditOperationName(newOperationName) {\n"
147-
+ " parameters.operationName = newOperationName;\n"
148-
+ " updateURL();\n"
149-
+ " }\n"
230+
+ " // When the query and variables string is edited, update the URL bar so\n"
231+
+ " // that it can be easily shared\n"
232+
+ " function onEditQuery(newQuery) {\n"
233+
+ " parameters.query = newQuery;\n"
234+
+ " updateURL();\n"
235+
+ " }\n"
236+
+ " function onEditVariables(newVariables) {\n"
237+
+ " parameters.variables = newVariables;\n"
238+
+ " updateURL();\n"
239+
+ " }\n"
240+
+ " function onEditOperationName(newOperationName) {\n"
241+
+ " parameters.operationName = newOperationName;\n"
242+
+ " updateURL();\n"
243+
+ " }\n"
244+
+ " function updateURL() {\n"
245+
+ " var newSearch = '?' + Object.keys(parameters).filter(function (key) {\n"
246+
+ " return Boolean(parameters[key]);\n"
247+
+ " }).map(function (key) {\n"
248+
+ " return encodeURIComponent(key) + '=' +\n"
249+
+ " encodeURIComponent(parameters[key]);\n"
250+
+ " }).join('&');\n"
251+
+ " history.replaceState(null, null, newSearch);\n"
252+
+ " }\n"
150253
+ "\n"
151-
+ " function updateURL() {\n"
152-
+ " history.replaceState(null, null, locationQuery(parameters));\n"
153-
+ " }\n"
254+
+ " function graphQLFetcher(graphQLParams) {\n"
255+
+ " // This example expects a GraphQL server at the path /graphql.\n"
256+
+ " // Change this to point wherever you host your GraphQL server.\n"
257+
+ " return fetch(parameters.fetchURL || 'https://swapi-graphql.netlify.app/.netlify/functions/index', {\n"
258+
+ " method: 'post',\n"
259+
+ " headers: {\n"
260+
+ " 'Accept': 'application/json',\n"
261+
+ " 'Content-Type': 'application/json'\n"
262+
+ " },\n"
263+
+ " body: JSON.stringify(graphQLParams),\n"
264+
+ " }).then(function (response) {\n"
265+
+ " return response.text();\n"
266+
+ " }).then(function (responseBody) {\n"
267+
+ " try {\n"
268+
+ " return JSON.parse(responseBody);\n"
269+
+ " } catch (error) {\n"
270+
+ " return responseBody;\n"
271+
+ " }\n"
272+
+ " });\n"
273+
+ " }\n"
154274
+ "\n"
155-
+ " // Render <GraphiQL /> into the body.\n"
156-
+ " ReactDOM.render(\n"
157-
+ " React.createElement(GraphiQL, {\n"
158-
+ " fetcher: graphQLFetcher,\n"
159-
+ " onEditQuery: onEditQuery,\n"
160-
+ " onEditVariables: onEditVariables,\n"
161-
+ " onEditOperationName: onEditOperationName,\n"
162-
+ " query: undefined,\n"
163-
+ " response: undefined,\n"
164-
+ " variables: undefined,\n"
165-
+ " operationName: undefined,\n"
166-
+ " }),\n"
167-
+ " document.getElementById('graphiql')\n"
168-
+ " );\n"
169-
+ "</script>\n"
275+
+ " // Render <GraphiQL /> into the body.\n"
276+
+ " ReactDOM.render(\n"
277+
+ " React.createElement(GraphiQL, {\n"
278+
+ " fetcher: graphQLFetcher,\n"
279+
+ " query: parameters.query,\n"
280+
+ " variables: parameters.variables,\n"
281+
+ " operationName: parameters.operationName,\n"
282+
+ " onEditQuery: onEditQuery,\n"
283+
+ " onEditVariables: onEditVariables,\n"
284+
+ " onEditOperationName: onEditOperationName\n"
285+
+ " }),\n"
286+
+ " document.body,\n"
287+
+ " );\n"
288+
+ " </script>\n"
170289
+ "</body>\n"
171-
+ "</html>\n";
290+
+ "</html>\n"
291+
+ "\n";
172292
}

0 commit comments

Comments
 (0)