routes.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. const graphqlHTTP = require('express-graphql');
  2. const escape = require('escape-html');
  3. const dateFormat = require('dateformat');
  4. const { makeExecutableSchema } = require('graphql-tools');
  5. module.exports = (app, resolvers) => {
  6. const typeDefs = require('./schema');
  7. const schema = makeExecutableSchema({
  8. typeDefs,
  9. resolvers
  10. });
  11. app.get('/json', async(req, res) => {
  12. const graphql = await graphqlHTTP((req, res, graphQLParams) => {
  13. graphQLParams.query = "{ helloWorld }";
  14. graphQLParams.operationName = null;
  15. graphQLParams.variables = {};
  16. return graphqlOpts()
  17. });
  18. res.real_end = res.end;
  19. res.end = (data) => {
  20. let toRet;
  21. const json = JSON.parse(data.toString('utf8'));
  22. if(json.data.helloWorld) {
  23. toRet = json.data.helloWorld;
  24. } else {
  25. toRet = { helloWorld: null };
  26. }
  27. setResponseHeaders(res, toRet.length);
  28. res.real_end(toRet);
  29. }
  30. await graphql(req, res);
  31. });
  32. app.get('/db', async (req, res) => {
  33. const graphql = await graphqlHTTP((req, res, graphQLParams) => {
  34. graphQLParams.query = "{ singleDatabaseQuery { id, randomNumber }}";
  35. graphQLParams.variables = {};
  36. graphQLParams.operationName = null;
  37. return graphqlOpts();
  38. });
  39. formatResData(res, "singleDatabaseQuery");
  40. await graphql(req, res);
  41. });
  42. app.get('/queries', async (req, res) => {
  43. const graphql = await graphqlHTTP((req, res, graphQLParams) => {
  44. let totalNumOfQueries = ensureQueryIsAnInt(req.query.queries);
  45. graphQLParams.query = `{ multipleDatabaseQueries(total: ${totalNumOfQueries}) { id, randomNumber }}`
  46. graphQLParams.variables = {};
  47. graphQLParams.operationName = null;
  48. return graphqlOpts();
  49. });
  50. formatResData(res, "multipleDatabaseQueries");
  51. await graphql(req, res);
  52. });
  53. app.get('/fortunes', async (req, res) => {
  54. const graphql = await graphqlHTTP((req, res, graphQLParams) => {
  55. graphQLParams.query = "{ getAllFortunes { id, message } }"
  56. graphQLParams.operationName = null;
  57. graphQLParams.variables = {};
  58. return graphqlOpts();
  59. });
  60. retrieveAndFormatAllFortunes(res);
  61. await graphql(req, res);
  62. });
  63. app.get('/updates', async (req, res) => {
  64. const totalNumOfQueries = ensureQueryIsAnInt(req.query.queries);
  65. const graphql = await graphqlHTTP((req, res, graphQLParams) => {
  66. graphQLParams.query = `{ getRandomAndUpdate(total: ${totalNumOfQueries}) { id, randomNumber } }`
  67. graphQLParams.operationName = null;
  68. graphQLParams.variables = {};
  69. return graphqlOpts();
  70. });
  71. formatResData(res, 'getRandomAndUpdate');
  72. await graphql(req, res);
  73. });
  74. app.get('/plaintext', (req, res) => {
  75. const responseTxt = "Hello, World!";
  76. res.setHeader('Content-Length', responseTxt.length);
  77. res.setHeader('Server', 'Express-GraphQL-MySQL');
  78. res.contentType('text/plain');
  79. res.status(200);
  80. res.send(responseTxt);
  81. });
  82. // Helper Functions
  83. const ensureQueryIsAnInt = (queryString) => {
  84. if(queryString === undefined) return 1;
  85. const possibleInt = parseInt(queryString);
  86. if(!possibleInt) return 1;
  87. return possibleInt;
  88. };
  89. const graphqlOpts = (params) => {
  90. return {
  91. schema,
  92. graphiql: false,
  93. context: params || {}
  94. }
  95. };
  96. const retrieveAndFormatAllFortunes = res => {
  97. res.real_end = res.end;
  98. res.end = async (data) => {
  99. let toRet;
  100. const json = JSON.parse(data.toString('utf8'));
  101. if(json.data.getAllFortunes) {
  102. toRet = json.data.getAllFortunes;
  103. } else {
  104. toRet = [];
  105. }
  106. const newFortune = { "id": 0, "message": "Additional fortune added at request time." };
  107. toRet.push(newFortune);
  108. toRet.sort((a, b) => (a.message < b.message) ? -1 : 1);
  109. const htmlToRet = await spoofHTML(toRet);
  110. res.contentType('html');
  111. res.setHeader('Server', 'GraphQL-MySQL');
  112. res.setHeader('Content-Length', htmlToRet.length + 32);
  113. res.status(200);
  114. res.real_end(htmlToRet);
  115. }
  116. };
  117. const spoofHTML = arr => {
  118. return new Promise((resolve, reject) => {
  119. let count = 0;
  120. let htmlToRet = `<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>`;
  121. for (let fortune of arr) {
  122. htmlToRet += `<tr><td>${escape(fortune.id)}</td><td>${escape(fortune.message)}</td></tr>`;
  123. count++;
  124. }
  125. htmlToRet += '</table></body></html>';
  126. if(count == arr.length)resolve(htmlToRet);
  127. });
  128. };
  129. const formatResData = (res, queryName) => {
  130. res.real_end = res.end;
  131. res.end = (data) => {
  132. const json = JSON.parse(data.toString('utf8'));
  133. let toRet = formatJson(queryName, json);
  134. const jsonToRet = JSON.stringify(toRet);
  135. setResponseHeaders(res, jsonToRet.length);
  136. res.real_end(jsonToRet);
  137. };
  138. };
  139. const formatJson = (queryName, jsonData) => {
  140. const isQueryReturningAnArray = {
  141. singleDatabaseQuery: false,
  142. multipleDatabaseQueries: true,
  143. getRandomAndUpdate: true
  144. };
  145. if (isQueryReturningAnArray[queryName] == false) {
  146. if(jsonData.data[`${queryName}`]) {
  147. return {
  148. id: jsonData.data[`${queryName}`].id,
  149. randomNumber: jsonData.data[`${queryName}`].randomNumber
  150. };
  151. } else {
  152. return {
  153. id: null,
  154. randomNumber: null
  155. }
  156. }
  157. } else {
  158. return jsonData.data[`${queryName}`] || [];
  159. }
  160. };
  161. const setResponseHeaders = (res, jsonLength) => {
  162. let now = new Date();
  163. res.status(200);
  164. res.contentType('application/json', 'charset=UTF-8');
  165. res.setHeader('Date', dateFormat(now, "ddd, dd mmm yyyy hh:MM:ss Z"));
  166. res.setHeader('Server', 'GraphQL-Express-MySQL');
  167. res.setHeader('Content-Length', jsonLength);
  168. };
  169. }