{"componentChunkName":"component---src-templates-post-js","path":"/post/node-is-simple-part-1","result":{"data":{"contentfulHero":{"coverImage":{"file":{"url":"//images.ctfassets.net/xmu5vdhtphau/1jqMTE2RJBiMLIcZAnu6It/5495c6ec7df10a55768df442e73fe4b2/home-hero-min.jpg","fileName":"home-hero-min.jpg"}}}},"pageContext":{"post":{"id":"96ed4651-99ad-523e-a370-f09f0ba8d9eb","slug":"node-is-simple-part-1","title":"Node is Simple — Part 1","createdAt":"Jun 30, 2020","tweetText":null,"type":"blog","video":null,"podcast":null,"categories":[{"id":"4384d042-dd09-5c7b-967b-95eab1334a2c","name":"Node.js","slug":"node-js"},{"id":"50768c9e-fc69-55ce-8a68-88617e5bcfbd","name":"How To","slug":"how-to"}],"image":{"file":{"url":"//images.ctfassets.net/xmu5vdhtphau/1wPDiEeSUpjD3lRRdev6UP/fa2b5a348289eb756540991b919747db/1_q4C3LGm0jGTaDtoSco5d1w.jpg","fileName":"1_q4C3LGm0jGTaDtoSco5d1w.jpg"}},"author":{"name":"Nipuna Weerasekara","bio":{"childMarkdownRemark":{"html":"<p>Part time web developer, full time dreamer… Find me @ <a href=\"https://niweera.gq\">https://niweera.gq</a></p>"}},"avatar":{"file":{"fileName":"1_cuJOF_sqBLbMA69vCFMqEQ.jpeg","url":"//images.ctfassets.net/xmu5vdhtphau/4iEstuN4qOq6h1vKjwpPRW/413c90f5bfa0c51170b560407e31c7c6/1_cuJOF_sqBLbMA69vCFMqEQ.jpeg"}}},"bodyContent":{"childMarkdownRemark":{"html":"<p><strong><em>tl;dr</em></strong> — <em>This is the first article of the</em> <strong><em>Node is Simple</em></strong> <em>article series. In this article series, I will be discussing how to create a simple and secure NodeJS, Express, MongoDB web application.</em></p>\n<p>First of all let me give a big shout out to <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript\">JavaScript</a>, who’s going to turn 25 years old this year. W/O JavaScript, the world would be a much darker place indeed. 😁 In this article series what I am going to do is create an API with <a href=\"https://nodejs.org/\">NodeJS</a>, <a href=\"http://expressjs.com/\">ExpressJS</a>, and <a href=\"https://www.mongodb.com/\">MongoDB</a>. I know there is a vast ocean of tutorials out there, describing how to build an API with these technologies, but the thing is that I have never found a very comprehensive all in one tutorial where you get the knowledge of the following things.</p>\n<ol>\n<li>Setting up a basic NodeJS, Express web app with SSL/TLS.</li>\n<li>Setting up <a href=\"https://eslint.org/\">ESLint</a> in your favorite editor or IDE.</li>\n<li>Adding MongoDB as the database.</li>\n<li>Creating basic CRUD endpoints and testing with <a href=\"https://www.postman.com/\">Postman</a>.</li>\n<li>Uploading files and view them using MongoDB <a href=\"https://docs.mongodb.com/manual/core/gridfs\">GridFS</a>.</li>\n<li>Creating custom middleware with Express.</li>\n<li>Add logging for the web application.</li>\n<li>Securing endpoints with <a href=\"https://jwt.io/\">JWT</a> authentication.</li>\n<li>Validating the input using <a href=\"https://hapi.dev/module/joi/\">@Hapi/Joi</a>.</li>\n<li>Adding an <a href=\"https://swagger.io/specification/\">OpenAPI Swagger</a> Documentation.</li>\n<li>Caching the responses with <a href=\"https://redis.io/\">Redis</a>.</li>\n<li>Load balancing with <a href=\"https://pm2.keymetrics.io/\">PM2</a>.</li>\n<li>Testing the API using <a href=\"https://www.chaijs.com/\">Chai</a>, <a href=\"https://mochajs.org/\">Mocha</a>.</li>\n<li>Create a CI/CD pipeline.</li>\n<li>Deploying to your favorite platform.</li>\n</ol>\n<p>Well if you have done all of these things with your web application, it would be awesome. Since I learned all of these the hard way, I want to share them with all of you. Because sharing is caring 😇.</p>\n<p>Since this tutorial is a series I won’t be making this a long; boring to read one. In this first article, I will describe how to set up a simple NodeJS and Express app with SSL/TLS. Just that, nothing else.</p>\n<p><img src=\"//images.ctfassets.net/xmu5vdhtphau/6LsNJMcGwfz5MxaiPSf55W/6515ce3dea77d2caceb7c434e51e4287/maxresdefault.jpg\" alt=\"maxresdefault\"></p>\n<p><strong>On your feet soldier, we are starting.</strong></p>\n<p>First of all, let’s create the folder structure of our web application.</p>\n<p><img src=\"//images.ctfassets.net/xmu5vdhtphau/X8HViCF0BVbb4gPN1ojt4/909fea9e6991bbde125497f3c92d8016/1_jnP_vv30BKCx84yOSHbTRQ.png\" alt=\"1 jnP vv30BKCx84yOSHbTRQ\"></p>\n<figcaption>Figure 1: node-is-simple folder structure</figcaption>\n<p>As shown in figure 1, you need to create the folders and the <em>index.js</em> file. If you use Linux or, Git Bash on Windows, let’s make a simple script to do this. So you won’t have to do this again when you need to create another application. (We are so lazy aren’t we? 😂)</p>\n<pre><code>#!/usr/bin/env bash\n\n############################################################\n# Remember to create a folder for your project first       #\n# And run `npm init` to initialize a node project          #\n# Inside that project folder run this bootstrap.sh script  #\n############################################################\n\n# Create the folders\nmkdir config controllers errors middleware models services swagger utilities database\n\n# Create the index.js file\ntouch index.js\n\n############################################################\n# Remember to check if you have node and npm installed     #\n# I assume you have installed node and npm                 #\n############################################################\n\n# Install required packages\nnpm install express chalk --save\n\n#That's it folks!\n</code></pre>\n<p>Let’s go through it again.</p>\n<p>First, you need to create a folder for your project and run <em>npm init</em> and initialize your application. With this, you can specify a great name to your project, your license of preference, and many more. Ah, I just forgot. You need to check if you have the current version of Node and <a href=\"https://www.npmjs.com/\">NPM</a> installed in your machine. I hope you know how to install NodeJS on your computer. If not please refer to the following links.</p>\n<p><a href=\"https://www.guru99.com/download-install-node-js.html\">How to Download &#x26; Install Node.js - NPM on Windows</a></p>\n<p><a href=\"https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-18-04\">How To Install Node.js on Ubuntu 18.04</a></p>\n<p>After doing that just run this <em>bootstrap.sh</em> bash script inside your project folder and it will create a simple Node, Express application. So simple right?</p>\n<p>After creating the necessary folder structure let’s set up the Express application. Let’s go to the <em>index.js</em> file on the root folder and add these lines.</p>\n<pre><code>const express = require(\"express\");\nconst chalk = require(\"chalk\");\nconst http = require(\"http\");\nconst https = require(\"https\");\nconst config = require(\"./config\");\n\nconst HTTP_PORT = config.HTTP_PORT;\nconst HTTPS_PORT = config.HTTPS_PORT;\nconst SERVER_CERT = config.SERVER_CERT;\nconst SERVER_KEY = config.SERVER_KEY;\n\nconst app = express();\nconst MainController = require(\"./controllers\");\n\napp.use(\"\", MainController);\napp.set(\"port\", HTTPS_PORT);\n\n/**\n * Create HTTPS Server\n */\n\nconst server = https.createServer(\n  {\n    key: SERVER_KEY,\n    cert: SERVER_CERT\n  },\n  app\n);\n\nconst onError = error => {\n  if (error.syscall !== \"listen\") {\n    throw error;\n  }\n\n  const bind =\n    typeof HTTPS_PORT === \"string\"\n      ? \"Pipe \" + HTTPS_PORT\n      : \"Port \" + HTTPS_PORT;\n\n  switch (error.code) {\n    case \"EACCES\":\n      console.error(chalk.red(`[-] ${bind} requires elevated privileges`));\n      process.exit(1);\n      break;\n    case \"EADDRINUSE\":\n      console.error(chalk.red(`[-] ${bind} is already in use`));\n      process.exit(1);\n      break;\n    default:\n      throw error;\n  }\n};\n\nconst onListening = () => {\n  const addr = server.address();\n  const bind = typeof addr === \"string\" ? `pipe ${addr}` : `port ${addr.port}`;\n  console.log(chalk.yellow(`[!] Listening on HTTPS ${bind}`));\n};\n\nserver.listen(HTTPS_PORT);\nserver.on(\"error\", onError);\nserver.on(\"listening\", onListening);\n\n/**\n * Create HTTP Server (HTTP requests will be 301 redirected to HTTPS)\n */\nhttp\n  .createServer((req, res) => {\n    res.writeHead(301, {\n      Location:\n        \"https://\" +\n        req.headers[\"host\"].replace(\n          HTTP_PORT.toString(),\n          HTTPS_PORT.toString()\n        ) +\n        req.url\n    });\n    res.end();\n  })\n  .listen(HTTP_PORT)\n  .on(\"error\", onError)\n  .on(\"listening\", () =>\n    console.log(chalk.yellow(`[!] Listening on HTTP port ${HTTP_PORT}`))\n  );\n\nmodule.exports = app;\n</code></pre>\n<p>Don’t run this yet, since we haven’t done anything yet. I know this is a bit too much just bear with me, I’ll explain everything. What we are doing here is, first we create an HTTP server and then we create an HTTPS server. Then we redirect all the HTTP traffic to the HTTPS server. First of all, we need to create certificates to use inside the HTTPS server. It is a little bit of pain, but it’ll worth it. This is a good resource about creating SSL certificates for your Node application.</p>\n<p><a href=\"https://www.sitepoint.com/how-to-use-ssltls-with-node-js/\">How to Use SSL/TLS with Node.js</a></p>\n<p>I am a little bit of a lazy person so I’ll just generate <em>server.cert</em> and <em>server.key</em> files using this link.</p>\n<p><a href=\"https://www.selfsignedcertificate.com/\">Self-Signed Certificate Generator</a></p>\n<p>Inside the server name input, you just have to provide your domain name. For this purpose, I’ll use the <em>localhost</em> as the domain name.</p>\n<p>After generating the <em>*.cert</em> and <em>*.key</em> files copy them to the <em>/config</em> folder. And rename them to <em>server.cert</em> and <em>server.key.</em></p>\n<p>Now let’s import the certificates and make them useful. Inside the <em>/config</em> folder create the file <em>index.js</em> and add these lines.</p>\n<pre><code>const fs = require(\"fs\");\n\nconst SERVER_CERT = fs.readFileSync(__dirname + \"/server.cert\", \"utf8\");\nconst SERVER_KEY = fs.readFileSync(__dirname + \"/server.key\", \"utf8\");\n\nmodule.exports = {\n  SERVER_CERT,\n  SERVER_KEY,\n  HTTP_PORT: 8080,\n  HTTPS_PORT: 8081\n};\n</code></pre>\n<p>Not so simple after all right? Well, let’s see.</p>\n<p>Now that we have set up the certificates, let’s create a simple controller (endpoint) to our application and check that out. First, let’s got to the <em>/controllers</em> folder and create an <em>index.js</em> file. Inside that add the following lines.</p>\n<pre><code>const router = require(\"express\").Router();\nconst asyncWrapper = require(\"../utilities/async-wrapper\");\n\n/** @route  GET /\n *  @desc   Root endpoint\n *  @access Public\n */\nrouter.get(\n  \"/\",\n  asyncWrapper(async (req, res) => {\n    res.send({\n      message: \"Hello World!\",\n      status: 200\n    });\n  })\n);\n\nmodule.exports = router;\n</code></pre>\n<p><strong><em>asyncWrapper</em> what is that???</strong></p>\n<p>Let me tell you about that. Async Wrapper is a wrapper function that will catch all the errors happen inside your code and returns them to the error handling middleware. I’ll explain this a little more when I am discussing Express middleware. Now let’s create this infamous <em>asyncWrapper.</em> Go to the <em>/utilities</em> folder and create the two following files.</p>\n<p><code>**async-wrapper.js**</code></p>\n<pre><code>module.exports = requestHandler => (req, res, next) =>\n  requestHandler(req, res).catch(next);\n</code></pre>\n<p><code>**async.wrapper.d.ts**</code> (Async wrapper type definition file)</p>\n<p>We have done it, folks, we have done it. Now let’s check this beautiful Express app at work. Let’s run the web application first. Let’s go to the project folder and in the terminal (or Git Bash on Windows) run the following line.</p>\n<p><em>node index.js</em></p>\n<p>After that let’s fire up your favorite browser (mine is Chrome 😁) and hit the endpoint at,</p>\n<p><a href=\"https://localhost:8081/\">https://localhost:8081/</a></p>\n<p>Don’t worry if your browser says it is not secure to go to this URL. You trust yourself, don’t you? So let’s accept the risk and go ahead.</p>\n<p><img src=\"//images.ctfassets.net/xmu5vdhtphau/6376WfRDmfD2l7nNerhgOE/e67006295d61ab844c1e8531827330de/1_-j7gNIpPkuqIQj_OQf9Y0A.png\" alt=\"1 -j7gNIpPkuqIQj OQf9Y0A\"></p>\n<figcaption>This is the warning I told you about. (FYI, this screenshot is from Firefox)</figcaption>\n<p>Now if you can see something like this,</p>\n<p><img src=\"//images.ctfassets.net/xmu5vdhtphau/5fBDIxDCiysuWEzT5A05vb/de95f050a10cc91ab51695f37ea1506c/1_UNQTECXa-hXe2YM4ANG0DQ.png\" alt=\"1 UNQTECXa-hXe2YM4ANG0DQ\"></p>\n<figcaption>Response from [https://localhost:8081](https://localhost:8081)</figcaption>\n<p>You have successfully created a NodeJS, Express application. Also since we have set up an HTTP server, you can try this URL too. <a href=\"http://localhost:8080/\">http://localhost:8080</a></p>\n<p>If you go to this URL, you’ll see that you’ll be redirected to <a href=\"https://localhost:8081/\">https://localhost:8081</a></p>\n<p>Now that’s the magic with our Express application. Awesome right? So this is it for this tutorial. In the next tutorial, I’ll tell you all about adding MongoDB as the database.</p>\n<p><a href=\"https://github.com/Niweera/node-is-simple\">https://github.com/Niweera/node-is-simple</a></p>\n<p>This is the GitHub repo for this tutorial and I’ll update this repo as the tutorial grows. Check for the commit messages for the snapshot of the repo for a particular tutorial. If you have any queries, don’t forget to hit me up on any social media as shown on my website.</p>\n<p><a href=\"https://niweera.gq\">https://niweera.gq/</a></p>\n<p>So until we meet again with part two of this tutorial series, happy coding…</p>"}}}}}}