|
| 1 | +const express = require('express'); |
| 2 | +const bodyParser = require('body-parser'); |
| 3 | +const cors = require('cors'); |
| 4 | +const http = require('http'); |
| 5 | + |
| 6 | +/** |
| 7 | + * Class responsible for resolving paths of API endpoints and combining them |
| 8 | + * them into an express server. |
| 9 | + */ |
| 10 | +class SceRpcApiServer { |
| 11 | + /** |
| 12 | + * Store port information, create express server object and configure |
| 13 | + * BodyParser options. |
| 14 | + * @param {(String|Array<String>)} pathToEndpoints The path to a single |
| 15 | + * server file, directory or array of directories/files; |
| 16 | + * @param {Number} port The port for the server to listen on. |
| 17 | + * @param {String} prefix The prefix of the api endpoints to send requests |
| 18 | + * to, e.g. /api/Event/addEvent, with /api/ being the prefix. |
| 19 | + */ |
| 20 | + constructor(pathToEndpoints, port, prefix = '/api/') { |
| 21 | + this.runningInProduction = process.env.NODE_ENV === 'production'; |
| 22 | + this.port = port; |
| 23 | + this.pathToEndpoints = pathToEndpoints; |
| 24 | + this.prefix = prefix; |
| 25 | + this.app = express(); |
| 26 | + |
| 27 | + this.app.use(cors()); |
| 28 | + this.app.use( |
| 29 | + bodyParser.json({ |
| 30 | + // support JSON-encoded request bodies |
| 31 | + limit: '50mb', |
| 32 | + strict: true |
| 33 | + }) |
| 34 | + ); |
| 35 | + this.app.use( |
| 36 | + bodyParser.urlencoded({ |
| 37 | + // support URL-encoded request bodies |
| 38 | + limit: '50mb', |
| 39 | + extended: true |
| 40 | + }) |
| 41 | + ); |
| 42 | + } |
| 43 | + |
| 44 | + /** |
| 45 | + * This function is responsible for taking the pathToEndpoints instance |
| 46 | + * variable and resolving API endpoints from it. |
| 47 | + */ |
| 48 | + async initializeEndpoints() { |
| 49 | + // Because this.pathToEndpoints can either be an array or |
| 50 | + // string, we need to check before initializing the endpoints. |
| 51 | + if (Array.isArray(this.pathToEndpoints)) { |
| 52 | + this.pathToEndpoints.map((apiPath) => { |
| 53 | + this.app.use(this.prefix, require(apiPath)); |
| 54 | + }); |
| 55 | + } else { |
| 56 | + this.app.use(this.prefix, require(this.pathToEndpoints)); |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + /** |
| 61 | + * Create the http server and start listening on |
| 62 | + * the supplied port. |
| 63 | + */ |
| 64 | + openConnection() { |
| 65 | + this.server = http.createServer(this.app); |
| 66 | + const { port } = this; |
| 67 | + this.server.listen(port, function() { |
| 68 | + console.debug(`Now listening on port ${port}`); |
| 69 | + }); |
| 70 | + } |
| 71 | + |
| 72 | + /** |
| 73 | + * Return the current instance of the HTTP server. This function is useful |
| 74 | + * for making chai HTTP requests in our API testing files. |
| 75 | + * @returns {http.Server} The current instance of the HTTP server. |
| 76 | + */ |
| 77 | + getServerInstance() { |
| 78 | + return this.server; |
| 79 | + } |
| 80 | + |
| 81 | + /** |
| 82 | + * Stop the server. |
| 83 | + */ |
| 84 | + closeConnection() { |
| 85 | + this.server.close(); |
| 86 | + } |
| 87 | +} |
| 88 | + |
| 89 | +// This if statement checks if the module was require()'d or if it was run |
| 90 | +// by node server.js. If we are not requiring it and are running it from the |
| 91 | +// command line, we create a server instance and start listening for requests. |
| 92 | +if (typeof module !== 'undefined' && !module.parent) { |
| 93 | + const apiRoutes = [ |
| 94 | + __dirname + '2DPrinting.js', |
| 95 | + __dirname + '3DPrinting.js', |
| 96 | + __dirname + 'LedSign.js' |
| 97 | + ]; |
| 98 | + const server = new SceRpcApiServer( |
| 99 | + apiRoutes, 8083, '/SceRpcApi/'); |
| 100 | + server.initializeEndpoints().then(() => { |
| 101 | + server.openConnection(); |
| 102 | + }); |
| 103 | +} |
| 104 | + |
| 105 | +module.exports = { SceRpcApiServer }; |
0 commit comments