瀏覽代碼

added graphql-express-mongodb to the express configurations (#4042)

* added graphql-express-mongodb to the express configurations

* refactored code to use a single routes.js file passing in app and a resolver file
jenriquez-techempower 6 年之前
父節點
當前提交
8d22d1a01b

+ 24 - 1
frameworks/JavaScript/express/benchmark_config.json

@@ -89,6 +89,29 @@
       "display_name": "express",
       "display_name": "express",
       "notes": "",
       "notes": "",
       "versus": "None"
       "versus": "None"
+    },
+    "graphql-mongodb": {
+      "json_url": "/json",
+      "plaintext_url": "/plaintext",
+      "db_url": "/db",
+      "query_url": "/queries?queries=",
+      "fortune_url": "/fortunes",
+      "update_url": "/updates?queries=",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "framework": "graphql-express-mongodb",
+      "language": "JavaScript",
+      "flavor": "NodeJS",
+      "orm": "Full",
+      "platform": "NodeJS",
+      "webserver": "None",
+      "os": "Linux",
+      "database": "MongoDB",
+      "database_os": "Linux",
+      "display_name": "express",
+      "notes": "",
+      "versus": "None"
     }
     }
   }]
   }]
-}
+}

+ 9 - 0
frameworks/JavaScript/express/express-graphql-mongodb.dockerfile

@@ -0,0 +1,9 @@
+FROM node:10.3.0
+
+COPY ./ ./
+
+RUN npm install
+
+ENV NODE_ENV production
+
+CMD ["node", "graphql-mongodb-app.js"]

+ 26 - 0
frameworks/JavaScript/express/graphql-mongodb-app.js

@@ -0,0 +1,26 @@
+const express = require('express');
+const mongoose = require('mongoose');
+const app = express();
+const bodyParser = require('body-parser');
+const port = 8080;
+
+app.use(bodyParser.urlencoded({ extended:false }));
+app.use(bodyParser.json());
+
+mongoose.Promise = global.Promise;
+
+mongoose.connect('mongodb://tfb-database/hello_world').then(() => {
+    console.log('connected to mongo tfb-database hello_world');
+}).catch((err) => {
+    console.log('Failed connection attempt to Mongo: ', err);
+});
+
+const resolvers = require('./resolver-mongo');
+
+// Routes
+
+require('/routes.js')(app, resolvers);
+
+app.listen(port, () => {
+    console.log(`Listening on localhost:${port}`);
+});

+ 2 - 250
frameworks/JavaScript/express/graphql-mysql-app.js

@@ -1,264 +1,16 @@
 const express = require('express');
 const express = require('express');
 const app = express();
 const app = express();
-const graphqlHTTP = require('express-graphql');
-const escape = require('escape-html');
-const dateFormat = require('dateformat');
-
 const bodyParser = require('body-parser');
 const bodyParser = require('body-parser');
 const port = 8080;
 const port = 8080;
-const { makeExecutableSchema } = require('graphql-tools');
-
-const typeDefs = require('./schema');
-const resolvers = require('./resolver');
-
-const schema = makeExecutableSchema({
-    typeDefs,
-    resolvers
-});
 
 
 app.use(bodyParser.urlencoded({ extended:false }));
 app.use(bodyParser.urlencoded({ extended:false }));
 app.use(bodyParser.json());
 app.use(bodyParser.json());
 
 
 // Routes
 // Routes
 
 
-app.get('/json', async(req, res) => {
-    
-    const graphql = await graphqlHTTP((req, res, graphQLParams) => {
-        
-        graphQLParams.query = "{ helloWorld }";
-        graphQLParams.operationName = null;
-        graphQLParams.variables = {};
-
-        return graphqlOpts()
-    });
-
-    res.real_end = res.end;
-
-    res.end = (data) => {
-        
-        let toRet;
-        const json = JSON.parse(data.toString('utf8'));
-
-        if(json.data.helloWorld) {
-            toRet = json.data.helloWorld;
-        } else {
-            toRet = { helloWorld: null };
-        }
-        
-        setResponseHeaders(res, toRet.length);
-
-        res.real_end(toRet);
-    }
-
-    await graphql(req, res);
-});
-
-app.get('/db', async (req, res) => {
-    
-    const graphql = await graphqlHTTP((req, res, graphQLParams) => {
-    
-        graphQLParams.query = "{ singleDatabaseQuery { id, randomNumber }}";
-        graphQLParams.variables = {};
-        graphQLParams.operationName = null;
-    
-        return graphqlOpts();
-    });
-
-    formatResData(res, "singleDatabaseQuery");
-
-    await graphql(req, res);
-});
-
-app.get('/queries', async (req, res) => {
-    
-    const graphql = await graphqlHTTP((req, res, graphQLParams) => {
-        
-        let totalNumOfQueries = ensureQueryIsAnInt(req.query.queries);
-
-        graphQLParams.query = `{ multipleDatabaseQueries(total: ${totalNumOfQueries}) { id, randomNumber }}`
-        graphQLParams.variables = {};
-        graphQLParams.operationName = null;
-
-        return graphqlOpts();
-    });
-
-    formatResData(res, "multipleDatabaseQueries");
-
-    await graphql(req, res);
-});
-
-app.get('/fortunes', async (req, res) => {
-
-    const graphql = await graphqlHTTP((req, res, graphQLParams) => {
-
-        graphQLParams.query = "{ getAllFortunes { id, message } }"
-        graphQLParams.operationName = null;
-        graphQLParams.variables = {};
-
-        return graphqlOpts();
-    });
-
-    retrieveAndFormatAllFortunes(res);
-    
-    await graphql(req, res);
-});
-
-app.get('/updates', async (req, res) => {
-
-    const totalNumOfQueries = ensureQueryIsAnInt(req.query.queries);
-
-    const graphql = await graphqlHTTP((req, res, graphQLParams) => {
-
-        graphQLParams.query = `{ getRandomAndUpdate(total: ${totalNumOfQueries}) { id, randomNumber } }`
-        graphQLParams.operationName = null;
-        graphQLParams.variables = {};
-
-        return graphqlOpts();
-    });
-
-    formatResData(res, 'getRandomAndUpdate');
-
-    await graphql(req, res);
-});
-
-app.get('/plaintext', (req, res) => {
-
-    const responseTxt = "Hello, World!";
-
-    res.setHeader('Content-Length', responseTxt.length);
-    res.setHeader('Server', 'Express-GraphQL-MySQL');
-    res.contentType('text/plain');
-    res.status(200);
-
-    res.send(responseTxt);
-});
-
-// Helper Functions
-
-const ensureQueryIsAnInt = (queryString) => {
-
-    if(queryString === undefined) return 1;
-
-    const possibleInt = parseInt(queryString);
-    if(!possibleInt) return 1;
-
-    return possibleInt;
-};
-
-const graphqlOpts = (params) => {
-    return {
-        schema,
-        graphiql: false,
-        context: params || {}
-    }
-};
-
-const retrieveAndFormatAllFortunes = res => {
-
-    res.real_end = res.end;
-
-    res.end = async (data) => {
-        let toRet;
-        const json = JSON.parse(data.toString('utf8'));
-
-        if(json.data.getAllFortunes) {
-            toRet = json.data.getAllFortunes;
-        } else {
-            toRet = [];
-        }
-
-        const newFortune = { "id": 0, "message": "Additional fortune added at request time." };
-        toRet.push(newFortune);
-        toRet.sort((a, b) => (a.message < b.message) ? -1 : 1);
-
-        const htmlToRet = await spoofHTML(toRet);
-
-        res.contentType('html');
-        res.setHeader('Server', 'GraphQL-MySQL');
-        res.setHeader('Content-Length', htmlToRet.length + 32);
-        res.status(200);
-
-        res.real_end(htmlToRet);
-    }
-};
-
-const spoofHTML = arr => {
-
-    return new Promise((resolve, reject) => {
-
-        let count = 0;
-
-        let htmlToRet = `<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>`;
-
-        for (let fortune of arr) {
-
-            htmlToRet += `<tr><td>${escape(fortune.id)}</td><td>${escape(fortune.message)}</td></tr>`;
-            count++;
-        }
-
-        htmlToRet += '</table></body></html>';
-    
-        if(count == arr.length)resolve(htmlToRet);
-
-    });
-};
-
-const formatResData = (res, queryName) => {
-
-    res.real_end = res.end;
-    
-    res.end = (data) => {
-
-        const json = JSON.parse(data.toString('utf8'));
-        
-        let toRet = formatJson(queryName, json);
-
-        const jsonToRet = JSON.stringify(toRet);
-        
-        setResponseHeaders(res, jsonToRet.length);
-
-        res.real_end(jsonToRet);
-    };
-};
-
-const formatJson = (queryName, jsonData) => {
-
-    const isQueryReturningAnArray = {
-
-        singleDatabaseQuery: false,
-        multipleDatabaseQueries: true,
-        getRandomAndUpdate: true
-    };
-
-    if (isQueryReturningAnArray[queryName] == false) {
-
-        if(jsonData.data[`${queryName}`]) {
-            return {
-                id: jsonData.data[`${queryName}`].id,
-                randomNumber: jsonData.data[`${queryName}`].randomNumber
-            };
-        } else {
-            return {
-                id: null,
-                randomNumber: null
-            }
-        }
-    } else {
-
-        return jsonData.data[`${queryName}`] || [];
-    }
-};
-
-const setResponseHeaders = (res, jsonLength) => {
-
-    let now = new Date();
+const resolvers = require('./resolver');
 
 
-    res.status(200);
-    res.contentType('application/json', 'charset=UTF-8');
-    res.setHeader('Date', dateFormat(now, "ddd, dd mmm yyyy hh:MM:ss Z"));
-    res.setHeader('Server', 'GraphQL-Express-MySQL');
-    res.setHeader('Content-Length', jsonLength);
-};
+require('./routes')(app, resolvers);
 
 
 app.listen(port, () => {
 app.listen(port, () => {
     console.log(`Listening on localhost:${port}`);
     console.log(`Listening on localhost:${port}`);

+ 103 - 0
frameworks/JavaScript/express/resolver-mongo.js

@@ -0,0 +1,103 @@
+const mongoose = require('mongoose');
+
+const Schema = mongoose.Schema,
+  ObjectId = Schema.ObjectId;
+
+const WorldSchema = new mongoose.Schema({
+  id: Number,
+  randomNumber: Number
+}, {
+    collection: 'world'
+  }),
+  World = mongoose.model('world', WorldSchema);
+
+const FortuneSchema = new mongoose.Schema({
+  id: Number,
+  message: String
+}, {
+    collection: 'fortune'
+  }),
+  Fortune = mongoose.model('fortune', FortuneSchema);
+
+// Methods
+
+const randomizeNum = () => {
+
+    return Math.floor(Math.random() * 10000) + 1;
+};
+
+async function arrayOfRandomWorlds(totalWorldToReturn) {
+
+    var totalIterations = sanititizeTotal(totalWorldToReturn);
+    var arr = [];
+
+    return new Promise(async (resolve, reject) => {
+        for(var i = 0; i < totalIterations; i++) {
+            arr.push(await World.findOne({ id: randomizeNum() }));
+        }
+        if(arr.length == totalIterations) {
+            resolve(arr);
+        }
+    });
+};
+
+async function updateRandomWorlds(totalToUpdate) {
+
+    const totalIterations = sanititizeTotal(totalToUpdate);
+    var arr = [];
+
+    return new Promise(async (resolve, reject) => {
+        for(var i = 0; i < totalIterations; i++) {
+
+            arr.push(await World.findOneAndUpdate({ id: randomizeNum() }, { randomNumber: randomizeNum() }));
+        }
+        if(arr.length == totalIterations) {
+            resolve(arr);
+        }
+    });
+};
+
+const sanititizeTotal = (total) => {
+
+    var totalIterations;
+
+    if (!total) {
+        totalIterations = 1;
+    } else if(total < 501 && total > 0) {
+        totalIterations = total;
+    } else if (total > 500) {
+        totalIterations = 500;
+    } else {
+        totalIterations = 1;
+    }
+    return totalIterations;
+};
+
+const sayHello = () => {
+
+    var helloWorld = new Object;
+    helloWorld.message = "Hello, World!";
+
+    return JSON.stringify(helloWorld);
+};
+
+module.exports = {
+    Query: {
+        helloWorld: () => sayHello(),
+        getAllWorlds: async() => await World.find({}),
+        singleDatabaseQuery: async() => await World.findOne({ id: randomizeNum() }),
+        multipleDatabaseQueries: async(parent, args) => await arrayOfRandomWorlds(args.total),
+        getWorldById: async(parent, args) => await World.findById(args.id),
+        getAllFortunes: async() => await Fortune.find({}),
+        getRandomAndUpdate: async(parent, args) => await updateRandomWorlds(args.total)
+    },
+    Mutation: {
+        createWorld: async(parent, args) => {
+            let randInt = Math.floor(Math.random() * 1000) + 1;
+            return await World.create({ id: null, randomNumber: randInt });
+        },
+        updateWorld: async(parent, args) => {
+            return await World.update({id: args.id, randomNumber: args.randomNumber});
+        }
+    }
+}

+ 253 - 0
frameworks/JavaScript/express/routes.js

@@ -0,0 +1,253 @@
+const graphqlHTTP = require('express-graphql');
+const escape = require('escape-html');
+const dateFormat = require('dateformat');
+const { makeExecutableSchema } = require('graphql-tools');
+
+module.exports = (app, resolvers) => {
+    
+    const typeDefs = require('./schema');
+    
+    const schema = makeExecutableSchema({
+        typeDefs,
+        resolvers
+    });
+
+    app.get('/json', async(req, res) => {
+        
+        const graphql = await graphqlHTTP((req, res, graphQLParams) => {
+            
+            graphQLParams.query = "{ helloWorld }";
+            graphQLParams.operationName = null;
+            graphQLParams.variables = {};
+    
+            return graphqlOpts()
+        });
+    
+        res.real_end = res.end;
+    
+        res.end = (data) => {
+            
+            let toRet;
+            const json = JSON.parse(data.toString('utf8'));
+    
+            if(json.data.helloWorld) {
+                toRet = json.data.helloWorld;
+            } else {
+                toRet = { helloWorld: null };
+            }
+            
+            setResponseHeaders(res, toRet.length);
+    
+            res.real_end(toRet);
+        }
+    
+        await graphql(req, res);
+    });
+    
+    app.get('/db', async (req, res) => {
+        
+        const graphql = await graphqlHTTP((req, res, graphQLParams) => {
+        
+            graphQLParams.query = "{ singleDatabaseQuery { id, randomNumber }}";
+            graphQLParams.variables = {};
+            graphQLParams.operationName = null;
+        
+            return graphqlOpts();
+        });
+    
+        formatResData(res, "singleDatabaseQuery");
+    
+        await graphql(req, res);
+    });
+    
+    app.get('/queries', async (req, res) => {
+        
+        const graphql = await graphqlHTTP((req, res, graphQLParams) => {
+            
+            let totalNumOfQueries = ensureQueryIsAnInt(req.query.queries);
+    
+            graphQLParams.query = `{ multipleDatabaseQueries(total: ${totalNumOfQueries}) { id, randomNumber }}`
+            graphQLParams.variables = {};
+            graphQLParams.operationName = null;
+    
+            return graphqlOpts();
+        });
+    
+        formatResData(res, "multipleDatabaseQueries");
+    
+        await graphql(req, res);
+    });
+    
+    app.get('/fortunes', async (req, res) => {
+    
+        const graphql = await graphqlHTTP((req, res, graphQLParams) => {
+    
+            graphQLParams.query = "{ getAllFortunes { id, message } }"
+            graphQLParams.operationName = null;
+            graphQLParams.variables = {};
+    
+            return graphqlOpts();
+        });
+    
+        retrieveAndFormatAllFortunes(res);
+        
+        await graphql(req, res);
+    });
+    
+    app.get('/updates', async (req, res) => {
+    
+        const totalNumOfQueries = ensureQueryIsAnInt(req.query.queries);
+    
+        const graphql = await graphqlHTTP((req, res, graphQLParams) => {
+    
+            graphQLParams.query = `{ getRandomAndUpdate(total: ${totalNumOfQueries}) { id, randomNumber } }`
+            graphQLParams.operationName = null;
+            graphQLParams.variables = {};
+    
+            return graphqlOpts();
+        });
+    
+        formatResData(res, 'getRandomAndUpdate');
+    
+        await graphql(req, res);
+    });
+    
+    app.get('/plaintext', (req, res) => {
+    
+        const responseTxt = "Hello, World!";
+    
+        res.setHeader('Content-Length', responseTxt.length);
+        res.setHeader('Server', 'Express-GraphQL-MySQL');
+        res.contentType('text/plain');
+        res.status(200);
+    
+        res.send(responseTxt);
+    });
+    
+    // Helper Functions
+    
+    const ensureQueryIsAnInt = (queryString) => {
+    
+        if(queryString === undefined) return 1;
+    
+        const possibleInt = parseInt(queryString);
+        if(!possibleInt) return 1;
+    
+        return possibleInt;
+    };
+    
+    const graphqlOpts = (params) => {
+        return {
+            schema,
+            graphiql: false,
+            context: params || {}
+        }
+    };
+    
+    const retrieveAndFormatAllFortunes = res => {
+    
+        res.real_end = res.end;
+    
+        res.end = async (data) => {
+            let toRet;
+            const json = JSON.parse(data.toString('utf8'));
+    
+            if(json.data.getAllFortunes) {
+                toRet = json.data.getAllFortunes;
+            } else {
+                toRet = [];
+            }
+    
+            const newFortune = { "id": 0, "message": "Additional fortune added at request time." };
+            toRet.push(newFortune);
+            toRet.sort((a, b) => (a.message < b.message) ? -1 : 1);
+    
+            const htmlToRet = await spoofHTML(toRet);
+    
+            res.contentType('html');
+            res.setHeader('Server', 'GraphQL-MySQL');
+            res.setHeader('Content-Length', htmlToRet.length + 32);
+            res.status(200);
+    
+            res.real_end(htmlToRet);
+        }
+    };
+    
+    const spoofHTML = arr => {
+    
+        return new Promise((resolve, reject) => {
+    
+            let count = 0;
+    
+            let htmlToRet = `<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>`;
+    
+            for (let fortune of arr) {
+    
+                htmlToRet += `<tr><td>${escape(fortune.id)}</td><td>${escape(fortune.message)}</td></tr>`;
+                count++;
+            }
+    
+            htmlToRet += '</table></body></html>';
+        
+            if(count == arr.length)resolve(htmlToRet);
+    
+        });
+    };
+    
+    const formatResData = (res, queryName) => {
+    
+        res.real_end = res.end;
+        
+        res.end = (data) => {
+    
+            const json = JSON.parse(data.toString('utf8'));
+            
+            let toRet = formatJson(queryName, json);
+    
+            const jsonToRet = JSON.stringify(toRet);
+            
+            setResponseHeaders(res, jsonToRet.length);
+    
+            res.real_end(jsonToRet);
+        };
+    };
+    
+    const formatJson = (queryName, jsonData) => {
+    
+        const isQueryReturningAnArray = {
+    
+            singleDatabaseQuery: false,
+            multipleDatabaseQueries: true,
+            getRandomAndUpdate: true
+        };
+    
+        if (isQueryReturningAnArray[queryName] == false) {
+    
+            if(jsonData.data[`${queryName}`]) {
+                return {
+                    id: jsonData.data[`${queryName}`].id,
+                    randomNumber: jsonData.data[`${queryName}`].randomNumber
+                };
+            } else {
+                return {
+                    id: null,
+                    randomNumber: null
+                }
+            }
+        } else {
+    
+            return jsonData.data[`${queryName}`] || [];
+        }
+    };
+    
+    const setResponseHeaders = (res, jsonLength) => {
+    
+        let now = new Date();
+    
+        res.status(200);
+        res.contentType('application/json', 'charset=UTF-8');
+        res.setHeader('Date', dateFormat(now, "ddd, dd mmm yyyy hh:MM:ss Z"));
+        res.setHeader('Server', 'GraphQL-Express-MySQL');
+        res.setHeader('Content-Length', jsonLength);
+    };
+}