<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Express.js - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Express.js - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 19 May 2026 10:28:53 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/expressjs/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How Does the Morgan Express Middleware Library Work? Explained with Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ Morgan is an Express middleware library that examines HTTP requests and logs details of the request to an output. It is one of the most popular Express middleware libraries with over 8,000 GitHub star ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-does-the-morgan-library-work/</link>
                <guid isPermaLink="false">68dacc9e86b3b4616655000a</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Libraries ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Orim Dominic Adah ]]>
                </dc:creator>
                <pubDate>Mon, 29 Sep 2025 18:14:54 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1759169256698/9cb4e87a-2bc3-49ac-b1a6-b9d02d410ea1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><a href="https://www.npmjs.com/package/morgan">Morgan</a> is an Express middleware library that examines HTTP requests and logs details of the request to an output. It is one of the most popular Express middleware libraries with over 8,000 GitHub stars and more than 9,000 npm libraries dependent on it. GitHub reports that Morgan is used by at least 3.6 million repositories.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>This guide explains the Morgan library’s code to help you understand how it works under the hood. This is helpful if you have experience with Express and you're interested in understanding the inner workings that produce Morgan log lines. An understanding of closures in JavaScript is helpful for this guide but not necessary.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-what-is-an-express-middleware">What is an Express Middleware?</a></p>
</li>
<li><p><a href="#heading-a-brief-overview-of-how-morgan-works">A Brief Overview of How Morgan Works</a></p>
</li>
<li><p><a href="#heading-what-is-a-morgan-token">What is a Morgan Token?</a></p>
</li>
<li><p><a href="#heading-what-happens-when-morgan-is-initialised">What Happens When Morgan is Initialised?</a></p>
</li>
<li><p><a href="#heading-what-happens-when-morgan-captures-a-request">What Happens When Morgan Captures a Request?</a></p>
</li>
<li><p><a href="#heading-next-steps">Next Steps</a></p>
</li>
</ul>
<h2 id="heading-what-is-an-express-middleware">What is an Express Middleware?</h2>
<p>According to <a href="https://expressjs.com/en/guide/writing-middleware.html">Express documentation</a>, a middleware is a function that has access to the request and response objects and the <code>next</code> function of an Express request cycle. They are generally used to intercept requests to execute side-effects before or after the request is handled by its route handler.</p>
<p>A middleware can be used to:</p>
<ul>
<li><p><strong>Make changes to the request and the response objects</strong>: It can make changes to the request and response objects by attaching properties like headers and cookies to them.</p>
</li>
<li><p><strong>Terminate the request-response cycle</strong>: It can terminate a request and send a response to the client before or after the request is handled by its route handler.</p>
</li>
<li><p><strong>Execute the next middleware in the stack</strong>: It can trigger the execution of the middleware after it via the <code>next</code> function argument.</p>
</li>
</ul>
<p>A function called <code>next</code> is usually the third argument of a middleware and it is used to pass the request to the next middleware. If the <code>next</code> function is not executed in a middleware and the request is not explicitly terminated by sending a response to the client, the request will be left hanging.</p>
<p>The interface of a middleware is shown in the code snippet below:</p>
<pre><code class="language-javascript">function middleware(request, response, next) {
    // operations to be performed when this middleware is executed
    next() // execute the next middleware
}
</code></pre>
<p>A middleware can intercept and handle cases where preceding middleware or route handlers throw unhandled errors. These middlewares are usually called error handler middlewares and accept four arguments as shown below:</p>
<pre><code class="language-javascript">function errorHandlerMiddleware(error, request, response, next) {}
</code></pre>
<p>The <code>error</code> argument represents the unhandled error.</p>
<p>Some middlewares like Morgan and <a href="https://www.npmjs.com/package/cors">cors</a> are higher-order functions. They accept configuration arguments when initialised and return a middleware function, executed by Express when hit by a request.</p>
<pre><code class="language-javascript">function initialise(...configArgs) {
    // make use of configArgs here
    return function middleware(request, response, next) {
        // can also make use of configArgs here
        // operations to perform when this middleware is hit by a request
        next() // execute the next middleware
    }
}
</code></pre>
<h2 id="heading-a-brief-overview-of-how-morgan-works">A Brief Overview of How Morgan Works</h2>
<pre><code class="language-javascript">import morgan from "morgan"
// morgan(format, [options])
morgan("tiny") // initialise morgan and return a middleware
// Sample output: GET /tiny 200 2 - 0.188 ms
</code></pre>
<p>Morgan is initialised by executing it with a required <code>format</code> argument and an optional <code>options</code> argument. The <code>format</code> argument may be:</p>
<ul>
<li><p>A predefined Morgan format name</p>
</li>
<li><p>A format string containing predefined tokens (a token set)</p>
</li>
<li><p>A custom format function that returns a log output in the form of a string</p>
</li>
</ul>
<p>The <code>options</code> argument is optional. It is an object with three properties:</p>
<ul>
<li><p><code>immediate</code> (boolean): If <code>true</code>, the log output will be created on receiving requests and not when a response is sent. It defaults to <code>false</code>.</p>
</li>
<li><p><code>skip</code> (function): The function accepts the request and response objects as arguments and returns a boolean value based on the logic in it. If the value returned is <code>true</code>, the log line for a request is not logged. <code>skip</code> defaults to <code>false</code>.</p>
</li>
<li><p><code>stream</code> (WritableStream): Output stream for writing log lines. It defaults to <code>process.stdout</code> but it could be a file.</p>
</li>
</ul>
<p>When Morgan is initialised, it stores its initialisation arguments in closure variables and returns a middleware function. The function is executed when a request hits it and it outputs a log line for the request. The format and where the log line is output to are determined by the initialisation arguments.</p>
<h2 id="heading-what-is-a-morgan-token">What is a Morgan Token?</h2>
<p>A Morgan token is a string prefixed by a colon, corresponding to property of the request or response objects or a user-generated value. For example, the request method’s token is <code>':method'</code> and the response status code’s token is <code>':status'</code>. A token can also accept an argument to customise its behaviour. For instance, in <code>':date[format]'</code>, <code>format</code> can be replaced with <code>clf</code>, <code>iso</code> or <code>web</code> to set the format of the date that would be in the log line. An understanding of Morgan tokens is crucial to understanding how Morgan works.</p>
<p>You can create new tokens using the <code>morgan.token</code> function. The code snippet below creates a new token called <code>':type'</code> which corresponds to the response <code>Content-Type</code> header:</p>
<pre><code class="language-javascript">morgan.token('type', function (req, res) {
    return res.headers['content-type']
})
</code></pre>
<p>Morgan has predefined named format (<code>tiny</code>, <code>dev</code>, <code>short</code>, <code>combined</code>, <code>common</code>) strings containing a set of tokens and each named format has its specific token set and configuration. The token set for tiny is <code>':method :url :status :res[content-length] - :response-time ms'</code>. Morgan can accept these named formats as the value of the <code>format</code> argument.</p>
<p>Aside from accepting named formats, Morgan can also accept a token set (for example <code>':method :url :status :res[content-length] - :response-time ms'</code>) as the <code>format</code> argument. A third argument type that Morgan accepts as the <code>format</code> argument is a format function. A format function accepts three arguments and returns a string that forms the log line for each request. For example, the format function described below:</p>
<pre><code class="language-javascript">morgan(function (tokens, req, res) {
    return `method: ${tokens.method(req, res)}
path: ${tokens.url(req, res)}
code: ${tokens.status(req, res)}`
})
</code></pre>
<p>This will produce a log line output like:</p>
<pre><code class="language-bash">method: GET
path: /
code: 200
</code></pre>
<p><code>tokens.method</code>, <code>tokens.url</code> and <code>tokens.status</code> are examples of functions on the <code>morgan</code> object that can generate values to be logged. To illustrate, the table below shows sample token methods, their token and sample output values:</p>
<table>
<thead>
<tr>
<th>Token method</th>
<th>Token</th>
<th>Sample output</th>
</tr>
</thead>
<tbody><tr>
<td>method</td>
<td><code>“:method”</code></td>
<td>GET</td>
</tr>
<tr>
<td>url</td>
<td><code>“:url”</code></td>
<td>/</td>
</tr>
<tr>
<td>status</td>
<td><code>”:status”</code></td>
<td>200</td>
</tr>
</tbody></table>
<p>The next sections of this article explain how Morgan works under the hood. To follow along, open up <a href="https://github.com/expressjs/morgan/blob/master/index.js">Morgan’s index.js file on GitHub</a>.</p>
<h2 id="heading-what-happens-when-morgan-is-initialised">What Happens When Morgan is Initialised?</h2>
<p>When Morgan is initialised, it makes a copy of the arguments provided to it. For arguments that were not provided, Morgan sets default values for them. For instance, if no <code>format</code> string argument was provided, Morgan uses the <code>'default'</code> named format and logs a deprecation notice afterwards with a suggested fix.</p>
<p>Morgan then sets up the <code>formatLine</code> function - the function that creates and returns the log line for a request when executed. How does it create the log line?</p>
<p>First, Morgan checks if <code>format</code> is a format function. If it is, the format function is assigned to <code>formatLine</code> and next, Morgan sets up the output stream. If <code>format</code> is not a function, it is passed as an argument to <code>getFormatFunction</code>. <code>getFormatFunction</code> accepts <code>format</code> and looks up Morgan’s object store to check if <code>format</code> is:</p>
<ul>
<li><p>One of Morgan’s named formats or a user-defined named format created via <code>morgan.format</code></p>
</li>
<li><p>A token set</p>
</li>
</ul>
<p>If it is neither of the two, Morgan uses the <code>default</code> named format.</p>
<pre><code class="language-javascript">function getFormatFunction (name) { // `name` is also `format`
  var fmt = morgan[name] || name || morgan.default

  return typeof fmt !== 'function'
    ? compile(fmt)
    : fmt
}
</code></pre>
<p>If the named format corresponds to a format function after the lookup, Morgan returns the format function, which is then assigned to <code>formatLine</code>, else, it corresponds to a token set. Morgan compiles the token set into a format function through the <code>compile</code> function - one of the most important functions in the Morgan package.</p>
<h3 id="heading-how-the-compile-function-works">How the <code>compile</code> Function Works</h3>
<p>The <code>compile</code> function accepts a token set and returns a function that has the interface of a format function. How does it do this?</p>
<p>With the JavaScript <code>replace</code> method, it uses a RegEx to search for all occurrences of a token in the token set and replaces each occurrence. If the token set is <code>':method :res[content-length] - :response-time ms'</code> , the RegEx <code>replace</code> method replaces the tokens as illustrated in the table below:</p>
<table>
<thead>
<tr>
<th>name</th>
<th>arg</th>
<th>replacement string</th>
</tr>
</thead>
<tbody><tr>
<td>‘method’</td>
<td><code>undefined</code></td>
<td>`(tokens["method"](req, res)</td>
</tr>
<tr>
<td>‘res’</td>
<td><code>’content-length’</code></td>
<td>`(tokens["res"](req, res, "content-length")</td>
</tr>
<tr>
<td>‘response-time’</td>
<td>undefined</td>
<td>`(tokens["response-time"](req, res)</td>
</tr>
</tbody></table>
<p>The result of the RegEx replace is prefixed with <code>"use strict"\n return ""</code> and ends up producing the string below:</p>
<pre><code class="language-plaintext">"use strict" 
    return "" +  
    (tokens["method"](req, res) || "-") + " " +   
    (tokens["res"](req, res, "content-length") || "-") + " - " + 
    (tokens["response-time"](req, res) || "-") + " ms"
</code></pre>
<p>The string above is used to create a format function using the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/Function">Function constructor</a> and returned as:</p>
<pre><code class="language-javascript">function (tokens, req, res) {
  "use strict"
  return "" +
    (tokens["method"](req, res) || "-") + " " +
    (tokens["res"](req, res, "content-length") || "-") + " - " +
    (tokens["response-time"](req, res) || "-") + " ms"
}
</code></pre>
<p>The format function is eventually stored in <code>formatLine</code>.</p>
<p>When <code>formatLine</code> is executed with <code>morgan</code> as the <code>tokens</code> argument, it will create a log line. In the case of the sample token set, it will create a log line that will look like GET 20 - 1.233 ms.</p>
<p>After creating the <code>formatLine</code> function, Morgan uses the <code>createBufferStream</code> function to set up the streaming of the log lines created to the preferred output if set by <code>options.stream</code>. If <code>options.stream</code> is not set, it uses <code>process.stdout</code>.</p>
<p>Morgan does all this setting up so that it can create log lines quickly on capturing a request. It will be inefficient to do all of these for each request.</p>
<h2 id="heading-what-happens-when-morgan-captures-a-request">What Happens When Morgan Captures a Request?</h2>
<p>When Morgan captures a request, it stores the IP address of the client using the <code>getip</code> function. Next, it stores the time that the request was triggered in the <code>startAt</code> property of the request object.</p>
<p>Then Morgan tries to generate the log line for the request and log it by executing the <code>logRequest</code> function. Morgan checks if the log line should be output on request, and if it should, Morgan executes <code>logRequest</code> and executes <code>next</code> thereafter to pass the request to the next middleware.</p>
<pre><code class="language-javascript">if (immediate) {
  logRequest()
} else {
  onHeaders(res, recordStartTime)
  onFinished(res, logRequest)
}

next()
</code></pre>
<p>If the log output should be created on response, Morgan registers two functions on the response object event listeners:</p>
<ul>
<li><p><strong>An function to be run when headers start to be written to the response object</strong>: When this listener is triggered, it records the time when headers start to be written to the response object as <code>_startAt</code> and <code>startTime</code>. These values are used to calculate the response time and the total time of the request.</p>
</li>
<li><p><strong>A function to be run when the request closes, finishes or errors</strong>: It executes <code>logRequest</code> when this event occurs.  </p>
<p>Just when Node.js starts sending a response to the client, a <code>_startAt</code> property – the time when the response starts getting sent – is attached to the response object. The absolute difference between <code>_startAt</code> on the request object and <code>_startAt</code> on the response object is the response time of the request and can be seen through ":response-time".  </p>
<p>":total-time" is the total time taken from when the request was received to when the response was completely sent. In practice, total-time will be equal to or slightly greater than response-time, depending on how long it takes to write the response body to the stream after the response has started.</p>
</li>
</ul>
<p>Within <code>logRequest</code>, Morgan checks the value of the <code>skip</code> option. If it is a function, it is executed and if it returns <code>true</code>, Morgan doesn’t create a log output for the request and it exits.</p>
<pre><code class="language-javascript">function logRequest () {
  if (skip !== false &amp;&amp; skip(req, res)) {
    debug('skip request')
    return
  }

  var line = formatLine(morgan, req, res)

  if (line == null) {
    debug('skip line')
    return
  }

  stream.write(line + '\n')
};
</code></pre>
<p>If <code>skip</code> is <code>false</code> or executing it evaluates to <code>false</code>, Morgan generates the log line for the request using <code>formatLine</code>. If the log line is <code>null</code>, Morgan exits, else it sends the log line to the output medium and exits.</p>
<h2 id="heading-next-steps">Next Steps</h2>
<p>You have learned how the Morgan Express middleware outputs logs. You now have foundational skills to pick up another middleware or Node.js library like helmet or cors that you use and study it to see how it works. Choose one, study it, write about it, and share it with others.</p>
<p>If you have any questions, you can connect with me on <a href="https://www.linkedin.com/in/orimdominicadah/">LinkedIn</a>. I’ll be happy to respond.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a CRUD API – NodeJS and Express Project for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ An API is a technology that powers communication between software applications on the internet. API stands for Application Programming Interface, and it is basically a set of rules and protocols that define how different software can interact with ea... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-crud-api-project/</link>
                <guid isPermaLink="false">66ba305cf1ac6be9964fe7ac</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ backend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ crud ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Victor Yakubu ]]>
                </dc:creator>
                <pubDate>Fri, 08 Mar 2024 11:04:53 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/03/Swimm-Images-4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>An API is a technology that powers communication between software applications on the internet. API stands for Application Programming Interface, and it is basically a set of rules and protocols that define how different software can interact with each other. </p>
<p>Imagine having two different programs: program A and program B. For these two programs to communicate together, an API is needed, and a set of rules ensure that they know what to expect when they interact with each other.</p>
<p>As a backend developer, your responsibilities involve building server-side applications, handling data storage, and providing the necessary functionalities to do all these through APIs. </p>
<p>There are <a target="_blank" href="https://blog.postman.com/different-types-of-apis/">different types of APIs</a> like REST, GraphQL, gRPC, SOAP, and WebSockets. However, when it comes to web development, one is more popular, and that is the <a target="_blank" href="https://www.freecodecamp.org/news/what-is-a-rest-api/">REST API</a>.</p>
<p>In this article, you will learn how to create a CRUD API with Node.js and Express using the REST architecture, and by the end of this article, you should have a fully functional API that is able to perform CRUD operations.</p>
<p>So, let's dive into the world of backend development with Node.js and Express and get started on our journey to building a CRUD API.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-a-crud-api">What is a CRUD API?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-nodejs">What is Node.js?</a></li>
<li><a class="post-section-overview" href="#heading-why-node">Why Node?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-install-nodejs">How to Install Node.js</a></li>
<li><a class="post-section-overview" href="#heading-what-is-express">What is Express?</a></li>
<li><a class="post-section-overview" href="#heading-why-do-you-need-express">Why do You Need Express?</a></li>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisite<strong>s</strong></a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-your-development-environment">How to Set Up Your Development Environment</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-a-server-for-your-crud-restful-api-with-nodejs-and-express">How to Set up a server for Your CRUD Restful API with Node.js and Express</a></li>
<li><a class="post-section-overview" href="#heading-crud-api-example">CRUD API Example</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-api-routes">How to Create API Routes</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-your-own-crud-api">How to Create Your own CRUD API</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-the-get-users-endpoint">How to Create the GET /users Endpoint</a></li>
<li><a class="post-section-overview" href="#heading-how-to-test-your-api-get-request">How to Test Your API GET Request</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-the-post-users-endpoint">How to Create the POST /users Endpoint</a></li>
<li><a class="post-section-overview" href="#heading-how-to-test-the-post-request">How to Test the POST Request</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-the-get-usersid-endpoint">How to Create the GET /users/:id Endpoint</a></li>
<li><a class="post-section-overview" href="#heading-how-to-test-the-get-request">How to Test the GET Request</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-the-delete-usersid">How to Create the DELETE /users/:id</a></li>
<li><a class="post-section-overview" href="#heading-how-to-test-the-delete-request">How to Test the DELETE Request</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-the-patch-usersid-endpoint">How to Create the PATCH /users/:id Endpoint</a></li>
<li><a class="post-section-overview" href="#heading-how-to-test-the-patch-request">How to Test the PATCH Request</a></li>
<li><a class="post-section-overview" href="#heading-wrapping-up">Wrapping UP</a></li>
</ul>
<h2 id="heading-what-is-a-crud-api">What is a CRUD API?</h2>
<p>In web development, CRUD operations are the bread and butter of backend systems. This is because they allow you to "Create", "Read", "Update", and "Delete" data through your API. </p>
<p>Here's a quick overview of the four primary HTTP methods associated with CRUD operations:</p>
<ul>
<li><strong>GET</strong>: Used for reading or retrieving data from the server.</li>
<li><strong>POST</strong>: Used for creating new data on the server.</li>
<li><strong>PUT</strong>: Used for updating existing data on the server.</li>
<li><strong>DELETE</strong>: Used for removing data from the server.</li>
</ul>
<p>Virtually every web application interacts with a database to perform these four core operations. Whether it's a social media platform, an e-commerce website, or a weather app, they all rely on creating, reading, updating, and deleting data. </p>
<p>For example, WhatsApp recently added an edit feature to the application, allowing users to make corrections to an already-sent message. That's one part of the CRUD operation in action (updating).</p>
<p>In the context of building a web API, these operations become the backbone of how your application interacts with data. Your API provides endpoints that allow client applications (like web or mobile apps) to perform these operations on the server. </p>
<p>This communication between the client and the server is the essence of web development, and understanding how to create a CRUD API is a crucial skill for a web developer.</p>
<h2 id="heading-what-is-nodejs">What is Node.js?</h2>
<p>Node.js is an open-source and cross-platform runtime environment for executing JavaScript code outside of a browser. Quite often, we use it to build back-end services, also called APIs. Node is ideal for building highly scalable, data-intensive and real-time back-end services that power our client applications</p>
<h2 id="heading-why-node">Why Node?</h2>
<ul>
<li>It is one of the most popular choices for building the backend.</li>
<li>You get to write JavaScript across your entire stack, making it easier to transition from either a frontend developer to a backend developer and vice versa.</li>
<li>It allows for easy scaling of applications, making it a good choice for large-scale professional projects.</li>
<li>It is fast and non-blocking. This is because of the asynchronous event-driven nature of Node.js.</li>
<li>Node.js has a vibrant community and a rich ecosystem of packages and libraries.</li>
</ul>
<h2 id="heading-how-to-install-nodejs">How to Install Node.js</h2>
<p>Installation steps:</p>
<ol>
<li>Download the Mac/Windows installer from the <a target="_blank" href="https://nodejs.org/en/download">Node.js website</a>.</li>
<li>Choose the Long-Term Support (LTS) version that’s shown on the left</li>
<li>After downloading, install/run the installer, and then follow the prompts. (You will have to click the NEXT button a bunch of times and accept the default installation settings</li>
<li>To confirm that Node has been successfully installed, open your terminal and run the command. (For Windows, you might need to restart your command before running it.)</li>
</ol>
<pre><code>node –version
</code></pre><h2 id="heading-what-is-express">What is Express?</h2>
<p>Express is a fast, unopinionated, and minimalist web backend or server-side web framework for Node.js. Basically, it gives you the ability to build your APIs how you want them, with less code.</p>
<p>It is a framework built on top of Node.js that allows you to create your Backend with ease. You can use Express in combination with frontend frameworks like React, Angular, or Vue to build full-stack applications.</p>
<h2 id="heading-why-do-you-need-express">Why do You Need Express?</h2>
<ul>
<li>It makes building web applications with Node.js much easier.</li>
<li>It is extremely light, fast and free.</li>
<li>It is used for both server-rendered apps as well as API/Microservices.</li>
<li>It is the most popular Node.</li>
<li>It gives you full control over requests and responses.</li>
</ul>
<h2 id="heading-prerequisites">Prerequisite<strong>s</strong></h2>
<p>To follow along, you'll need to have the following:</p>
<ul>
<li>Basic knowledge of JavaScript</li>
<li>Download and install <a target="_blank" href="https://nodejs.org/en">Node.js</a> and <a target="_blank" href="https://www.postman.com/downloads/">Postman</a> on your computer</li>
</ul>
<p>See the complete code for this tutorial on <a target="_blank" href="https://github.com/Aviatorscode2/crud-api-tutorial">Github</a>.</p>
<h2 id="heading-how-to-set-up-your-development-environment">How to Set Up Your Development Environment</h2>
<p>Before diving into creating your API, let's go through the process of creating a basic server on your local computer. </p>
<p>Here are the steps to follow:</p>
<h3 id="heading-step-1-create-directory">Step #1 – Create Directory</h3>
<p>Create a directory/folder on your computer. Open the folder in a code editor</p>
<h3 id="heading-step-2-create-indexjs-file">Step #2 – Create index.js File</h3>
<p>Create an <strong>index.js</strong> file inside the folder using this command:</p>
<pre><code>touch index.js
</code></pre><h3 id="heading-step-3-initialize-npm">Step #3 – Initialize NPM</h3>
<p>Initialize NPM inside the folder by running this command in your terminal:</p>
<pre><code>npm init -y
</code></pre><p>The command will create a <strong>package.json</strong> file with default values.</p>
<h3 id="heading-step-5-install-express">Step #5 – Install Express</h3>
<p>Use the command below to install Express.js</p>
<pre><code>npm install express
</code></pre><p>After installing Express, go to the <strong>package.json</strong> file and include <strong>“type”: “module”</strong>. This declaration will tell Node that this project will be using <a target="_blank" href="https://nodejs.org/api/packages.html#type">ES6 module syntax</a> (import/export) instead of common.js, which is the default in Node.  </p>
<p><img src="https://lh7-us.googleusercontent.com/s0sHrHSK7ulqOU4Ddw6WzER6waGEGaCxV26mk-ieuqDVKYBZSKlJ1aDW8WXbCOlfzC1xcW8lXh1-HVSNnYUXYM3MRmmy0N-6uQh-J3qDnjHtxB5atRbJQ-cxR1AWzLTa9RTwv_cXNXpNGz3lbSBHejM" alt="Image" width="1600" height="601" loading="lazy">
<em>package.json file with <code>type:module</code></em></p>
<h2 id="heading-how-to-set-up-a-server-for-your-crud-restful-api-with-nodejs-and-express">How to Set up a server for Your CRUD Restful API with Node.js and Express</h2>
<p>To create a CRUD <a target="_blank" href="https://www.freecodecamp.org/news/what-is-rest-rest-api-definition-for-beginners/#:~:text=An%20API%20that%20complies%20with%20some%20or%20all%20of%20the%20six%20guiding%20constraints%20of%20REST%20is%20considered%20to%20be%20RESTful.">restful</a> API, you first need to set up your server. You can do this by following these steps:</p>
<h3 id="heading-step-1-write-your-server-application-code-inside-the-indexjs-file">Step #1 – Write your Server Application Code inside the index.js file</h3>
<p>Basically, a server code will look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-keyword">import</span> bodyParser <span class="hljs-keyword">from</span> ‘body-parser

<span class="hljs-keyword">const</span> app = express();
<span class="hljs-keyword">const</span> PORT = <span class="hljs-number">5000</span>

app.use(bodyParser.json());

app.listen(PORT, <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server running on port: http://localhost:<span class="hljs-subst">${PORT}</span>`</span>));
</code></pre>
<p>Here's an explanation for the code above:</p>
<ul>
<li>In the first line, we imported <code>express</code> from the Express module that we installed.</li>
<li>The <code>bodyParser</code> comes with Express, and it allows us to take in the incoming POST request body.</li>
<li>Next, we created an <code>app</code> using the <code>express</code> object.</li>
<li>We then specified the port for the application – it was set to <strong>5000</strong> (if you get an error using this port, it might be that the port is currently being used by a different app, so you can either change your port or stop the other app from using the port).</li>
<li>Next, we specified that JSON data will be used in the application.</li>
<li>Once that was created, we used the <code>listen</code> method on the <code>app</code> to make our application listen for incoming requests. The method accepts two things: the <strong>PORT</strong>, which is where we would be listening for requests from our client side, and a callback function that will be triggered when our server is set up.</li>
</ul>
<h3 id="heading-step-2-start-the-server">Step #2 – Start the Server</h3>
<p>Now you can start your server by running this command. If you used a different file, replace index.js with the file name where the server is located.</p>
<pre><code>node index.js
</code></pre><p>Now your server should be running on <strong>port 5000</strong>. You can verify that your server is running on your terminal</p>
<h3 id="heading-step-3-install-nodemon-optional">Step #3 – Install Nodemon (Optional)</h3>
<p>At the moment, anytime you make changes to your server file, you will need to restart the server before your changes can reflect (you can try it and see). So to take care of this challenge, you can use Nodemon. Run the command to install it:</p>
<pre><code>npm install nodemon
</code></pre><p>To use Nodemon, head over to your <strong>package.json</strong> file and set up a script. Replace your start script with this instead:</p>
<pre><code><span class="hljs-string">"start"</span>: <span class="hljs-string">"nodemon index.js"</span>
</code></pre><p>Note that <strong>index.js</strong> is the file where the server code is written.</p>
<p>Now you can start your server by running this command:</p>
<pre><code>npm start
</code></pre><p>With this code, we've set up a server that listens on port 5000 and prints a message when it starts. But this is just the beginning because our server needs to do much more. </p>
<p>Let's explore how to handle API requests next.</p>
<h2 id="heading-crud-api-example">CRUD API Example</h2>
<p>Let's start by defining the API routes for each CRUD operation. These routes will serve as the entry points for your API, and they will map to specific actions we want to perform on our data. </p>
<p>In our case, these actions are creating, reading, updating, and deleting data.</p>
<h2 id="heading-how-to-create-api-routes">How to Create API Routes</h2>
<p>When the port (<a target="_blank" href="http://localhost:5000/">http://localhost:5000/</a>) is opened in a browser, you will get an error.</p>
<p><img src="https://lh7-us.googleusercontent.com/p-3qnXzvHDxcsbhpYXO4VMopivQMhqgSPwSTXXDQJW_2GRhFFvkpL8JitNShGcrjyQiMx87ZwkK_4iEbs3JieTdRJQ13Q94O0hV7U9mwOpcm9ET7Yngb2TXQpItUrpepYzeXzg4rZMGdnxonhMREHAo" alt="Image" width="1600" height="905" loading="lazy">
<em>localhost:5000 in the browser without any routes</em></p>
<p>This is because Node.js and Express are all about routing, and we don't any routes yet. </p>
<p>You can define API routes using the <code>app.get()</code>, <code>app.post()</code>, <code>app.put()</code>, and <code>app.delete()</code> methods in your Express application (in the <strong>index.js</strong> file). </p>
<p>Here's how to create a route to handle GET requests using the <code>app.get()</code> function:</p>
<pre><code>app.get(<span class="hljs-string">'/'</span>, (req, res)
</code></pre><p>The <code>app.get()</code> function accepts two parameters. The first is used to specify the path (in this case, it is '/'). </p>
<p>The next parameter is a callback function where you define what happens when the GET request is called. The function also has <a target="_blank" href="https://www.freecodecamp.org/news/express-explained-with-examples-installation-routing-middleware-and-more/">two parameters</a>: the request body (<code>req</code>), which can contain information such as the request query string, parameters, body, and HTTP headers. While the response object (<code>res</code>) contains the information you want to send </p>
<p>Here is the complete code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-keyword">import</span> bodyParser <span class="hljs-keyword">from</span> <span class="hljs-string">'body-parser'</span>
<span class="hljs-keyword">const</span> app = express();

<span class="hljs-keyword">const</span> PORT = <span class="hljs-number">5000</span>;

app.use(bodyParser.json());

app.get(<span class="hljs-string">'/'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'[GET ROUTE]'</span>);
    res.send(<span class="hljs-string">'HELLO FROM HOMEPAGE'</span>);
})

app.listen(PORT, <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server running on port: http://localhost:<span class="hljs-subst">${PORT}</span>`</span>));
</code></pre>
<p>When you head back to <a target="_blank" href="http://localhost:5000/">http://localhost:5000/</a> and refresh it, you shouldn’t get an error anymore.</p>
<p><img src="https://lh7-us.googleusercontent.com/6289p5Vl_k4v2ULLd5iUVCpr-sykpbcEytcHsqoJZTB4MgWgDEfVuH1_4aTt0w9ThAhFNCn_rMrlwNFB2hfgOKWQ3znH3MHnHRxh0sd1czb_ntBHMIWS6HtAIo3yuCgDEFK7RVFGvTel0s89T3qTKjc" alt="Image" width="1600" height="905" loading="lazy">
<em>localhost:5000 in the browser with GET route</em></p>
<h2 id="heading-how-to-create-your-own-crud-api">How to Create Your own CRUD API</h2>
<p>For this API, you will be handling a set of users. Handling users in a database is a great example because it is a common use case in most applications. </p>
<p>Here are the API endpoints you will be creating:</p>
<ol>
<li>GET /users - find all users</li>
<li>POST /users - creates a user</li>
<li>GET /users/:id - finds a specific user</li>
<li>DELETE /users/:id - deletes a specific user</li>
<li>PATCH /users/:id - updates a specific user.</li>
</ol>
<h3 id="heading-how-to-create-the-get-users-endpoint">How to Create the GET /users Endpoint</h3>
<p>Reading data is one of the most common operations in an API. In this example, you will be getting the list of all the users in your mock database. This information will be presented in JSON format.</p>
<p>To define a route to retrieve users' data from the database, follow these steps:</p>
<ul>
<li>Create a new folder called routes</li>
<li>Create a new file called <strong>users.j</strong>s inside the routes folder.</li>
<li>Write the code to set up the GET router.</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-keyword">const</span> router = express.Router();

<span class="hljs-comment">// Mock database</span>
<span class="hljs-keyword">const</span> users = [
  {
    <span class="hljs-attr">first_name</span>: <span class="hljs-string">'John'</span>,
    <span class="hljs-attr">last_name</span>: <span class="hljs-string">'Doe'</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">'johndoe@example.com'</span>,
  },
  {
    <span class="hljs-attr">first_name</span>: <span class="hljs-string">'Alice'</span>,
    <span class="hljs-attr">last_name</span>: <span class="hljs-string">'Smith'</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">'alicesmith@example.com'</span>,
  },
];

<span class="hljs-comment">// Getting the list of users from the mock database</span>
router.get(<span class="hljs-string">'/'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
    res.send(users);
})

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> router
</code></pre>
<p>In this code snippet:</p>
<ul>
<li><code>import express from 'express';</code> imports the Express.js framework</li>
<li><code>const router = express.Router();</code> creates a fresh router instance, stored in the variable router.</li>
<li>The <code>users</code> variable serves as the mock database containing an array of users.</li>
<li>The <code>router.get()</code> function sets up a route that responds to HTTP GET requests.</li>
<li>The second part of the code <code>(req, res) =&gt; { ... }</code> is a callback function. It gets executed when a request is made to the GET route.</li>
<li>Inside the callback function, we used <code>res.send(users)</code> to send a response back to the client. In this example, we're sending the <code>users</code> variable as the response. So when a user hits the GET URL, the server responds by sending the data inside the <code>users</code> variable in JSON format to the client.</li>
</ul>
<p>Save your changes in the <strong>users.js</strong> file. Then do the following in the <strong>index.js</strong> file:</p>
<p>import your user routes from <strong>user.js</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> userRoutes <span class="hljs-keyword">from</span> <span class="hljs-string">'./routes/users.js'</span>
</code></pre>
<p>Use the <code>app.use</code> method, and specify the path and router handler:</p>
<pre><code class="lang-javascript">app.use(<span class="hljs-string">'/users'</span>, userRoutes);
</code></pre>
<p>When a user visits <a target="_blank" href="http://localhost:5000/users">http://localhost:5000/users</a>, the router is triggered. It effectively acts as a filter, determining when a specific set of routes should be applied.</p>
<p>Here is the complete code for the <strong>index.js</strong> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-keyword">import</span> bodyParser <span class="hljs-keyword">from</span> <span class="hljs-string">'body-parser'</span>
<span class="hljs-keyword">const</span> app = express();
<span class="hljs-keyword">import</span> userRoutes <span class="hljs-keyword">from</span> <span class="hljs-string">'./routes/users.js'</span>

<span class="hljs-keyword">const</span> PORT = <span class="hljs-number">5000</span>;

app.use(bodyParser.json());

app.use(<span class="hljs-string">'/users'</span>, userRoutes);

app.get(<span class="hljs-string">'/'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> res.send(<span class="hljs-string">'HELLO FROM HOMEPAGE'</span>))

app.get(<span class="hljs-string">'/'</span>, (req, res));

app.listen(PORT, <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server running on port: http://localhost:<span class="hljs-subst">${PORT}</span>`</span>));
</code></pre>
<h4 id="heading-how-to-test-your-api-get-request"><strong>How to Test Your API GET Request</strong></h4>
<p>You can use either a browser (browsers can only be used to perform GET requests) or Postman to test the GET request. </p>
<p>So copy your API URL, <a target="_blank" href="http://localhost:5000/users">http://localhost:5000/users</a>, and paste it either on Postman or in your browser. If you are using Postman, you will first need to make a GET request, then paste your API URL, and then click on send. After that, you will see the list of users in your Postman console.</p>
<p><img src="https://lh7-us.googleusercontent.com/XBhjewUFTBvBhc2larsYwqzS3-RHp7qFBrO4lvScf91EUFO5TEgt83iU48h9ArDK3EbrPwdS7_-WkI51JkDUHH4v2U9pWXdYMSbKeCpQrYRunvhuvAIAadzcAyj8y0hojjxs1CIlAo7TigoTJrM3y5c" alt="Image" width="1600" height="905" loading="lazy">
<em>postman GET route test</em></p>
<h3 id="heading-how-to-create-the-post-users-endpoint">How to Create the POST /users Endpoint</h3>
<p>You can use the POST request to add data to your database. It accepts input from the client and stores it in the database. To create data in our API, we'll define a route that accepts POST requests and saves the data to the mock database you have set up. </p>
<p>But before that, you'll need the UUID package. Use this command to install it:</p>
<pre><code>npm install uuid
</code></pre><p>This package will help generate a unique ID for each user you will be creating. This will be useful when you are implementing the GET, DELETE, and PATCH user by ID requests, where you will need a way to identify a specific user.</p>
<p>So in the <strong>users.js</strong> file, do the following:</p>
<p>Import the <code>uuid</code> package:</p>
<pre><code><span class="hljs-keyword">import</span> { v4 <span class="hljs-keyword">as</span> uuidv4 } <span class="hljs-keyword">from</span> <span class="hljs-string">'uuid'</span>;
</code></pre><p>Secondly, you'll have to implement the code for the POST request. </p>
<p>Here is what it looks like:</p>
<pre><code class="lang-javascript">router.post(<span class="hljs-string">'/'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> user = req.body;

    users.push({ ...user, <span class="hljs-attr">id</span>: uuidv4() });

    res.send(<span class="hljs-string">`<span class="hljs-subst">${user.first_name}</span> has been added to the Database`</span>);
})
</code></pre>
<p>In the code snippet:</p>
<ul>
<li>The <code>router.post()</code> function sets up a route that responds to HTTP POST requests. This means that when a client sends a POST request to the root URL of your application, this route will be triggered.</li>
<li>Within the callback function <code>(req, res) =&gt; { ... }</code>, we access the <code>req</code> object, which represents the incoming request made by the client. Specifically, we're interested in the <code>req.body</code> property. This property contains the data (first name, last name, and email) that the client will send as part of the POST request's body.</li>
<li>With <code>const user = req.body</code> we extract this data from <code>req.body</code> and store it in the <code>user</code> variable.</li>
<li>Next, we added the <code>user</code> data to an array called <code>users</code>. To ensure each user has a unique identifier, we generate a universally unique identifier (UUID) using a function like <code>uuidv4()</code> and include it as id in the user object. This helps in keeping user records distinct and identifiable.</li>
<li>Finally, we used <code>res.send()</code> to send a response back to the client. In this case, we're sending a simple message notifying the client that the user has been successfully added to the database. The message includes the user's first name for a personalized touch.</li>
</ul>
<p>Here is the complete code</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-keyword">import</span> { v4 <span class="hljs-keyword">as</span> uuidv4 } <span class="hljs-keyword">from</span> <span class="hljs-string">'uuid'</span>;

<span class="hljs-keyword">const</span> router = express.Router();

<span class="hljs-keyword">const</span> users = [];

<span class="hljs-comment">// Adding users to our mock database</span>

router.post(<span class="hljs-string">'/'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> user = req.body;

    users.push({ ...user, <span class="hljs-attr">id</span>: uuidv4() });

    res.send(<span class="hljs-string">`<span class="hljs-subst">${user.first_name}</span> has been added to the Database`</span>);
})  

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> router
</code></pre>
<h4 id="heading-how-to-test-the-post-request"><strong>How to Test the POST Request</strong></h4>
<p>Here are the steps to follow to make a POST request on Postman:</p>
<ul>
<li>Go to Postman</li>
<li>Open a new request tab</li>
<li>Select "POST" from the list of available HTTP methods</li>
<li>In the URL field, enter the full URL where you want to send the POST request (<a target="_blank" href="http://localhost:5000/users">http://localhost:5000/users</a>)</li>
<li>Click on the "Body" tab in the request window.</li>
<li>Choose the format in which you want to send your POST data (choose JSON).</li>
<li>Enter the data you want to send in the request body. This data should match the format expected by the server.</li>
<li>Finally, click on “Send”  </li>
</ul>
<p><img src="https://lh7-us.googleusercontent.com/olNqMdggCcvhUotN9ospAjg8r7t-HE_3yUqGrEkf_dKnCGTwFiKWQJB3x4dccUbHPlYbP-j8S7a2xBG3TpMvceVdmz_nC8zRtaRQzfeknyyo-OQJDwuSFZJkWPiQctDkoTYfZCsVnE1ljQN96Hxow54" alt="Image" width="1600" height="905" loading="lazy">
<em>postman POST route test</em></p>
<p>If it is successful, you will get a response saying, “Daanny has been added to the database."</p>
<p>To confirm if it has been added, make a GET request, and you should see the new user added to your database. (Note: This user information will be lost when your server restarts since it’s not saved to an actual database).</p>
<p><img src="https://lh7-us.googleusercontent.com/cHmJ3hcsMb5Vnj9zh_kSdqBMRrgtR1pQJ3-_DgHgukwdtyLrnG5AN0jyL4gGtzyTYUJj4w_ENO6ZqVsMZLqdnRytOgP4tR5A2B2T_TnDHNbRDEb9JAGF7SmTwVVwBczzg02JmLfWAucyeyMlnPs1Ehg" alt="Image" width="1152" height="652" loading="lazy">
<em>postman GET route test</em></p>
<h3 id="heading-how-to-create-the-get-usersid-endpoint">How to Create the GET /users/:id Endpoint</h3>
<p>Fetching specific data based on a unique identifier, such as a user ID, is a common operation. It's often essential for building features like user profiles or retrieving individual records from a database. </p>
<p>In this section, you’ll explore how to use this endpoint (users/:id) to retrieve user information based on a provided user ID. </p>
<p>Let's get started!</p>
<pre><code class="lang-javascript">router.get(<span class="hljs-string">'/:id'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> { id } = req.params;

    <span class="hljs-keyword">const</span> foundUser = users.find(<span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> user.id === id)

    res.send(foundUser)
});
</code></pre>
<p>Here's what this code snippet does:</p>
<ul>
<li>The <code>router.get()</code> function sets up a route that responds to HTTP GET requests. In this example, we've defined a route with ('/:id'). The :id part is a route parameter, which allows us to capture a dynamic value from the URL. In this case, it represents the user ID we want to retrieve.</li>
<li>Within the callback function <code>(req, res) =&gt; { ... }</code>, we can access the <code>req</code> object, which represents the incoming request made by the client. Specifically, we're interested in <code>req.params</code>, which holds the values of route parameters. In this case, we destructure <code>id</code> from <code>req.params</code>, effectively extracting the user ID from the URL. For example, if a client makes a GET request to /users/123, the id will be '123'.</li>
<li>We used the <code>.find()</code> method to search through this data based on the user ID (id) captured from the URL. This method attempts to find a user whose ID matches the provided id.</li>
<li>Once we located the user data (if it exists), we send it as the response using <code>res.send(foundUser)</code>. The <code>foundUser</code> variable contains the user object that matches the requested ID.</li>
</ul>
<h4 id="heading-how-to-test-the-get-request"><strong>How to Test the GET Request</strong></h4>
<p>In testing the API, follow these steps:</p>
<ul>
<li>Go to your POST request tab and make as many requests as you want to add a new user to the database.</li>
<li>Go to your GET request tab and make a request to see the list of users you have added</li>
</ul>
<p><img src="https://lh7-us.googleusercontent.com/qEuvm-1QKHvGmFCmru5dF2b9JSW5ua_dMcovZaKFZL_NChfSQqaazX4QvvSrSkjMzTO9Yqon5zhsZ5ZZwrWO0WifthlOKfboojC6ws8Fju2HK5TcE1oLvZZhOaO5xljRIUvYt_oun_NsIH13sq2Yf0o" alt="Image" width="1600" height="905" loading="lazy">
<em>postman GET route test</em></p>
<ul>
<li>Copy the id of any of the users on the list</li>
<li>Create a new GET request tab, copy in the base API URL, and add the id of any of the users to it. It should be in a format like this: <a target="_blank" href="http://localhost:5000/users/734a9e75-b3f5-415f-82fb-79b4fdf1a593">http://localhost:5000/users/734a9e75-b3f5-415f-82fb-79b4fdf1a593</a></li>
<li>Click on “Send”. If it’s successful, you will see the user information of the user id you used for the request</li>
</ul>
<p><img src="https://lh7-us.googleusercontent.com/ui9cj6HDXIifMjzlnICvnzgIGOssvRbGeCrlos2DXG541b4r9Dsn0mVrXZBfyCwvO6gh3yovrbsDD1I7EU0-5j7r3fRIrQ4XFX1QR-vlFJlXuXb1Ht753re7ZDf2cC7VyPyLgee6a6gZmwjnkCb8RI0" alt="Image" width="1600" height="905" loading="lazy">
<em>postman GET route test</em></p>
<h3 id="heading-how-to-create-the-delete-usersid">How to Create the DELETE /users/:id</h3>
<p>Sometimes, it's necessary to remove user accounts or specific records from a database for various reasons, such as account deactivation. </p>
<p>Here, you will explore how to use this endpoint to delete user data based on a provided user ID.</p>
<p>To delete data, we'll define a route that accepts DELETE requests and removes the data from the database.</p>
<p>See the code to delete a user from a database below</p>
<pre><code class="lang-javascript">router.delete(<span class="hljs-string">'/:id'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> { id } = req.params;

  users = users.filter(<span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> user.id !== id)

  res.send(<span class="hljs-string">`<span class="hljs-subst">${id}</span> deleted successfully from database`</span>);
});
</code></pre>
<p>Here's what this code does:</p>
<ul>
<li>The <code>router.delete()</code> function sets up a route that responds to HTTP DELETE requests. In this example, we've defined a route with ('/:id'), where :id is a route parameter. It captures a dynamic value from the URL, representing the user ID we want to delete.</li>
<li>In the callback function <code>(req, res) =&gt; { ... }</code>, we can access the <code>req</code> object, which represents the incoming request made by the client. Specifically, we're interested in <code>req.params</code>, which holds the values of route parameters. Here, we destructure id from <code>req.params</code>, extracting the user ID from the URL. For instance, if a client sends a DELETE request to /users/123, id will be '123'.</li>
<li>Assuming that we have an array or database (users) containing user data, we employ the <code>.filter()</code> method to create a new array that excludes the user with the matching ID (id). This effectively removes the user from the data store.</li>
<li>After successfully deleting the user, we send a response back to the client using <code>res.send()</code>. The response contains a message confirming the deletion, including the user's ID that was deleted from the database.</li>
</ul>
<h4 id="heading-how-to-test-the-delete-request"><strong>How to Test the DELETE Request</strong></h4>
<p>Here are the steps to delete a user from the database on Postman:</p>
<ul>
<li>Go to Postman</li>
<li>Open a new request tab</li>
<li>Select "DELETE" from the list of available HTTP methods</li>
<li>Enter the URL. It should contain the id of the user you want to delete (for example: <a target="_blank" href="http://localhost:5000/users/734a9e75-b3f5-415f-82fb-79b4fdf1a593">http://localhost:5000/users/734a9e75-b3f5-415f-82fb-79b4fdf1a593</a>). If you don’t have a user in your database, you will need to create one and copy the id.</li>
<li>Click on “Send”.  </li>
</ul>
<p><img src="https://lh7-us.googleusercontent.com/bTO6dcTaujyxm7ruPcyCJTzMfZemFop1oqU803Fif2kCeq1Z2q3uB1-JHB1aK4-ePIimPvb1LBYuty8_YFd7xP_i8UVhFZewWHlmwKy3MlWssMWtdaBnXtCkyB8NZebDnldJzRXc_v0Fs7MS4rZJq_g" alt="Image" width="1600" height="905" loading="lazy">
<em>postman DELETE route test</em></p>
<p><img src="https://lh7-us.googleusercontent.com/B9YHqAtEyg1f0O0CAojNJDXjK212LCxFodc9Ld3j04bdZsK9R5qHExSxaKGCAqgI0W79jHJ2bN3l9GkVgB3DYAd192zB9LzThvcAZJFuXoBO5JUqcUKWyBWcc6q4KirQA4B6Hi6t1NN3eU8e-dH10pY" alt="Image" width="1152" height="652" loading="lazy">
<em>postman DELETE route test</em></p>
<h3 id="heading-how-to-create-the-patch-usersid-endpoint">How to Create the PATCH /users/:id Endpoint</h3>
<p>There are times when you don't need to update an entire resource or object. Instead, you'd want to make partial modifications or adjustments. This is where the HTTP PATCH request comes into play.</p>
<p>For example, after creating a new user, you can change either the first name, last name, or email of that user using the PATCH request. Let’s see how to do that.</p>
<pre><code class="lang-javascript">router.patch(<span class="hljs-string">'/:id'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> { id } = req.params;

  <span class="hljs-keyword">const</span> { first_name, last_name, email} = req.body;

  <span class="hljs-keyword">const</span> user = users.find(<span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> user.id === id)

  <span class="hljs-keyword">if</span>(first_name) user.first_name = first_name;
  <span class="hljs-keyword">if</span>(last_name) user.last_name = last_name;
  <span class="hljs-keyword">if</span>(email) user.email = email;

  res.send(<span class="hljs-string">`User with the <span class="hljs-subst">${id}</span> has been updated`</span>)

});
</code></pre>
<p>Here's what this code snippet accomplishes:</p>
<ul>
<li>The <code>router.patch()</code> function sets up a route that responds to HTTP PATCH requests. In this example, we've defined a route with ('/:id'), where :id is a route parameter. It captures the dynamic value from the URL, representing the user ID we want to update.</li>
<li>Within the callback function <code>(req, res) =&gt; { ... }</code>, we can access the <code>req</code> object, which represents the incoming request made by the client. Specifically, we're interested in <code>req.params</code>, which hold the values of route parameters (id in this case), and <code>req.body</code>, which contains the data to be updated.</li>
<li>Next, we used <code>.find()</code> to locate the user object with the matching ID (id). Once found, we can proceed to modify the user's data based on the content of <code>req.body</code>. We also checked if first_name, last_name, or email properties exist in <code>req.body</code>. If they do, we can update the corresponding properties of the user object with the new values. This allows us to make selective changes to the user's data without affecting other attributes.</li>
<li>After successfully applying the requested modifications, we send a response back to the client using <code>res.send()</code>. The response includes a message confirming the successful update of the user data, along with the user's ID.</li>
</ul>
<h4 id="heading-how-to-test-the-patch-request"><strong>How to Test the PATCH Request</strong></h4>
<p>Follow these steps to make a PATCH request in Postman:</p>
<ul>
<li>Go to Postman</li>
<li>Open a new request tab</li>
<li>Select "PATCH" from the list of available HTTP methods</li>
<li>Enter URL; the URL will contain the id of the user you want to delete (for example: <a target="_blank" href="http://localhost:5000/users/734a9e75-b3f5-415f-82fb-79b4fdf1a593">http://localhost:5000/users/734a9e75-b3f5-415f-82fb-79b4fdf1a593</a>). If you don’t have a user in your database, you will need to create one and copy the id.</li>
<li>Click on the "Body" tab in the request window and choose the format in which you want to send your PATCH data (for example: JSON, form-data, x-www-form-urlencoded).</li>
<li>Enter the data you want to send in the request body. This data should only include the specific changes you want to make to the resource.</li>
<li>Then click the "Send" button. Postman will send the PATCH request to the specified URL with the provided data.</li>
</ul>
<p><img src="https://lh7-us.googleusercontent.com/K1OH_u-2DOJbkMqlQ3uJow9XNKh0iOmE8fedCCspUiQIHcvm-DmIorFvZcApoDWGSK4YMkFR7RtcHBmzMZaJUyXy7SMDJWxH_PDLFmugGPNQDmKzM6HE3tPOBQZaS1388bZzLlmcTThQa_wy1ZPrm1g" alt="Image" width="1600" height="905" loading="lazy">
<em>postman PATCH route test</em></p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>APIs are the linchpin connecting various software components and enabling them to work together seamlessly. They allow them to communicate, share data, and perform tasks. In the context of web development, APIs enable the web to function as we know it today.</p>
<p>In this tutorial, we explored backend development by creating a CRUD API with Node.js and Express. We covered various concepts, like how to set up a development environment, create a server with Express and Node.js, and most importantly, how to handle CRUD operations and test your API using Postman.</p>
<p>While we've covered fundamental aspects of API creation in this tutorial, there is still a vast landscape of knowledge to explore as regards to APIs. These include how to secure your API by adding authentication, how to use middleware, database interaction, API deployment, and a lot more.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Multiplayer Tabletop Game Simulator with Vue, Phaser, Node, Express, and Socket.IO ]]>
                </title>
                <description>
                    <![CDATA[ By M. S. Farzan Putting together all of the pieces of a full stack JavaScript application can be a complex endeavor.   In this tutorial, we're going to build a multiplayer tabletop game simulator using Vue, Phaser, Node/Express, and Socket.IO to lear... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-multiplayer-tabletop-game-simulator/</link>
                <guid isPermaLink="false">66d851eba2a6d73be8613877</guid>
                
                    <category>
                        <![CDATA[ ES6 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express JS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Game Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ phaser 3 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SocketIO ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 13 Jul 2020 23:31:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/07/How-to-Tabletop-Game-Simulator---Thumb.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By M. S. Farzan</p>
<p>Putting together all of the pieces of a full stack JavaScript application can be a complex endeavor.  </p>
<p>In this tutorial, we're going to build a multiplayer tabletop game simulator using <a target="_blank" href="https://vuejs.org/">Vue</a>, <a target="_blank" href="http://phaser.io/">Phaser</a>, <a target="_blank" href="https://nodejs.org/">Node</a>/<a target="_blank" href="https://expressjs.com/">Express</a>, and <a target="_blank" href="https://socket.io/">Socket.IO</a> to learn several concepts that will be useful in any full stack app.</p>
<p>You can follow along with this video tutorial as well (1 hour 16 minute watch):</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/laNi0fdF_DU" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>All of the project files for this tutorial are available on <a target="_blank" href="https://github.com/sominator/tabletop-project">GitHub</a>.</p>
<h2 id="heading-project-overview">Project Overview</h2>
<p>Our project will feature a Phaser game instance that will allow us to create tokens and cards on screen, and move them around on a digital game board.</p>
<p>The Phaser instance will be wrapped in a Vue component that will handle things like multiplayer chat and commands.  Together, Phaser and Vue will comprise our front end (referred to from here on as the "client"), and we'll use Socket.IO to communicate with other players and tie together the front and back ends of our app.</p>
<p>The back end (referred to from here on as the "server") will be a simple Express server that receives Socket.IO events from the client and acts accordingly.  The whole application will run on Node as its runtime.</p>
<p>You don't need to be an expert in any of the above frameworks to complete this project, but it would be a good idea to have a solid foundation in basic JavaScript and HTML/CSS before trying to tackle the specifics. You can also follow along with my series on <a target="_blank" href="https://www.freecodecamp.org/news/learn-javascript-by-making-digital-tabletop-games-and-web-apps/">Learning JavaScript by Making Digital Tabletop Games and Web Apps</a>.  </p>
<p>You'll also want to make sure that you have Node and <a target="_blank" href="https://github.com/">Git</a> installed, along with your favorite code editor and a command line interface (you can follow my tutorial on setting up an IDE <a target="_blank" href="https://www.freecodecamp.org/news/how-to-set-up-an-integrated-development-environment-ide/">here</a> if you need help).</p>
<p>Let's get started!</p>
<h2 id="heading-part-1-client-basics">Part 1: Client Basics</h2>
<p>We'll begin building our client by installing the <a target="_blank" href="https://cli.vuejs.org/">Vue CLI</a>, which will help us with some tooling and allow us to make changes to our files without having to reload our web browser.</p>
<p>In a command line, type in the following to install the Vue CLI globally:</p>
<pre><code class="lang-cli">npm install -g @vue/cli
</code></pre>
<p>Navigate to a desired directory and create a new folder for our project:</p>
<pre><code class="lang-cli">mkdir tabletop-project
cd tabletop-project
</code></pre>
<p>Now we can use the Vue CLI to template a front end project for us:</p>
<pre><code class="lang-cli">vue create client
</code></pre>
<p>You can just hit "enter" at the ensuing prompts unless you have specific preferences.</p>
<p>The Vue CLI has helpfully templated a front end project for us, which we can view in our code editor:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/1.JPG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Let's navigate to our new client folder in our CLI and run the template app:</p>
<pre><code class="lang-cli">cd client
npm run serve
</code></pre>
<p>After a little work, the Vue CLI should begin displaying our app in a web browser at the default http://localhost:8080:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/2.JPG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Cool!  We have the basic structure of our client.  Let's break it by creating two new components in the /components folder, called Game.vue and Chat.vue (you can go ahead and delete HelloWorld.vue and anything in the assets folder if you're obsessed with tidiness like I am).</p>
<p>Replace the code in App.vue with the following:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"game"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Game</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"border"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"input"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Chat</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">import</span> Chat <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Chat.vue'</span>;
    <span class="hljs-keyword">import</span> Game <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Game.vue'</span>;

    <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'App'</span>,
        <span class="hljs-attr">components</span>: {
            Chat,
            Game
        }
    }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
    <span class="hljs-selector-id">#app</span> {
        <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Trebuchet MS'</span>;
        <span class="hljs-attribute">text-align</span>: left;
        <span class="hljs-attribute">background-color</span>: black;
        <span class="hljs-attribute">color</span>: cyan;
        <span class="hljs-attribute">display</span>: flex;
    }
    <span class="hljs-selector-id">#game</span> {
        <span class="hljs-attribute">width</span>: <span class="hljs-number">50vw</span>;
        <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;
    }
    <span class="hljs-selector-id">#input</span> {
        <span class="hljs-attribute">width</span>: <span class="hljs-number">50vw</span>;
        <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;
    }
    <span class="hljs-selector-id">#border</span> {
        <span class="hljs-attribute">border-right</span>: <span class="hljs-number">2px</span> solid cyan;
    }
    <span class="hljs-keyword">@media</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">1000px</span>) {
        <span class="hljs-selector-id">#app</span> {
            <span class="hljs-attribute">flex-direction</span>: column;
        }
        <span class="hljs-selector-id">#game</span> {
            <span class="hljs-attribute">width</span>: <span class="hljs-number">100vw</span>;
            <span class="hljs-attribute">height</span>: <span class="hljs-number">50vh</span>;
        }
        <span class="hljs-selector-id">#input</span> {
            <span class="hljs-attribute">width</span>: <span class="hljs-number">100vw</span>;
            <span class="hljs-attribute">height</span>: <span class="hljs-number">50vh</span>;
        }
    }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
</code></pre>
<p>As you can see, a Vue component ordinarily has three sections: Template, Script, and Style, which contain any HTML, JavaScript, and CSS for that component, respectively.  We've just imported our Game and Chat components here and added a little styling to give it a cyberpunk feel when it's all up and running.</p>
<p>That's actually all that we need to do to set up our App.vue component, which will house everything else in our client.  Before we can actually do anything with it, we'll need to get our server working!</p>
<h2 id="heading-part-2-server-basics">Part 2: Server Basics</h2>
<p>At our root directory (tabletop-project, above /client), initialize a new project in a new command line interface by typing:</p>
<pre><code class="lang-cli">npm init
</code></pre>
<p>Like with our client, you can go ahead and press "enter" at the prompts unless there are specifics that you'd like to designate at this time.</p>
<p>We'll need to install Express and Socket.IO, along with <a target="_blank" href="https://nodemon.io/">Nodemon</a> to watch our server files for us and reboot as necessary:</p>
<pre><code class="lang-cli">npm install --save express socket.io nodemon
</code></pre>
<p>Let's open up the new package.json file in that root directory and add a "start" command in the "scripts" section:</p>
<pre><code class="lang-javascript">  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"nodemon server.js"</span>
  },
</code></pre>
<p>Create a new file called server.js in this directory, and enter the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> server = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>)();
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>).createServer(server);
<span class="hljs-keyword">const</span> io = <span class="hljs-built_in">require</span>(<span class="hljs-string">'socket.io'</span>)(http);

io.on(<span class="hljs-string">'connection'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">socket</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A user connected: '</span> + socket.id);

    socket.on(<span class="hljs-string">'send'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">text</span>) </span>{
        <span class="hljs-keyword">let</span> newText = <span class="hljs-string">"&lt;"</span> + socket.id + <span class="hljs-string">"&gt; "</span> + text;
        io.emit(<span class="hljs-string">'receive'</span>, newText);
    });

    socket.on(<span class="hljs-string">'disconnect'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A user disconnected: '</span> + socket.id);
    });
});

http.listen(<span class="hljs-number">3000</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server started!'</span>);
});
</code></pre>
<p>Excellent!  Our simple server will now listen at http://localhost:3000, and use Socket.IO to log to the console when a user connects and disconnects, with their socket ID.</p>
<p>When the server receives a "send" event from a client, it will create a new text string that includes the socket ID of the client that emitted the event, and emit its own "receive" event to all clients with the text that it received, interpolated with the socket ID.</p>
<p>We can test the server by returning to our command line and starting it up :</p>
<pre><code class="lang-cli">npm run start
</code></pre>
<p>The command console should now display:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/07/3-4.JPG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Cool! Let's return to the Chat component of our client to start building out our front end functionality.</p>
<h2 id="heading-part-3-chat">Part 3: Chat</h2>
<p>Let's open a separate command line interface and navigate to the /client directory. Within that directory, install the client version of Socket.IO:</p>
<pre><code class="lang-cli">npm install --save socket.io-client
</code></pre>
<p>In /client/src/components/Chat.vue, add the following code:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"output"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>STRUCT<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">"(text, index) in textOutput"</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">"index"</span>&gt;</span>{{text}}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"input"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"textInput"</span> <span class="hljs-attr">:placeholder</span>=<span class="hljs-string">"textInput"</span> /&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"Send"</span> <span class="hljs-attr">v-on:click</span>=<span class="hljs-string">"submitText"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">import</span> io <span class="hljs-keyword">from</span> <span class="hljs-string">'socket.io-client'</span>;
    <span class="hljs-keyword">let</span> socket = io(<span class="hljs-string">'http://localhost:3000'</span>);

    <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
        <span class="hljs-attr">name</span>: <span class="hljs-string">'Chat'</span>,
        <span class="hljs-attr">data</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            <span class="hljs-keyword">return</span> {
                <span class="hljs-attr">textInput</span>: <span class="hljs-literal">null</span>,
                <span class="hljs-attr">textOutput</span>: []
            }
        },
        <span class="hljs-attr">methods</span>: {
            <span class="hljs-attr">submitText</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">event</span>) </span>{
                event.preventDefault();
                socket.emit(<span class="hljs-string">'send'</span>, <span class="hljs-built_in">this</span>.textInput);
            }
        },
        <span class="hljs-attr">created</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            socket.on(<span class="hljs-string">'connect'</span>, <span class="hljs-function">() =&gt;</span> {
                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Connected!'</span>);
            });
            socket.on(<span class="hljs-string">'receive'</span>, <span class="hljs-function">(<span class="hljs-params">text</span>) =&gt;</span> {
                <span class="hljs-built_in">this</span>.textOutput.push(text);
                <span class="hljs-built_in">this</span>.textInput = <span class="hljs-literal">null</span>;
            });
        }
    }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">style</span> <span class="hljs-attr">scoped</span>&gt;</span><span class="css">
    <span class="hljs-selector-id">#container</span> {
        <span class="hljs-attribute">text-align</span>: left;
        <span class="hljs-attribute">display</span>: flex;
        <span class="hljs-attribute">flex-direction</span>: column;
        <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">1vw</span>;
        <span class="hljs-attribute">min-height</span>: <span class="hljs-number">100vh</span>;
    }
    <span class="hljs-selector-tag">h1</span> {
        <span class="hljs-attribute">text-align</span>: center;
    }
    <span class="hljs-selector-class">.hotpink</span> {
        <span class="hljs-attribute">color</span>: hotpink;
    }
    <span class="hljs-selector-id">#input</span> {
        <span class="hljs-attribute">position</span>: fixed;
        <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">95vh</span>;
    }
    <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=text]</span> {
        <span class="hljs-attribute">height</span>: <span class="hljs-number">20px</span>;
        <span class="hljs-attribute">width</span>:  <span class="hljs-number">40vw</span>;
        <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> solid cyan;
        <span class="hljs-attribute">background-color</span>: black;
        <span class="hljs-attribute">color</span>: hotpink;
        <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">1em</span>;
    }
    <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=submit]</span>{
        <span class="hljs-attribute">height</span>: <span class="hljs-number">25px</span>;
        <span class="hljs-attribute">width</span>: <span class="hljs-number">5vw</span>;
        <span class="hljs-attribute">background-color</span>: black;
        <span class="hljs-attribute">color</span>: cyan;
        <span class="hljs-attribute">border</span>: <span class="hljs-number">2px</span> solid cyan;
        <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">2vw</span>;
    }
    <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=submit]</span><span class="hljs-selector-pseudo">:focus</span>{
        <span class="hljs-attribute">outline</span>: none;
    }
    <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=submit]</span><span class="hljs-selector-pseudo">:hover</span>{
        <span class="hljs-attribute">color</span>: hotpink;
    }
    <span class="hljs-keyword">@media</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">1000px</span>) {
        <span class="hljs-selector-id">#container</span> {
            <span class="hljs-attribute">border-left</span>: none;
            <span class="hljs-attribute">border-top</span>: <span class="hljs-number">2px</span> solid cyan;
            <span class="hljs-attribute">min-height</span>: <span class="hljs-number">50vh</span>;
        }
        <span class="hljs-selector-id">#input</span> {
            <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">43vh</span>;
        }
        <span class="hljs-selector-id">#output</span> {
            <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">10vw</span>;
        }
        <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=text]</span> {
            <span class="hljs-attribute">width</span>: <span class="hljs-number">60vw</span>;
        }
        <span class="hljs-selector-tag">input</span><span class="hljs-selector-attr">[type=submit]</span> {
            <span class="hljs-attribute">min-width</span>: <span class="hljs-number">10vw</span>;
        }
    }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
</code></pre>
<p>Let's examine the above from bottom to top before moving forward.  Between the </p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Professional Chat API Solution with Sockets in NodeJS [Beginner level] ]]>
                </title>
                <description>
                    <![CDATA[ By Adeel Imran Have you ever wondered how chat applications work behind the scenes? Well, today I am going to walk you through how to make a REST + Sockets-based application built on top of NodeJS/ExpressJS using MongoDB. I have been working on the c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-a-professional-node-express/</link>
                <guid isPermaLink="false">66d45d5bbd438296f45cd375</guid>
                
                    <category>
                        <![CDATA[ backend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ node js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ REST API ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SocketIO ]]>
                    </category>
                
                    <category>
                        <![CDATA[ websocket ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 16 Jun 2020 23:47:21 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9a39740569d1a4ca2455.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adeel Imran</p>
<p>Have you ever wondered how chat applications work behind the scenes? Well, today I am going to walk you through how to make a REST + Sockets-based application built on top of <a target="_blank" href="https://nodejs.org/">NodeJS</a>/<a target="_blank" href="http://expressjs.com/">ExpressJS</a> using <a target="_blank" href="https://www.mongodb.com/">MongoDB</a>.</p>
<p>I have been working on the content for this article for over a week now – I really hope it helps someone out there.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li>Set up Mongodb on your machine [<a target="_blank" href="https://github.com/adeelibr/node-playground/blob/master/chapter-1-chat/guidelines/installing-mongo.md">Installation guide written here</a>]</li>
<li>For windows users, you can find the installation guide [<a target="_blank" href="https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/#procedure">here</a>]</li>
<li>For macOS users, you can find the installation guide [<a target="_blank" href="https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/#install-homebrew">here</a>][<a target="_blank" href="https://github.com/adeelibr/node-playground/blob/master/chapter-1-chat/guidelines/installing-mongo.md">To the point installation that I wrote</a>]</li>
<li>For Linux users, you can find the installation guide [<a target="_blank" href="https://docs.mongodb.com/manual/administration/install-on-linux/">here</a>]</li>
<li>Install Node/NPM on your machine [<a target="_blank" href="https://nodejs.org/en/download/">Installation link here</a>] (I am using Node version v12.18.0)</li>
</ul>
<h2 id="heading-topics-well-cover">Topics we'll cover</h2>
<h3 id="heading-general">General</h3>
<ul>
<li>Create an express server</li>
<li>How to do API validations</li>
<li>Create basic skeleton for the entire application</li>
<li>Setting up MongoDB (installation, setup in express)</li>
<li>Creating users API + Database (Create a user, Get a user by id, Get all users, Delete a user by id)</li>
<li>Understanding what a middleware is</li>
<li>JWT (JSON web tokens) authentication (decode/encode) - Login middleware</li>
<li>Web socket class that handles events when a user disconnects, adds its identity, joins a chat room, wants to mute a chat room</li>
<li>Discussing chat room &amp; chat message database model</li>
</ul>
<h3 id="heading-for-the-api">For the API</h3>
<ul>
<li>Initiate a chat between users</li>
<li>Create a message in chat room</li>
<li>See conversation for a chat room by its id</li>
<li>Mark an entire conversation as read (similar to Whatsapp)</li>
<li>Get recent conversation from all chats (similar to Facebook messenger)</li>
</ul>
<h3 id="heading-bonus-api">Bonus  - API</h3>
<ul>
<li>Delete a chat room by id along with all its associated messages</li>
<li>Delete a message by id</li>
</ul>
<p>Before we begin, I wanted to touch on some basics in the following videos.</p>
<h3 id="heading-understanding-the-basics-of-expressjs">Understanding the basics of ExpressJS</h3>
<p>What are routes? Controllers? How do we allow for CORS (cross origin resource sharing)? How do we allow enduser to send data in JSON format in API request?</p>
<p>I talk about all this and more (including REST conventions) in this video:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/t7-yuYFVG1Y" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Also, here's a <a target="_blank" href="https://github.com/adeelibr/node-playground/tree/master/chapter-0-basic">GitHub link to the entire source code of this video</a> [Chapter 0]</p>
<p>Do have a look at the README.md for "Chapter 0" source code. It has all the relevant learning links I mention in the video along with an amazing half hour tutorial on postman. </p>
<h3 id="heading-adding-api-validation-to-your-api-end-point">Adding API validation to your API end-point</h3>
<p>In the below video, you'll learn how to write your own custom validation using a library called "make-validation":</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/t-KGXLM0YlE" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Here's the <a target="_blank" href="https://github.com/adeelibr/node-playground/tree/master/chapter-0-basic">GitHub link to the entire source code of this video</a> [Chapter 0].</p>
<p>And here's the <strong>make-validation</strong> library link [G<a target="_blank" href="https://github.com/withvoid/make-validation">itHub</a>][<a target="_blank" href="https://www.npmjs.com/package/@withvoid/make-validation">npm</a>][<a target="_blank" href="https://github.com/withvoid/make-validation/tree/master/example">example</a>].</p>
<p>The entire source code of this tutorial can be found <strong><a target="_blank" href="https://github.com/adeelibr/node-playground/tree/master/chapter-1-chat">here</a></strong>. If you have any feedback, please just reach out to me on <a target="_blank" href="http://twitter.com/adeelibr">http://twitter.com/adeelibr</a>. If you like this tutorial kindly leave a star on the <strong>github repository**</strong>.**</p>
<p>Let's begin now that you know the basics of ExpressJS and how to validate a user response.</p>
<h2 id="heading-getting-started">Getting started</h2>
<p>Create a folder called <code>chat-app</code>:</p>
<pre><code>mkdir chat-app;
cd chat-app;
</code></pre><p>Next initialize a new npm project in your project root folder by typing the following:</p>
<pre><code>npm init -y
</code></pre><p>and install the following packages:</p>
<pre><code>npm i cors @withvoid/make-validation express jsonwebtoken mongoose morgan socket.io uuid --save;
npm i nodemon --save-dev;
</code></pre><p>And in your <code>package.json</code> <code>scripts</code> section add the following 2 scripts:</p>
<pre><code><span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"nodemon server/index.js"</span>,
    <span class="hljs-string">"start:server"</span>: <span class="hljs-string">"node server/index.js"</span>
},
</code></pre><p>Your <code>package.json</code> now should look something like this:</p>
<pre><code>{
  <span class="hljs-string">"name"</span>: <span class="hljs-string">"chapter-1-chat"</span>,
  <span class="hljs-string">"version"</span>: <span class="hljs-string">"0.0.0"</span>,
  <span class="hljs-string">"private"</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-string">"type"</span>: <span class="hljs-string">"module"</span>,
  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"nodemon server/index.js"</span>,
    <span class="hljs-string">"start:server"</span>: <span class="hljs-string">"node server/index.js"</span>
  },
  <span class="hljs-string">"dependencies"</span>: {
    <span class="hljs-string">"@withvoid/make-validation"</span>: <span class="hljs-string">"1.0.5"</span>,
    <span class="hljs-string">"cors"</span>: <span class="hljs-string">"2.8.5"</span>,
    <span class="hljs-string">"express"</span>: <span class="hljs-string">"4.16.1"</span>,
    <span class="hljs-string">"jsonwebtoken"</span>: <span class="hljs-string">"8.5.1"</span>,
    <span class="hljs-string">"mongoose"</span>: <span class="hljs-string">"5.9.18"</span>,
    <span class="hljs-string">"morgan"</span>: <span class="hljs-string">"1.9.1"</span>,
    <span class="hljs-string">"socket.io"</span>: <span class="hljs-string">"2.3.0"</span>,
    <span class="hljs-string">"uuid"</span>: <span class="hljs-string">"8.1.0"</span>
  },
  <span class="hljs-string">"devDependencies"</span>: {
    <span class="hljs-string">"nodemon"</span>: <span class="hljs-string">"2.0.4"</span>
  }
}
</code></pre><p>Awesome!</p>
<p>Now in your project's root folder create a new folder called <code>server</code>:</p>
<pre><code>cd chat-app;
mkdir server;
cd server;
</code></pre><p>Inside your <code>server</code> folder create a file called <code>index.js</code> and add the following content to it:</p>
<pre><code><span class="hljs-keyword">import</span> http <span class="hljs-keyword">from</span> <span class="hljs-string">"http"</span>;
<span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">"express"</span>;
<span class="hljs-keyword">import</span> logger <span class="hljs-keyword">from</span> <span class="hljs-string">"morgan"</span>;
<span class="hljs-keyword">import</span> cors <span class="hljs-keyword">from</span> <span class="hljs-string">"cors"</span>;
<span class="hljs-comment">// routes</span>
<span class="hljs-keyword">import</span> indexRouter <span class="hljs-keyword">from</span> <span class="hljs-string">"./routes/index.js"</span>;
<span class="hljs-keyword">import</span> userRouter <span class="hljs-keyword">from</span> <span class="hljs-string">"./routes/user.js"</span>;
<span class="hljs-keyword">import</span> chatRoomRouter <span class="hljs-keyword">from</span> <span class="hljs-string">"./routes/chatRoom.js"</span>;
<span class="hljs-keyword">import</span> deleteRouter <span class="hljs-keyword">from</span> <span class="hljs-string">"./routes/delete.js"</span>;
<span class="hljs-comment">// middlewares</span>
<span class="hljs-keyword">import</span> { decode } <span class="hljs-keyword">from</span> <span class="hljs-string">'./middlewares/jwt.js'</span>

<span class="hljs-keyword">const</span> app = express();

<span class="hljs-comment">/** Get port from environment and store in Express. */</span>
<span class="hljs-keyword">const</span> port = process.env.PORT || <span class="hljs-string">"3000"</span>;
app.set(<span class="hljs-string">"port"</span>, port);

app.use(logger(<span class="hljs-string">"dev"</span>));
app.use(express.json());
app.use(express.urlencoded({ <span class="hljs-attr">extended</span>: <span class="hljs-literal">false</span> }));

app.use(<span class="hljs-string">"/"</span>, indexRouter);
app.use(<span class="hljs-string">"/users"</span>, userRouter);
app.use(<span class="hljs-string">"/room"</span>, decode, chatRoomRouter);
app.use(<span class="hljs-string">"/delete"</span>, deleteRouter);

<span class="hljs-comment">/** catch 404 and forward to error handler */</span>
app.use(<span class="hljs-string">'*'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">404</span>).json({
    <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">message</span>: <span class="hljs-string">'API endpoint doesnt exist'</span>
  })
});

<span class="hljs-comment">/** Create HTTP server. */</span>
<span class="hljs-keyword">const</span> server = http.createServer(app);
<span class="hljs-comment">/** Listen on provided port, on all network interfaces. */</span>
server.listen(port);
<span class="hljs-comment">/** Event listener for HTTP server "listening" event. */</span>
server.on(<span class="hljs-string">"listening"</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Listening on port:: http://localhost:<span class="hljs-subst">${port}</span>/`</span>)
});
</code></pre><p>Let's add the routes for <code>indexRouter</code> <code>userRouter</code> <code>chatRoomRouter</code> &amp; <code>deleteRouter</code>.</p>
<p>In your project's root folder create a folder called <code>routes</code>. Inside the <code>routes</code> folder add the following files:</p>
<ul>
<li><code>index.js</code></li>
<li><code>user.js</code></li>
<li><code>chatRoom.js</code></li>
<li><code>delete.js</code></li>
</ul>
<p>Let's add content for <code>routes/index.js</code> first:</p>
<pre><code><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-comment">// controllers</span>
<span class="hljs-keyword">import</span> users <span class="hljs-keyword">from</span> <span class="hljs-string">'../controllers/user.js'</span>;
<span class="hljs-comment">// middlewares</span>
<span class="hljs-keyword">import</span> { encode } <span class="hljs-keyword">from</span> <span class="hljs-string">'../middlewares/jwt.js'</span>;

<span class="hljs-keyword">const</span> router = express.Router();

router
  .post(<span class="hljs-string">'/login/:userId'</span>, encode, <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> { });

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> router;
</code></pre><p>Let's add content for <code>routes/user.js</code> next:</p>
<pre><code><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-comment">// controllers</span>
<span class="hljs-keyword">import</span> user <span class="hljs-keyword">from</span> <span class="hljs-string">'../controllers/user.js'</span>;

<span class="hljs-keyword">const</span> router = express.Router();

router
  .get(<span class="hljs-string">'/'</span>, user.onGetAllUsers)
  .post(<span class="hljs-string">'/'</span>, user.onCreateUser)
  .get(<span class="hljs-string">'/:id'</span>, user.onGetUserById)
  .delete(<span class="hljs-string">'/:id'</span>, user.onDeleteUserById)

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> router;
</code></pre><p>And now let's add content for <code>routes/chatRoom.js</code>:</p>
<pre><code><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-comment">// controllers</span>
<span class="hljs-keyword">import</span> chatRoom <span class="hljs-keyword">from</span> <span class="hljs-string">'../controllers/chatRoom.js'</span>;

<span class="hljs-keyword">const</span> router = express.Router();

router
  .get(<span class="hljs-string">'/'</span>, chatRoom.getRecentConversation)
  .get(<span class="hljs-string">'/:roomId'</span>, chatRoom.getConversationByRoomId)
  .post(<span class="hljs-string">'/initiate'</span>, chatRoom.initiate)
  .post(<span class="hljs-string">'/:roomId/message'</span>, chatRoom.postMessage)
  .put(<span class="hljs-string">'/:roomId/mark-read'</span>, chatRoom.markConversationReadByRoomId)

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> router;
</code></pre><p>Finally, let's add content for <code>routes/delete.js</code>:</p>
<pre><code><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-comment">// controllers</span>
<span class="hljs-keyword">import</span> deleteController <span class="hljs-keyword">from</span> <span class="hljs-string">'../controllers/delete.js'</span>;

<span class="hljs-keyword">const</span> router = express.Router();

router
  .delete(<span class="hljs-string">'/room/:roomId'</span>, deleteController.deleteRoomById)
  .delete(<span class="hljs-string">'/message/:messageId'</span>, deleteController.deleteMessageById)

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> router;
</code></pre><p>Awesome now that our routes are in place let's add the controllers for each route.</p>
<p>Create a new folder called <code>controllers</code>. Inside that folder create the following files:</p>
<ul>
<li><code>user.js</code></li>
<li><code>chatRoom.js</code></li>
<li><code>delete.js</code></li>
</ul>
<p>Let's start of with <code>controllers/user.js</code>:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">onGetAllUsers</span>: <span class="hljs-keyword">async</span> (req, res) =&gt; { },
  <span class="hljs-attr">onGetUserById</span>: <span class="hljs-keyword">async</span> (req, res) =&gt; { },
  <span class="hljs-attr">onCreateUser</span>: <span class="hljs-keyword">async</span> (req, res) =&gt; { },
  <span class="hljs-attr">onDeleteUserById</span>: <span class="hljs-keyword">async</span> (req, res) =&gt; { },
}
</code></pre><p>Next let's add content in <code>controllers/chatRoom.js</code>:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">initiate</span>: <span class="hljs-keyword">async</span> (req, res) =&gt; { },
  <span class="hljs-attr">postMessage</span>: <span class="hljs-keyword">async</span> (req, res) =&gt; { },
  <span class="hljs-attr">getRecentConversation</span>: <span class="hljs-keyword">async</span> (req, res) =&gt; { },
  <span class="hljs-attr">getConversationByRoomId</span>: <span class="hljs-keyword">async</span> (req, res) =&gt; { },
  <span class="hljs-attr">markConversationReadByRoomId</span>: <span class="hljs-keyword">async</span> (req, res) =&gt; { },
}
</code></pre><p>And finally let's add content for <code>controllers/delete.js</code>:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">deleteRoomById</span>: <span class="hljs-keyword">async</span> (req, res) =&gt; {},
  <span class="hljs-attr">deleteMessageById</span>: <span class="hljs-keyword">async</span> (req, res) =&gt; {},
}
</code></pre><p>So far we have added empty controllers for each route, so they don't do much yet. We'll add functionality in a bit.</p>
<p>Just one more thing – let's add a new folder called <code>middlewares</code> and inside that folder create a file called <code>jwt.js</code>. Then add the following content to it:</p>
<pre><code><span class="hljs-keyword">import</span> jwt <span class="hljs-keyword">from</span> <span class="hljs-string">'jsonwebtoken'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> decode = <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> encode = <span class="hljs-keyword">async</span> (req, res, next) =&gt; {}
</code></pre><p>I will talk about what this file does in a bit, so for now let's just ignore it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/0f2621f3fad63457842f817f81df58ec.gif" alt="Image" width="600" height="400" loading="lazy">
<em>We are done with our basic boilerplate of the code base</em></p>
<p>We have ended up doing the following:</p>
<ul>
<li>Created an Express server that listens on port 3000</li>
<li>Added cross-origin-resource (CORS) to our <code>server.js</code></li>
<li>Added a logger to our <code>server.js</code></li>
<li>And also added route handlers with empty controllers.</li>
</ul>
<p>Nothing fancy so far that I haven't covered in the videos above.</p>
<h2 id="heading-lets-setup-mongodb-in-our-application">Let's setup MongoDB in our application</h2>
<p>Before we add MongoDB to our code base, make sure it is installed in your machine by running one of the following:</p>
<ul>
<li>For Windows users installation guide [<a target="_blank" href="https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/#procedure">here</a>]</li>
<li>For macOS users installation guide [<a target="_blank" href="https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/#install-homebrew">here</a>][<a target="_blank" href="https://github.com/adeelibr/node-playground/blob/master/chapter-1-chat/guidelines/installing-mongo.md">To the point installation that I wrote</a>]</li>
<li>For Linux users installation guide [<a target="_blank" href="https://docs.mongodb.com/manual/administration/install-on-linux/">here</a>]</li>
</ul>
<p>If you are having issues installing MongoDB, just let me know at <a target="_blank" href="https://twitter.com/adeelibr">https://twitter.com/adeelibr</a> and I'll write a custom guide for you or make an installation video guide. :)</p>
<p>I am using <a target="_blank" href="https://robomongo.org/">Robo3T</a> as my MongoDB GUI.</p>
<p>Now you should have your MongoDB instance running and <a target="_blank" href="https://robomongo.org/">Robo3T</a> installed. (You can use any GUI client that you like for this. I like <a target="_blank" href="https://robomongo.org/">Robo3T</a> a lot so I'm using it. Also, it's open source.)</p>
<p>Here is a small video I found on YouTube that gives a 6 minute intro to <a target="_blank" href="https://robomongo.org/">Robo3T</a>:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/DKZr1Urs7sA" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Once your MongoDB instance is up and running let's begin integrating MongoDB in our code as well.</p>
<p>In your root folder create a new folder called <code>config</code>. Inside that folder create a file called <code>index.js</code> and add the following content:</p>
<pre><code><span class="hljs-keyword">const</span> config = {
  <span class="hljs-attr">db</span>: {
    <span class="hljs-attr">url</span>: <span class="hljs-string">'localhost:27017'</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">'chatdb'</span>
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> config
</code></pre><p>Usually the default port that <code>MongoDB</code> instances will run on is <code>27017</code>.</p>
<p>Here we set info about our database URL (which is in <code>db</code>) and the <code>name</code> of database which is <code>chatdb</code> (you can call this whatever you want).</p>
<p>Next create a new file called <code>config/mongo.js</code> and add the following content:</p>
<pre><code><span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">'mongoose'</span>
<span class="hljs-keyword">import</span> config <span class="hljs-keyword">from</span> <span class="hljs-string">'./index.js'</span>

<span class="hljs-keyword">const</span> CONNECTION_URL = <span class="hljs-string">`mongodb://<span class="hljs-subst">${config.db.url}</span>/<span class="hljs-subst">${config.db.name}</span>`</span>

mongoose.connect(CONNECTION_URL, {
  <span class="hljs-attr">useNewUrlParser</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">useUnifiedTopology</span>: <span class="hljs-literal">true</span>
})

mongoose.connection.on(<span class="hljs-string">'connected'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Mongo has connected succesfully'</span>)
})
mongoose.connection.on(<span class="hljs-string">'reconnected'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Mongo has reconnected'</span>)
})
mongoose.connection.on(<span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Mongo connection has an error'</span>, error)
  mongoose.disconnect()
})
mongoose.connection.on(<span class="hljs-string">'disconnected'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Mongo connection is disconnected'</span>)
})
</code></pre><p>Next import <code>config/mongo.js</code> in your <code>server/index.js</code> file like this:</p>
<pre><code>.
.
<span class="hljs-comment">// mongo connection</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"./config/mongo.js"</span>;
<span class="hljs-comment">// routes</span>
<span class="hljs-keyword">import</span> indexRouter <span class="hljs-keyword">from</span> <span class="hljs-string">"./routes/index.js"</span>;
</code></pre><p>If you get lost at any time, the entire source code for this tutorial is right <a target="_blank" href="https://github.com/adeelibr/node-playground/tree/master/chapter-1-chat"><strong>here</strong></a><strong>.</strong></p>
<p>Let's discuss what we are doing here step by step:</p>
<p>We first import our <code>config.js</code> file in <code>config/mongo.js</code>. Next we pass in the value to our <code>CONNECTION_URL</code> like this:</p>
<pre><code><span class="hljs-keyword">const</span> CONNECTION_URL = <span class="hljs-string">`mongodb://<span class="hljs-subst">${config.db.url}</span>/<span class="hljs-subst">${config.db.name}</span>`</span>
</code></pre><p>Then using the <code>CONNECTION_URL</code> we form a Mongo connection, by doing this:</p>
<pre><code>mongoose.connect(CONNECTION_URL, {
  <span class="hljs-attr">useNewUrlParser</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">useUnifiedTopology</span>: <span class="hljs-literal">true</span>
})
</code></pre><p>This tells <code>mongoose</code> to make a connection with the database with our Node/Express application.</p>
<p>The options we are giving Mongo here are:</p>
<ul>
<li><code>useNewUrlParser</code>: MongoDB driver has deprecated their current <a target="_blank" href="https://docs.mongodb.com/manual/reference/connection-string/">connection string</a> parser. <code>useNewUrlParser: true</code> tells mongoose to use the new parser by Mongo. (If it's set to true, we have to provide a database port in the <code>CONNECTION_URL</code>.)</li>
<li><code>useUnifiedTopology</code>: False by default. Set to <code>true</code> to opt in to using <a target="_blank" href="https://mongoosejs.com/docs/deprecations.html#useunifiedtopology">MongoDB driver's new connection management engine</a>. You should set this option to <code>true</code>, except for the unlikely case that it prevents you from maintaining a stable connection.</li>
</ul>
<p>Next we simply add <code>mongoose</code> event handlers like this:</p>
<pre><code>mongoose.connection.on(<span class="hljs-string">'connected'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Mongo has connected succesfully'</span>)
})
mongoose.connection.on(<span class="hljs-string">'reconnected'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Mongo has reconnected'</span>)
})
mongoose.connection.on(<span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Mongo connection has an error'</span>, error)
  mongoose.disconnect()
})
mongoose.connection.on(<span class="hljs-string">'disconnected'</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Mongo connection is disconnected'</span>)
})
</code></pre><ul>
<li><code>connected</code> will be called once the database connection is established</li>
<li><code>disconnected</code> will be called when your Mongo connection is disabled</li>
<li><code>error</code> is called if there is an error connecting to your Mongo database</li>
<li><code>reconnected</code> event is called when the database loses connection and then makes an attempt to successfully reconnect. </li>
</ul>
<p>Once you have this in place, simply go in your <code>server/index.js</code> file and import <code>config/mongo.js</code>. And that is it. Now when you start up your server by typing this:</p>
<pre><code>npm start;
</code></pre><p>You should see something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-15-at-19.42.53.png" alt="Image" width="600" height="400" loading="lazy">
<em>Logs when you start your server</em></p>
<p>If you see this you have successfully added Mongo to your application.</p>
<p>Congratulations!</p>
<p>If you got stuck here for some reason, let me know at <a target="_blank" href="https://twitter.com/adeelibr">twitter.com/adeelibr</a> and I will try to sort it out for you. :)</p>
<h2 id="heading-lets-setup-our-first-api-section-for-users">Let's setup our first API section for users/</h2>
<p>The setup of our API for <code>users/</code> will have no authentication token for this tutorial, because my main focus is to teach you about the Chat application here.</p>
<h3 id="heading-user-modal-scheme">User Modal Scheme</h3>
<p>Let's create our first model (database scheme) for the <code>user</code> collection.</p>
<p>Create a new folder called <code>models</code>. Inside that folder create a file called <code>User.js</code> and add the following content:</p>
<pre><code><span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;
<span class="hljs-keyword">import</span> { v4 <span class="hljs-keyword">as</span> uuidv4 } <span class="hljs-keyword">from</span> <span class="hljs-string">"uuid"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> USER_TYPES = {
  <span class="hljs-attr">CONSUMER</span>: <span class="hljs-string">"consumer"</span>,
  <span class="hljs-attr">SUPPORT</span>: <span class="hljs-string">"support"</span>,
};

<span class="hljs-keyword">const</span> userSchema = <span class="hljs-keyword">new</span> mongoose.Schema(
  {
    <span class="hljs-attr">_id</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">default</span>: <span class="hljs-function">() =&gt;</span> uuidv4().replace(<span class="hljs-regexp">/\-/g</span>, <span class="hljs-string">""</span>),
    },
    <span class="hljs-attr">firstName</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">lastName</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
  },
  {
    <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">collection</span>: <span class="hljs-string">"users"</span>,
  }
);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> mongoose.model(<span class="hljs-string">"User"</span>, userSchema);
</code></pre><p>Let's break this down into pieces:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> USER_TYPES = {
  <span class="hljs-attr">CONSUMER</span>: <span class="hljs-string">"consumer"</span>,
  <span class="hljs-attr">SUPPORT</span>: <span class="hljs-string">"support"</span>,
};
</code></pre><p>We are basically going to have 2 types of users, <code>consumer</code> and <code>support</code>. I have written it this way because I want to programmatically ensure API and DB validation, which I will talk about later.</p>
<p>Next we create a schema on how a single <code>document</code> (object/item/entry/row) will look inside our <code>user</code> collection (a collection is equivalent to a MySQL table). We define it like this:</p>
<pre><code><span class="hljs-keyword">const</span> userSchema = <span class="hljs-keyword">new</span> mongoose.Schema(
  {
    <span class="hljs-attr">_id</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">default</span>: <span class="hljs-function">() =&gt;</span> uuidv4().replace(<span class="hljs-regexp">/\-/g</span>, <span class="hljs-string">""</span>),
    },
    <span class="hljs-attr">firstName</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">lastName</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
  },
  {
    <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">collection</span>: <span class="hljs-string">"users"</span>,
  }
);
</code></pre><p>Here we are telling <code>mongoose</code> that for a single document in our <code>users</code> collection we want the structure to be like this:</p>
<pre><code>{
    <span class="hljs-attr">id</span>: <span class="hljs-built_in">String</span> <span class="hljs-comment">// will get random string by default thanks to uuidv4</span>
        <span class="hljs-attr">firstName</span>: <span class="hljs-built_in">String</span>,
        <span class="hljs-attr">lastName</span>: <span class="hljs-built_in">String</span>,
        <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span> <span class="hljs-comment">// this can be of 2 types consumer/support</span>
}
</code></pre><p>In the second part of the schema we have something like this:</p>
<pre><code>{
    <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">collection</span>: <span class="hljs-string">"users"</span>,
}
</code></pre><p>Setting <code>timestamps</code> to <code>true</code> will add 2 things to my schema: a <code>createdAt</code> and a <code>updatedAt</code> date value. Every time when we create a new entry the <code>createdAt</code> will be updated automatically and <code>updatedAt</code> will update once we update an entry in the database using mongoose. Both of these are done automatically by <code>mongoose</code>.</p>
<p>The second part is <code>collection</code>. This shows what my collection name will be inside my database. I am assigning it the name of <code>users</code>.</p>
<p>And then finally we'll export the object like this:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> mongoose.model(<span class="hljs-string">"User"</span>, userSchema);
</code></pre><p>So <code>mongoose.model</code> takes in 2 parameters here. </p>
<ul>
<li>The name of the model, which is <code>User</code> here</li>
<li>The schema associated with that model, which is <code>userSchema</code> in this case</li>
</ul>
<p>Note: Based on the name of the model, which is <code>User</code> in this case, we don't add <code>collection</code> key in the schema section. It will take this <code>User</code> name and append an <code>s</code> to it and create a collection by its name, which becomes <code>user</code>.</p>
<p>Great, now we have our first model.</p>
<p>If you've gotten stuck anywhere, just have a look at the <a target="_blank" href="https://github.com/adeelibr/node-playground/tree/master/chapter-1-chat">source code</a>.</p>
<h3 id="heading-create-a-new-user-api-post-request">Create a new user API [POST request]</h3>
<p>Next let's write our first controller for this route: <code>.post('/', user.onCreateUser)</code>.</p>
<p>Go inside <code>controllers/user.js</code> and import 2 things at the top:</p>
<pre><code><span class="hljs-comment">// utils</span>
<span class="hljs-keyword">import</span> makeValidation <span class="hljs-keyword">from</span> <span class="hljs-string">'@withvoid/make-validation'</span>;
<span class="hljs-comment">// models</span>
<span class="hljs-keyword">import</span> UserModel, { USER_TYPES } <span class="hljs-keyword">from</span> <span class="hljs-string">'../models/User.js'</span>;
</code></pre><p>Here we are importing the validation library that I talked about in the video at the very top. We are also importing our user modal along with the <code>USER_TYPES</code> from the same file.</p>
<p>This is what <code>USER_TYPES</code> represents:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> USER_TYPES = {
  <span class="hljs-attr">CONSUMER</span>: <span class="hljs-string">"consumer"</span>,
  <span class="hljs-attr">SUPPORT</span>: <span class="hljs-string">"support"</span>,
};
</code></pre><p>Next find the controller <code>onCreateUser</code> and add the following content to it:</p>
<pre><code>onCreateUser: <span class="hljs-keyword">async</span> (req, res) =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> validation = makeValidation(<span class="hljs-function"><span class="hljs-params">types</span> =&gt;</span> ({
        <span class="hljs-attr">payload</span>: req.body,
        <span class="hljs-attr">checks</span>: {
          <span class="hljs-attr">firstName</span>: { <span class="hljs-attr">type</span>: types.string },
          <span class="hljs-attr">lastName</span>: { <span class="hljs-attr">type</span>: types.string },
          <span class="hljs-attr">type</span>: { <span class="hljs-attr">type</span>: types.enum, <span class="hljs-attr">options</span>: { <span class="hljs-attr">enum</span>: USER_TYPES } },
        }
      }));
      <span class="hljs-keyword">if</span> (!validation.success) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json(validation);

      <span class="hljs-keyword">const</span> { firstName, lastName, type } = req.body;
      <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> UserModel.createUser(firstName, lastName, type);
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>, user });
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">error</span>: error })
    }
  },
</code></pre><p>Let's divide this into 2 sections.</p>
<p>First we validate the user response by doing this:</p>
<pre><code><span class="hljs-keyword">const</span> validation = makeValidation(<span class="hljs-function"><span class="hljs-params">types</span> =&gt;</span> ({
  <span class="hljs-attr">payload</span>: req.body,
  <span class="hljs-attr">checks</span>: {
    <span class="hljs-attr">firstName</span>: { <span class="hljs-attr">type</span>: types.string },
    <span class="hljs-attr">lastName</span>: { <span class="hljs-attr">type</span>: types.string },
    <span class="hljs-attr">type</span>: { <span class="hljs-attr">type</span>: types.enum, <span class="hljs-attr">options</span>: { <span class="hljs-attr">enum</span>: USER_TYPES } },
  }
}));
<span class="hljs-keyword">if</span> (!validation.success) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ ...validation });
</code></pre><p>Please make sure that you have seen the video (above) on <code>validate an API request in Node using custom validation or by using make-validation library</code>.</p>
<p>Here we are using the <code>[make-validation](https://www.npmjs.com/package/@withvoid/make-validation)</code> library (that I ended up making while writing this tutorial). I talk about it's usage in the video at the start of this tutorial.</p>
<p>All we are doing here is passing <code>req.body</code> to <code>payload</code>. Then in the checks we're adding an object where against each <code>key</code> we are telling what are the requirements for each type, for example:</p>
<pre><code>firstName: { <span class="hljs-attr">type</span>: types.string },
</code></pre><p>Here we are telling it that <code>firstName</code> is of type string. If the user forgets to add this value while hitting the API, or if the type is not string, it will throw an error.</p>
<p>The <code>validation</code> variable will return an object with 3 things: <code>{success: boolean, message: string, errors: object}</code>.</p>
<p>If <code>validation.success</code> is false we simply return everything from the validation and give it to the user with a status code of <code>400</code>.</p>
<p>Once our validation is in place and we know that the data we are getting are valid, then we do the following:</p>
<pre><code><span class="hljs-keyword">const</span> { firstName, lastName, type } = req.body;
<span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> UserModel.createUser(firstName, lastName, type);
<span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>, user });
</code></pre><p>Then we destruct <code>firstName, lastName, type</code> from <code>req.body</code> and pass those values to our <code>UserModel.createUser</code>. If everything goes right, it simply returns <code>success: true</code> with the new <code>user</code> created along with a status <code>200</code>. </p>
<p>If anywhere in this process anything goes wrong, it throws an error and goes to the catch block:</p>
<pre><code><span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">error</span>: error })
}
</code></pre><p>There we simply return an error message along with the HTTP status <code>500</code>.</p>
<p>The only thing we are missing here is the <code>UserModel.createUser()</code> method.</p>
<p>So let's go back into our <code>models/User.js</code> file and add it:</p>
<pre><code>userSchema.statics.createUser = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">
    firstName, 
        lastName, 
        type
</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.create({ firstName, lastName, type });
    <span class="hljs-keyword">return</span> user;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">throw</span> error;
  }
}


<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> mongoose.model(<span class="hljs-string">"User"</span>, userSchema);
</code></pre><p>So all we are doing here is adding a static method to our <code>userSchema</code> called <code>createUser</code> that takes in 3 parameters: <code>firstName, lastName, type</code>.</p>
<p>Next we use this:</p>
<pre><code><span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.create({ firstName, lastName, type });
</code></pre><p>Here the <code>this</code> part is very important, since we are writing a static method on <code>userSchema</code>. Writing <code>this</code> will ensure that we are using performing operations on the <code>userSchema</code> object</p>
<p>One thing to note here is that <code>userSchema.statics.createUser = async function (firstName, lastName, type) =&gt; {}</code> won't work. If you use an <code>=&gt;</code> arrow function the <code>this</code> context will be lost and it won't work.</p>
<p>If you want to learn more about <code>static</code> methods in mongoose, see this very short but helpful doc example <a target="_blank" href="https://mongoosejs.com/docs/2.7.x/docs/methods-statics.html">here</a>.</p>
<p>Now that we have everything set up, let's start our terminal by running the following command in the project's root folder:</p>
<pre><code>npm start;
</code></pre><p>Go into postman, set up a <code>POST</code> request on this API <code>http://localhost:3000/users</code>, and add the following body to the API:</p>
<pre><code>{
    <span class="hljs-attr">firstName</span>: <span class="hljs-string">'John'</span>
        <span class="hljs-attr">lastName</span>: <span class="hljs-string">'Doe'</span>,
        <span class="hljs-attr">type</span>: <span class="hljs-string">'consumer'</span>
}
</code></pre><p>Like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-15-at-21.37.15.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can also get the <strong>entire postman API</strong> collection from <a target="_blank" href="https://www.getpostman.com/collections/c28b12148c3d980fc39d"><strong>here</strong></a> so that you don't have to write the APIs again and again.</p>
<p>Awesome – we just ended up creating our first API. Let's create a couple more user APIs before we move to the chat part because there is no chat without users (unless we have robots, but robots are users as well ?).</p>
<h3 id="heading-get-a-user-by-its-id-api-get-request">Get a user by its ID API [GET request]</h3>
<p>Next we need to write an API that gets us a user by its ID. So for our route <code>.get('/:id', user.onGetUserById)</code> let's write down its controller.</p>
<p>Go to <code>controllers/user.js</code> and for the method <code>onGetUserById</code> write this:</p>
<pre><code>onGetUserById: <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> UserModel.getUserById(req.params.id);
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>, user });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">error</span>: error })
  }
},
</code></pre><p>Cool, this looks straightforward. Let's add <code>UserModel.getUserById()</code> in our <code>models/User.js</code> file.</p>
<p>Add this method below the last <code>static</code> method you wrote:</p>
<pre><code>userSchema.statics.getUserById = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">id</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.findOne({ <span class="hljs-attr">_id</span>: id });
    <span class="hljs-keyword">if</span> (!user) <span class="hljs-keyword">throw</span> ({ <span class="hljs-attr">error</span>: <span class="hljs-string">'No user with this id found'</span> });
    <span class="hljs-keyword">return</span> user;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">throw</span> error;
  }
}
</code></pre><p>We pass in an <code>id</code> parameter and we wrap our function in <code>try/catch</code>. This is very important when you are using <code>async/await</code>. The lines to focus on here are these 2:</p>
<pre><code><span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.findOne({ <span class="hljs-attr">_id</span>: id });
<span class="hljs-keyword">if</span> (!user) <span class="hljs-keyword">throw</span> ({ <span class="hljs-attr">error</span>: <span class="hljs-string">'No user with this id found'</span> });
</code></pre><p>We use <code>mongoose</code>'s  <code>findOne</code> method to find an entry by <code>id</code>. We know that only one item exists in the collection by this <code>id</code> because the <code>id</code> is unique. If no user is found we simply throw an error with the message <code>No user with this id found</code>.</p>
<p>And that is it! Let's start up our server:</p>
<pre><code>npm start;
</code></pre><p>Open up postman and create a <code>GET</code> request <code>http://localhost:3000/users/:id</code>.</p>
<p>Note: I am using the ID of the last user we just created.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-15-at-22.01.16.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Nicely done! Good job.</p>
<p>Two more API's to go for our user section.</p>
<h3 id="heading-get-all-users-api-get-request">Get all users API [GET request]</h3>
<p>For our router in <code>.get('/', user.onGetAllUsers)</code> let's add information to its controller.</p>
<p>Go to <code>controllers/user.js</code> and add code in the <code>onGetAllUsers()</code> method:</p>
<pre><code>onGetAllUsers: <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> users = <span class="hljs-keyword">await</span> UserModel.getUsers();
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>, users });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">error</span>: error })
  }
},
</code></pre><p>Next let's create the static method for <code>getUsers()</code> in the <code>models/User.js</code> file. Below the last static method you wrote in that file, type:</p>
<pre><code>userSchema.statics.getUsers = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> users = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.find();
    <span class="hljs-keyword">return</span> users;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">throw</span> error;
  }
}
</code></pre><p>We use the <code>mongoose</code> method called <code>await this.find();</code> to get all the records for our <code>users</code> collection and return it.</p>
<p>Note: I am not handling pagination in our users API because that's not the main focus here. I'll talk about pagination once we move towards our chat APIs.</p>
<p>Let's start our server:</p>
<pre><code>npm start;
</code></pre><p>Open up postman and create a <code>GET</code> request for this route <code>http://localhost:3000/users</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-15-at-22.12.13.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>I went ahead and ended up creating a couple more users. ?</p>
<h3 id="heading-delete-a-user-by-id-api-delete-request-more-of-a-bonus-section-you-can-skip-this-if-you-want">Delete a user by ID API [DELETE request] (More of a bonus section, you can skip this if you want)</h3>
<p>Let's create our final route to delete a user by their ID. For the route <code>.delete('/:id', user.onDeleteUserById)</code> go to its controller in <code>controllers/user.js</code> and write this code in the <code>onDeleteUserById()</code> method:</p>
<pre><code>onDeleteUserById: <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> UserModel.deleteByUserById(req.params.id);
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({ 
      <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>, 
      <span class="hljs-attr">message</span>: <span class="hljs-string">`Deleted a count of <span class="hljs-subst">${user.deletedCount}</span> user.`</span> 
    });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">error</span>: error })
  }
},
</code></pre><p>Let's add the static method <code>deleteByUserById</code> in <code>models/User.js</code>:</p>
<pre><code>userSchema.statics.deleteByUserById = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">id</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.remove({ <span class="hljs-attr">_id</span>: id });
    <span class="hljs-keyword">return</span> result;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">throw</span> error;
  }
}
</code></pre><p>We pass in the <code>id</code> here as a parameter and then use the <code>mongoose</code> method called <code>this.remove</code> to delete a record item from a specific collection. In this case, it's the <code>users</code> collection.</p>
<p>Let's start up our server:</p>
<pre><code>npm start;
</code></pre><p>Go to postman and create a new <code>DELETE</code> route:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-15-at-22.24.51.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>With this we'll conclude our USER API section. </p>
<p>Next we will cover how to authenticate routes with an authentication token. This is the last thing I want to touch on before moving on to the chat section – because all of the chat APIs will be authenticated.</p>
<h3 id="heading-what-are-middlewares-in-expressjs">What are middlewares in ExpressJS?</h3>
<p>How can we write them? By adding JWT middleware in your application:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/G8Z6yeV0ytc" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>And here's the <a target="_blank" href="https://github.com/adeelibr/node-playground/tree/master/chapter-0-basic">GitHub link to the entire source code of this video</a> [Chapter 0].</p>
<p>And again, all the relevant info can be found in the READ.ME.</p>
<p>Coming back to our code base, let's create a JWT middleware to authenticate our routes. Go to <code>middlewares/jwt.js</code> and add the following:</p>
<pre><code><span class="hljs-keyword">import</span> jwt <span class="hljs-keyword">from</span> <span class="hljs-string">'jsonwebtoken'</span>;
<span class="hljs-comment">// models</span>
<span class="hljs-keyword">import</span> UserModel <span class="hljs-keyword">from</span> <span class="hljs-string">'../models/User.js'</span>;

<span class="hljs-keyword">const</span> SECRET_KEY = <span class="hljs-string">'some-secret-key'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> encode = <span class="hljs-keyword">async</span> (req, res, next) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { userId } = req.params;
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> UserModel.getUserById(userId);
    <span class="hljs-keyword">const</span> payload = {
      <span class="hljs-attr">userId</span>: user._id,
      <span class="hljs-attr">userType</span>: user.type,
    };
    <span class="hljs-keyword">const</span> authToken = jwt.sign(payload, SECRET_KEY);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Auth'</span>, authToken);
    req.authToken = authToken;
    next();
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">message</span>: error.error });
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> decode = <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (!req.headers[<span class="hljs-string">'authorization'</span>]) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">message</span>: <span class="hljs-string">'No access token provided'</span> });
  }
  <span class="hljs-keyword">const</span> accessToken = req.headers.authorization.split(<span class="hljs-string">' '</span>)[<span class="hljs-number">1</span>];
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> decoded = jwt.verify(accessToken, SECRET_KEY);
    req.userId = decoded.userId;
    req.userType = decoded.type;
    <span class="hljs-keyword">return</span> next();
  } <span class="hljs-keyword">catch</span> (error) {

    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">401</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">message</span>: error.message });
  }
}
</code></pre><p>Let's discuss the <code>encode</code> method first:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> encode = <span class="hljs-keyword">async</span> (req, res, next) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { userId } = req.params;
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> UserModel.getUserById(userId);
    <span class="hljs-keyword">const</span> payload = {
      <span class="hljs-attr">userId</span>: user._id,
      <span class="hljs-attr">userType</span>: user.type,
    };
    <span class="hljs-keyword">const</span> authToken = jwt.sign(payload, SECRET_KEY);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Auth'</span>, authToken);
    req.authToken = authToken;
    next();
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ 
        <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">message</span>: error.error 
    });
  }
}
</code></pre><p>Let's go through it step by step.</p>
<p>We get the <code>userId</code> from our <code>req.params</code>. If you remember from the video earlier, <code>req.params</code> is the <code>/:&lt;identifier&gt;</code> defined in our routes section.</p>
<p>Next we use the <code>const user = await UserModel.getUserById(userId);</code> method we just created recently to get user information. If it exists, that is – otherwise this line will throw an error and it will directly go to the <code>catch</code> block where we will return the user with a <code>400</code> response and and an error message.</p>
<p>But if we get a response from the <code>getUserById</code> method we then make a payload:</p>
<pre><code><span class="hljs-keyword">const</span> payload = {
      <span class="hljs-attr">userId</span>: user._id,
      <span class="hljs-attr">userType</span>: user.type,
};
</code></pre><p>Next we sign that payload in JWT using the following:</p>
<pre><code><span class="hljs-keyword">const</span> authToken = jwt.sign(payload, SECRET_KEY);
</code></pre><p>Once we have the JWT signed we then do this:</p>
<pre><code>req.authToken = authToken;
next();
</code></pre><p>Set it to our <code>req.authToken</code> and then forward this information as <code>next()</code>.</p>
<p>Next let's talk about the <code>decode</code> method:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> decode = <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (!req.headers[<span class="hljs-string">'authorization'</span>]) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">message</span>: <span class="hljs-string">'No access token provided'</span> });
  }
  <span class="hljs-keyword">const</span> accessToken = req.headers.authorization.split(<span class="hljs-string">' '</span>)[<span class="hljs-number">1</span>];
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> decoded = jwt.verify(accessToken, SECRET_KEY);
    req.userId = decoded.userId;
    req.userType = decoded.type;
    <span class="hljs-keyword">return</span> next();
  } <span class="hljs-keyword">catch</span> (error) {

    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">401</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">message</span>: error.message });
  }
}
</code></pre><p>Let's break this down:</p>
<pre><code><span class="hljs-keyword">if</span> (!req.headers[<span class="hljs-string">'authorization'</span>]) {
  <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ 
      <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, 
        <span class="hljs-attr">message</span>: <span class="hljs-string">'No access token provided'</span> 
  });
}
</code></pre><p>First we check if the <code>authorization</code> header is present or not. If not we simply return an error message to user.</p>
<p>Then we do this:</p>
<pre><code><span class="hljs-keyword">const</span> accessToken = req.headers.authorization.split(<span class="hljs-string">' '</span>)[<span class="hljs-number">1</span>];
</code></pre><p>It's being <code>split(' ')</code> by space and then we are getting the second index of the array by accessing its <code>[1]</code> index because the convention is <code>authorization: Bearer &lt;auth-token&gt;</code>. Want to read more on this? Check out this nice <a target="_blank" href="https://www.quora.com/Why-is-Bearer-required-before-the-token-in-Authorization-header-in-a-HTTP-request">thread on quora</a>.</p>
<p>Then we try to decode our token:</p>
<pre><code><span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> decoded = jwt.verify(accessToken, SECRET_KEY);
  req.userId = decoded.userId;
  req.userType = decoded.type;
  <span class="hljs-keyword">return</span> next();
} <span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">401</span>).json({ 
      <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">message</span>: error.message 
  });
}
</code></pre><p>If this is not successful <code>jwt.verify(accessToken, SECRET_KEY)</code> will simply throw an error and our code will go in the <code>catch</code> block immediately. If it is successful, then we can decode it. We get <code>userId</code> and <code>type</code> from the token and save it as <code>req.userId, req.userType</code> and simply hit <code>next()</code>.</p>
<p>Now, moving forward, every route that goes through this <code>decode</code> middleware will have the current user's <code>id &amp; it's type</code>.</p>
<p>This was it for the middleware section. Let's create a <code>login</code> route so that we can ask a user for their information and give a token in return (because moving forward they'll need a token to access the rest of chat APIs).</p>
<h3 id="heading-creating-a-login-route-post-request">Creating a login route [POST request]</h3>
<p>Go to your <code>routes/index.js</code> file and paste the following content:</p>
<pre><code><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-comment">// middlewares</span>
<span class="hljs-keyword">import</span> { encode } <span class="hljs-keyword">from</span> <span class="hljs-string">'../middlewares/jwt.js'</span>;

<span class="hljs-keyword">const</span> router = express.Router();

router
  .post(<span class="hljs-string">'/login/:userId'</span>, encode, <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {
    <span class="hljs-keyword">return</span> res
      .status(<span class="hljs-number">200</span>)
      .json({
        <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
        <span class="hljs-attr">authorization</span>: req.authToken,
      });
  });

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> router;
</code></pre><p>So all we are doing is adding the <code>encode</code> middleware to our <code>http://localhost:3000/login/:&lt;user-id&gt;</code> [POST] route. If everything goes smoothly the user will get an <code>authorization</code> token.</p>
<p>Note: I am not adding a login/signup flow, but I still wanted to touch on JWT/middleware in this tutorial.</p>
<p>Usually authentication is done in a similar way. The only addition here is that the user doesn't provide their ID. They provide their username, password (which we verify in the database), and if everything checks out we give them an authorization token.</p>
<p>If you got stuck anywhere up to this point, just write to me at <a target="_blank" href="https://twitter.com/adeelibr">twitter.com/adeelibr</a>, so that way I can improve the content. You can also write to me if you would like to learn something else.</p>
<p>As a reminder, the entire source code is available <a target="_blank" href="https://github.com/adeelibr/node-playground/tree/master/chapter-1-chat">here</a>. You don't have to code along with this tutorial, but if you do the concepts will stick better.</p>
<p>Let's just check our <code>/login</code> route now.</p>
<p>Start your server:</p>
<pre><code>npm start;
</code></pre><p>Let's run postman. Create a new POST request <code>http://localhost:3000/login/&lt;user-id&gt;</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-15-at-23.03.15.png" alt="Image" width="600" height="400" loading="lazy">
<em>When the user ID is correct</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-15-at-23.03.32.png" alt="Image" width="600" height="400" loading="lazy">
<em>When the user ID is invalid</em></p>
<p>With this we are done with our login flow as well.</p>
<p>This was a lot. But now we can focus only on our chat routes.</p>
<h2 id="heading-create-a-web-socket-class">Create a web socket class</h2>
<p>This web socket class will handle events when a user disconnects, joins a chat room, or wants to mute a chat room.</p>
<p>So let's create a web-socket class that will manage sockets for us. Create a new folder called <code>utils</code>. Inside that folder create a file called <code>WebSockets.js</code> and add the following content:</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WebSockets</span> </span>{
  users = [];
  connection(client) {
    <span class="hljs-comment">// event fired when the chat room is disconnected</span>
    client.on(<span class="hljs-string">"disconnect"</span>, <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">this</span>.users = <span class="hljs-built_in">this</span>.users.filter(<span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> user.socketId !== client.id);
    });
    <span class="hljs-comment">// add identity of user mapped to the socket id</span>
    client.on(<span class="hljs-string">"identity"</span>, <span class="hljs-function">(<span class="hljs-params">userId</span>) =&gt;</span> {
      <span class="hljs-built_in">this</span>.users.push({
        <span class="hljs-attr">socketId</span>: client.id,
        <span class="hljs-attr">userId</span>: userId,
      });
    });
    <span class="hljs-comment">// subscribe person to chat &amp; other user as well</span>
    client.on(<span class="hljs-string">"subscribe"</span>, <span class="hljs-function">(<span class="hljs-params">room, otherUserId = <span class="hljs-string">""</span></span>) =&gt;</span> {
      <span class="hljs-built_in">this</span>.subscribeOtherUser(room, otherUserId);
      client.join(room);
    });
    <span class="hljs-comment">// mute a chat room</span>
    client.on(<span class="hljs-string">"unsubscribe"</span>, <span class="hljs-function">(<span class="hljs-params">room</span>) =&gt;</span> {
      client.leave(room);
    });
  }

  subscribeOtherUser(room, otherUserId) {
    <span class="hljs-keyword">const</span> userSockets = <span class="hljs-built_in">this</span>.users.filter(
      <span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> user.userId === otherUserId
    );
    userSockets.map(<span class="hljs-function">(<span class="hljs-params">userInfo</span>) =&gt;</span> {
      <span class="hljs-keyword">const</span> socketConn = <span class="hljs-built_in">global</span>.io.sockets.connected(userInfo.socketId);
      <span class="hljs-keyword">if</span> (socketConn) {
        socketConn.join(room);
      }
    });
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">new</span> WebSockets();
</code></pre><p>The WebSockets class has three major things here:</p>
<ul>
<li>users array</li>
<li>connection method</li>
<li>subscribing members of a chat room to it. <code>subscribeOtherUser</code></li>
</ul>
<p>Let's break this down.</p>
<p>We have a class: </p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WebSockets</span> </span>{

}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">new</span> WebSocket();
</code></pre><p>We create a class and export an instance of that class.</p>
<p>Inside the class we have an empty <code>users</code> array. This array will hold a list of all the active users that are online using our application.</p>
<p>Next we have a <code>connection</code> method, the core of this class:</p>
<pre><code>connection(client) {
  <span class="hljs-comment">// event fired when the chat room is disconnected</span>
  client.on(<span class="hljs-string">"disconnect"</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">this</span>.users = <span class="hljs-built_in">this</span>.users.filter(<span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> user.socketId !== client.id);
  });
  <span class="hljs-comment">// add identity of user mapped to the socket id</span>
  client.on(<span class="hljs-string">"identity"</span>, <span class="hljs-function">(<span class="hljs-params">userId</span>) =&gt;</span> {
    <span class="hljs-built_in">this</span>.users.push({
      <span class="hljs-attr">socketId</span>: client.id,
      <span class="hljs-attr">userId</span>: userId,
    });
  });
  <span class="hljs-comment">// subscribe person to chat &amp; other user as well</span>
  client.on(<span class="hljs-string">"subscribe"</span>, <span class="hljs-function">(<span class="hljs-params">room, otherUserId = <span class="hljs-string">""</span></span>) =&gt;</span> {
    <span class="hljs-built_in">this</span>.subscribeOtherUser(room, otherUserId);
    client.join(room);
  });
  <span class="hljs-comment">// mute a chat room</span>
  client.on(<span class="hljs-string">"unsubscribe"</span>, <span class="hljs-function">(<span class="hljs-params">room</span>) =&gt;</span> {
    client.leave(room);
  });
}
</code></pre><p>The <code>connection</code> method takes in a parameter called <code>client</code> (client here will be our server instance, I will talk more about this in a bit).</p>
<p>We take the param <code>client</code> and add some event to it</p>
<ul>
<li>client.on('disconnect') // when a user connection is lost this method will be called</li>
<li>client.on('identity') // when user logs in from the front end they will make a connection with our server by giving their identity</li>
<li>client.on('subscribe') // when a user joins a chat room this method is called</li>
<li>client.on('unsubscribe') // when a user leaves or wants to mute a chat room</li>
</ul>
<p>Let's talk about <code>disconnect</code>:</p>
<pre><code>client.on(<span class="hljs-string">"disconnect"</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">this</span>.users = <span class="hljs-built_in">this</span>.users.filter(<span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> user.socketId !== client.id);
});
</code></pre><p>As soon as the connection is disconnected, we run a filter on users array. Where we find <code>user.id === client.id</code> we remove it from our sockets array. ( <code>client</code> here is coming from the function param.)</p>
<p>Let's talk about <code>identity</code>:</p>
<pre><code>client.on(<span class="hljs-string">"identity"</span>, <span class="hljs-function">(<span class="hljs-params">userId</span>) =&gt;</span> {
  <span class="hljs-built_in">this</span>.users.push({
    <span class="hljs-attr">socketId</span>: client.id,
    <span class="hljs-attr">userId</span>: userId,
  });
});
</code></pre><p>When a user logs in through he front end application web/android/ios they will make a socket connection with our backend app and call this identity method. They'll also send their own user id.</p>
<p>We will take that user id and the client id (the user's own unique socket id that socket.io creates when they make a connection with our BE).</p>
<p>Next we have <code>unsubscribe</code>:</p>
<pre><code>client.on(<span class="hljs-string">"unsubscribe"</span>, <span class="hljs-function">(<span class="hljs-params">room</span>) =&gt;</span> {
  client.leave(room);
});
</code></pre><p>The user passes in the <code>room</code> id and we just tell <code>client.leave()</code> to remove the current user calling this method from a particular chat room.</p>
<p>Next we have subscribe:</p>
<pre><code>client.on(<span class="hljs-string">"subscribe"</span>, <span class="hljs-function">(<span class="hljs-params">room, otherUserId = <span class="hljs-string">""</span></span>) =&gt;</span> {
  <span class="hljs-built_in">this</span>.subscribeOtherUser(room, otherUserId);
  client.join(room);
});
</code></pre><p>When a user joins a chat room, they will tell us about the room they want to join along with the other person who is part of that chat room.</p>
<p>Note: We will see later that when we initiate a chat room we get all the users associated with that room in the API response.</p>
<p><strong>In my opinion</strong>: Another thing we could have done here was when the user sends in the room number, we can make a DB query to see all the members of the chat room and make them join if they are online at the moment (that is, in our users list).</p>
<p>The <code>subscribeOtherUser</code> method is defined like this:</p>
<pre><code>subscribeOtherUser(room, otherUserId) {
  <span class="hljs-keyword">const</span> userSockets = <span class="hljs-built_in">this</span>.users.filter(
    <span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> user.userId === otherUserId
  );
  userSockets.map(<span class="hljs-function">(<span class="hljs-params">userInfo</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> socketConn = <span class="hljs-built_in">global</span>.io.sockets.connected(userInfo.socketId);
    <span class="hljs-keyword">if</span> (socketConn) {
      socketConn.join(room);
    }
  });
}
</code></pre><p>We pass in  <code>room</code> and <code>otherUserId</code> as params to this function.</p>
<p>Using the <code>otherUserId</code> we filter on our <code>this.users</code> array and all the results that match are stored in <code>userSockets</code> array.</p>
<p>You might be thinking – how can one user have multiple presences in the user array? Well, think of a scenario where the same user is logged in from both their web application and mobile phone. It will create multiple socket connections for the same user.</p>
<p>Next we map on <code>userSockets</code>. For each item in this array we pass it into this method:  <code>const socketConn = global.io.sockets.connected(userInfo.socketId)</code> </p>
<p>I will talk more about this <code>global.io.sockets.connected</code> in a bit. But what this initially does is it takes in <code>userInfo.socketId</code> and if it exists in our socket connection, it will return the connection, otherwise <code>null</code>.</p>
<p>Next we simply see if <code>socketConn</code> is available. If so, we take that <code>socketConn</code> and make this connection join the <code>room</code> passed in the function:</p>
<pre><code><span class="hljs-keyword">if</span> (socketConn) {
    socketConn.join(room);
}
</code></pre><p>And this is it for our WebSockets class.</p>
<p>Let's import this file in our <code>server/index.js</code> file:</p>
<pre><code><span class="hljs-keyword">import</span> socketio <span class="hljs-keyword">from</span> <span class="hljs-string">"socket.io"</span>;
<span class="hljs-comment">// mongo connection</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"./config/mongo.js"</span>;
<span class="hljs-comment">// socket configuration</span>
<span class="hljs-keyword">import</span> WebSockets <span class="hljs-keyword">from</span> <span class="hljs-string">"./utils/WebSockets.js"</span>;
</code></pre><p>So just import <code>socket.io</code> and import <code>WebSockets</code> somewhere at the top.</p>
<p>Next where we are creating our server add the content below this:</p>
<pre><code><span class="hljs-comment">/** Create HTTP server. */</span>
<span class="hljs-keyword">const</span> server = http.createServer(app);
<span class="hljs-comment">/** Create socket connection */</span>
<span class="hljs-built_in">global</span>.io = socketio.listen(server);
<span class="hljs-built_in">global</span>.io.on(<span class="hljs-string">'connection'</span>, WebSockets.connection)
</code></pre><p>The <code>server</code> was created and we do two things:</p>
<ul>
<li>assign <code>global.io</code> to <code>socketio.listen(server)</code> (As soon as a port starts listening on the <code>server</code>, sockets starts listening for events happening on that port as well.)</li>
<li>then we assign <code>global.io.on('connection', WebSockets.connection)</code> method. Every time someone from the front end makes a socket connection, the <code>connection</code> method will be called which will invoke our <code>Websockets</code> class and inside that class the <code>connection</code> method.</li>
</ul>
<p><code>global.io</code> is equivalent to <code>windows</code> object in browser. But since we don't have <code>windows</code> in NodeJS we use <code>global.io</code>. Whatever we put in <code>global.io</code> is available in the entire application.</p>
<p>This is the same <code>global.io</code> we used in the <code>WebSockets</code> class inside the <code>subscribeOtherUser</code> method.</p>
<p>If you got lost here is the <a target="_blank" href="https://github.com/adeelibr/node-playground/tree/master/chapter-1-chat">entire source code of this chat application</a>. Also free to drop me a message with your feedback and I will try to improve the content of this tutorial.</p>
<h2 id="heading-discussing-chat-room-amp-chat-message-database-model">Discussing chat room &amp; chat message database model</h2>
<p>Before starting off with Chat, I think it is really important to discuss the database model on which we will create our chat application. Have a look at the below video:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/GAt-XjGvMxM" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Now that you have a clear idea about what our chat structure will be like, let's start off by making our chat room model.</p>
<p>Go inside your <code>models</code> folder and create the following <code>ChatRoom.js</code>. Add the following content to it:</p>
<pre><code><span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;
<span class="hljs-keyword">import</span> { v4 <span class="hljs-keyword">as</span> uuidv4 } <span class="hljs-keyword">from</span> <span class="hljs-string">"uuid"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> CHAT_ROOM_TYPES = {
  <span class="hljs-attr">CONSUMER_TO_CONSUMER</span>: <span class="hljs-string">"consumer-to-consumer"</span>,
  <span class="hljs-attr">CONSUMER_TO_SUPPORT</span>: <span class="hljs-string">"consumer-to-support"</span>,
};

<span class="hljs-keyword">const</span> chatRoomSchema = <span class="hljs-keyword">new</span> mongoose.Schema(
  {
    <span class="hljs-attr">_id</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">default</span>: <span class="hljs-function">() =&gt;</span> uuidv4().replace(<span class="hljs-regexp">/\-/g</span>, <span class="hljs-string">""</span>),
    },
    <span class="hljs-attr">userIds</span>: <span class="hljs-built_in">Array</span>,
    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">chatInitiator</span>: <span class="hljs-built_in">String</span>,
  },
  {
    <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">collection</span>: <span class="hljs-string">"chatrooms"</span>,
  }
);

chatRoomSchema.statics.initiateChat = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">
    userIds, type, chatInitiator
</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> availableRoom = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.findOne({
      <span class="hljs-attr">userIds</span>: {
        <span class="hljs-attr">$size</span>: userIds.length,
        <span class="hljs-attr">$all</span>: [...userIds],
      },
      type,
    });
    <span class="hljs-keyword">if</span> (availableRoom) {
      <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">isNew</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-attr">message</span>: <span class="hljs-string">'retrieving an old chat room'</span>,
        <span class="hljs-attr">chatRoomId</span>: availableRoom._doc._id,
        <span class="hljs-attr">type</span>: availableRoom._doc.type,
      };
    }

    <span class="hljs-keyword">const</span> newRoom = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.create({ userIds, type, chatInitiator });
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">isNew</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">message</span>: <span class="hljs-string">'creating a new chatroom'</span>,
      <span class="hljs-attr">chatRoomId</span>: newRoom._doc._id,
      <span class="hljs-attr">type</span>: newRoom._doc.type,
    };
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'error on start chat method'</span>, error);
    <span class="hljs-keyword">throw</span> error;
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> mongoose.model(<span class="hljs-string">"ChatRoom"</span>, chatRoomSchema);
</code></pre><p>We have three things going on here:</p>
<ul>
<li>We have a const for <code>CHAT_ROOM_TYPES</code> which has only two types</li>
<li>We define our ChatRoom schema</li>
<li>We add a static method to initiate chat</li>
</ul>
<h2 id="heading-chat-related-apis">Chat related APIs</h2>
<h3 id="heading-initiate-a-chat-between-users-roominitiate-post-request">Initiate a chat between users (/room/initiate [POST request])</h3>
<p>Let's discuss our static method defined in <code>models/ChatRoom.js</code> called <code>initiateChat</code>:</p>
<pre><code>chatRoomSchema.statics.initiateChat = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">userIds, type, chatInitiator</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> availableRoom = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.findOne({
      <span class="hljs-attr">userIds</span>: {
        <span class="hljs-attr">$size</span>: userIds.length,
        <span class="hljs-attr">$all</span>: [...userIds],
      },
      type,
    });
    <span class="hljs-keyword">if</span> (availableRoom) {
      <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">isNew</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-attr">message</span>: <span class="hljs-string">'retrieving an old chat room'</span>,
        <span class="hljs-attr">chatRoomId</span>: availableRoom._doc._id,
        <span class="hljs-attr">type</span>: availableRoom._doc.type,
      };
    }

    <span class="hljs-keyword">const</span> newRoom = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.create({ userIds, type, chatInitiator });
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">isNew</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">message</span>: <span class="hljs-string">'creating a new chatroom'</span>,
      <span class="hljs-attr">chatRoomId</span>: newRoom._doc._id,
      <span class="hljs-attr">type</span>: newRoom._doc.type,
    };
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'error on start chat method'</span>, error);
    <span class="hljs-keyword">throw</span> error;
  }
}
</code></pre><p>This function takes in three parameters:</p>
<ul>
<li>userIds (array of users)</li>
<li>type (type of chatroom)</li>
<li>chatInitiator (the user who created the chat room)</li>
</ul>
<p>Next we are doing two things here: either returning an existing chatroom document or creating a new one. </p>
<p>Let's break this one down:</p>
<pre><code><span class="hljs-keyword">const</span> availableRoom = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.findOne({
  <span class="hljs-attr">userIds</span>: {
    <span class="hljs-attr">$size</span>: userIds.length,
    <span class="hljs-attr">$all</span>: [...userIds],
  },
  type,
});
<span class="hljs-keyword">if</span> (availableRoom) {
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">isNew</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">message</span>: <span class="hljs-string">'retrieving an old chat room'</span>,
    <span class="hljs-attr">chatRoomId</span>: availableRoom._doc._id,
    <span class="hljs-attr">type</span>: availableRoom._doc.type,
  };
}
</code></pre><p>First using the <code>this.findOne()</code> API in mongoose, we find all the chatrooms where the following criteria is met:</p>
<pre><code>userIds: { <span class="hljs-attr">$size</span>: userIds.length, <span class="hljs-attr">$all</span>: [...userIds] },
<span class="hljs-attr">type</span>: type,
</code></pre><p>You can read more on the $size operator <a target="_blank" href="https://docs.mongodb.com/manual/reference/operator/query/size/">here</a>, and more on the $all operator <a target="_blank" href="https://docs.mongodb.com/manual/reference/operator/query/all/">here</a>.</p>
<p>We're checking to find a chatroom document where an item exists in our chatrooms collection where</p>
<ol>
<li>the <code>userIds</code> are the same as the one we are passing to this function (irrespective of the user ids order), and </li>
<li>the length of the <code>userIds</code> is the same as that my <code>userIds.length</code> that we are passing through the function.</li>
</ol>
<p>Also we're checking that the chat room type should be the same.</p>
<p>If something like this is found, we simply return the existing chatroom.</p>
<p>Otherwise we create a new chat room and return it by doing this:</p>
<pre><code><span class="hljs-keyword">const</span> newRoom = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.create({ userIds, type, chatInitiator });
<span class="hljs-keyword">return</span> {
  <span class="hljs-attr">isNew</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">message</span>: <span class="hljs-string">'creating a new chatroom'</span>,
  <span class="hljs-attr">chatRoomId</span>: newRoom._doc._id,
  <span class="hljs-attr">type</span>: newRoom._doc.type,
};
</code></pre><p>Create a new room and return the response.</p>
<p>We also have an <code>isNew</code> key where, if it's retrieving an old chatroom, we set it to <code>false</code> otherwise <code>true</code>.</p>
<p>Next for your route created in <code>routes/chatRoom.js</code> called <code>post('/initiate', chatRoom.initiate)</code> go to its appropriate controller in <code>controllers/chatRoom.js</code> and add the following in the <code>initiate</code> method:</p>
<pre><code>initiate: <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> validation = makeValidation(<span class="hljs-function"><span class="hljs-params">types</span> =&gt;</span> ({
      <span class="hljs-attr">payload</span>: req.body,
      <span class="hljs-attr">checks</span>: {
        <span class="hljs-attr">userIds</span>: { 
          <span class="hljs-attr">type</span>: types.array, 
          <span class="hljs-attr">options</span>: { <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">empty</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">stringOnly</span>: <span class="hljs-literal">true</span> } 
        },
        <span class="hljs-attr">type</span>: { <span class="hljs-attr">type</span>: types.enum, <span class="hljs-attr">options</span>: { <span class="hljs-attr">enum</span>: CHAT_ROOM_TYPES } },
      }
    }));
    <span class="hljs-keyword">if</span> (!validation.success) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ ...validation });

    <span class="hljs-keyword">const</span> { userIds, type } = req.body;
    <span class="hljs-keyword">const</span> { <span class="hljs-attr">userId</span>: chatInitiator } = req;
    <span class="hljs-keyword">const</span> allUserIds = [...userIds, chatInitiator];
    <span class="hljs-keyword">const</span> chatRoom = <span class="hljs-keyword">await</span> ChatRoomModel.initiateChat(allUserIds, type, chatInitiator);
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>, chatRoom });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">error</span>: error })
  }
},
</code></pre><p>We are using the <code>[make-validation](https://www.npmjs.com/package/@withvoid/make-validation)</code> library here to validate the user's request. For the initiate API, we expect the user to send an array of <code>users</code> and also define the type of the <code>chat-room</code> that is being created.</p>
<p>Once the validation passes, then:</p>
<pre><code><span class="hljs-keyword">const</span> { userIds, type } = req.body;
<span class="hljs-keyword">const</span> { <span class="hljs-attr">userId</span>: chatInitiator } = req;
<span class="hljs-keyword">const</span> allUserIds = [...userIds, chatInitiator];
<span class="hljs-keyword">const</span> chatRoom = <span class="hljs-keyword">await</span> ChatRoomModel.initiateChat(allUserIds, type, chatInitiator);
<span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>, chatRoom });
</code></pre><p>One thing to notice here is <code>userIds, type</code> is coming from <code>req.body</code> while <code>userId</code> that is being aliased as <code>chatInitiatorId</code> is coming from <code>req</code> thanks to our <code>decode</code> middleware.</p>
<p>If you remember, we attached <code>app.use("/room", decode, chatRoomRouter);</code> in our <code>server/index.js</code> file. This means this route <code>/room/initiate</code> is authenticated. So <code>const { userId: chatInitiator } = req;</code> is the id of the current user logged in.</p>
<p>We simply call our <code>initiateChat</code> method from <code>ChatRoomModel</code> and pass it <code>allUserIds, type, chatInitiator</code>. Whatever result comes we simply pass it to the user.</p>
<p>Let's run this and see if it works (here is a video of me doing it):</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/vWzmTrNoNJs" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h3 id="heading-create-a-message-in-chat-room-roomidmessage-post-request">Create a message in chat room (/:roomId/message) [POST request]</h3>
<p>Let's create a message for the chat room we just created with <code>pikachu</code>.</p>
<p>But before we create a message we need to create a model for our <code>chatmessages</code>. So let's do that first. In your <code>models</code> folder create a new file called <code>ChatMessage.js</code> and add the following content to it:</p>
<pre><code><span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;
<span class="hljs-keyword">import</span> { v4 <span class="hljs-keyword">as</span> uuidv4 } <span class="hljs-keyword">from</span> <span class="hljs-string">"uuid"</span>;

<span class="hljs-keyword">const</span> MESSAGE_TYPES = {
  <span class="hljs-attr">TYPE_TEXT</span>: <span class="hljs-string">"text"</span>,
};

<span class="hljs-keyword">const</span> readByRecipientSchema = <span class="hljs-keyword">new</span> mongoose.Schema(
  {
    <span class="hljs-attr">_id</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">readByUserId</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">readAt</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">Date</span>,
      <span class="hljs-attr">default</span>: <span class="hljs-built_in">Date</span>.now(),
    },
  },
  {
    <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">false</span>,
  }
);

<span class="hljs-keyword">const</span> chatMessageSchema = <span class="hljs-keyword">new</span> mongoose.Schema(
  {
    <span class="hljs-attr">_id</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">default</span>: <span class="hljs-function">() =&gt;</span> uuidv4().replace(<span class="hljs-regexp">/\-/g</span>, <span class="hljs-string">""</span>),
    },
    <span class="hljs-attr">chatRoomId</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">message</span>: mongoose.Schema.Types.Mixed,
    <span class="hljs-attr">type</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">default</span>: <span class="hljs-function">() =&gt;</span> MESSAGE_TYPES.TYPE_TEXT,
    },
    <span class="hljs-attr">postedByUser</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">readByRecipients</span>: [readByRecipientSchema],
  },
  {
    <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">collection</span>: <span class="hljs-string">"chatmessages"</span>,
  }
);

chatMessageSchema.statics.createPostInChatRoom = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">chatRoomId, message, postedByUser</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> post = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.create({
      chatRoomId,
      message,
      postedByUser,
      <span class="hljs-attr">readByRecipients</span>: { <span class="hljs-attr">readByUserId</span>: postedByUser }
    });
    <span class="hljs-keyword">const</span> aggregate = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.aggregate([
      <span class="hljs-comment">// get post where _id = post._id</span>
      { <span class="hljs-attr">$match</span>: { <span class="hljs-attr">_id</span>: post._id } },
      <span class="hljs-comment">// do a join on another table called users, and </span>
      <span class="hljs-comment">// get me a user whose _id = postedByUser</span>
      {
        <span class="hljs-attr">$lookup</span>: {
          <span class="hljs-attr">from</span>: <span class="hljs-string">'users'</span>,
          <span class="hljs-attr">localField</span>: <span class="hljs-string">'postedByUser'</span>,
          <span class="hljs-attr">foreignField</span>: <span class="hljs-string">'_id'</span>,
          <span class="hljs-attr">as</span>: <span class="hljs-string">'postedByUser'</span>,
        }
      },
      { <span class="hljs-attr">$unwind</span>: <span class="hljs-string">'$postedByUser'</span> },
      <span class="hljs-comment">// do a join on another table called chatrooms, and </span>
      <span class="hljs-comment">// get me a chatroom whose _id = chatRoomId</span>
      {
        <span class="hljs-attr">$lookup</span>: {
          <span class="hljs-attr">from</span>: <span class="hljs-string">'chatrooms'</span>,
          <span class="hljs-attr">localField</span>: <span class="hljs-string">'chatRoomId'</span>,
          <span class="hljs-attr">foreignField</span>: <span class="hljs-string">'_id'</span>,
          <span class="hljs-attr">as</span>: <span class="hljs-string">'chatRoomInfo'</span>,
        }
      },
      { <span class="hljs-attr">$unwind</span>: <span class="hljs-string">'$chatRoomInfo'</span> },
      { <span class="hljs-attr">$unwind</span>: <span class="hljs-string">'$chatRoomInfo.userIds'</span> },
      <span class="hljs-comment">// do a join on another table called users, and </span>
      <span class="hljs-comment">// get me a user whose _id = userIds</span>
      {
        <span class="hljs-attr">$lookup</span>: {
          <span class="hljs-attr">from</span>: <span class="hljs-string">'users'</span>,
          <span class="hljs-attr">localField</span>: <span class="hljs-string">'chatRoomInfo.userIds'</span>,
          <span class="hljs-attr">foreignField</span>: <span class="hljs-string">'_id'</span>,
          <span class="hljs-attr">as</span>: <span class="hljs-string">'chatRoomInfo.userProfile'</span>,
        }
      },
      { <span class="hljs-attr">$unwind</span>: <span class="hljs-string">'$chatRoomInfo.userProfile'</span> },
      <span class="hljs-comment">// group data</span>
      {
        <span class="hljs-attr">$group</span>: {
          <span class="hljs-attr">_id</span>: <span class="hljs-string">'$chatRoomInfo._id'</span>,
          <span class="hljs-attr">postId</span>: { <span class="hljs-attr">$last</span>: <span class="hljs-string">'$_id'</span> },
          <span class="hljs-attr">chatRoomId</span>: { <span class="hljs-attr">$last</span>: <span class="hljs-string">'$chatRoomInfo._id'</span> },
          <span class="hljs-attr">message</span>: { <span class="hljs-attr">$last</span>: <span class="hljs-string">'$message'</span> },
          <span class="hljs-attr">type</span>: { <span class="hljs-attr">$last</span>: <span class="hljs-string">'$type'</span> },
          <span class="hljs-attr">postedByUser</span>: { <span class="hljs-attr">$last</span>: <span class="hljs-string">'$postedByUser'</span> },
          <span class="hljs-attr">readByRecipients</span>: { <span class="hljs-attr">$last</span>: <span class="hljs-string">'$readByRecipients'</span> },
          <span class="hljs-attr">chatRoomInfo</span>: { <span class="hljs-attr">$addToSet</span>: <span class="hljs-string">'$chatRoomInfo.userProfile'</span> },
          <span class="hljs-attr">createdAt</span>: { <span class="hljs-attr">$last</span>: <span class="hljs-string">'$createdAt'</span> },
          <span class="hljs-attr">updatedAt</span>: { <span class="hljs-attr">$last</span>: <span class="hljs-string">'$updatedAt'</span> },
        }
      }
    ]);
    <span class="hljs-keyword">return</span> aggregate[<span class="hljs-number">0</span>];
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">throw</span> error;
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> mongoose.model(<span class="hljs-string">"ChatMessage"</span>, chatMessageSchema);
</code></pre><p>There are a couple of things happening here:</p>
<ul>
<li>We have a <code>MESSAGE_TYPES</code> object which has only one type called <code>text</code></li>
<li>We are defining our schema for <code>chatmessage</code> and <code>readByRecipient</code></li>
<li>Then we are writing our static method for <code>createPostInChatRoom</code></li>
</ul>
<p>I know this is a lot of content, but just bear with me. Let's just write the controller for the route that creates this message.</p>
<p>For the route defined in our <code>routes/chatRoom.js</code> API called <code>.post('/:roomId/message', chatRoom.postMessage)</code> let's go to its controller in <code>controllers/chatRoom.js</code> and define it:</p>
<pre><code>postMessage: <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { roomId } = req.params;
    <span class="hljs-keyword">const</span> validation = makeValidation(<span class="hljs-function"><span class="hljs-params">types</span> =&gt;</span> ({
      <span class="hljs-attr">payload</span>: req.body,
      <span class="hljs-attr">checks</span>: {
        <span class="hljs-attr">messageText</span>: { <span class="hljs-attr">type</span>: types.string },
      }
    }));
    <span class="hljs-keyword">if</span> (!validation.success) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ ...validation });

    <span class="hljs-keyword">const</span> messagePayload = {
      <span class="hljs-attr">messageText</span>: req.body.messageText,
    };
    <span class="hljs-keyword">const</span> currentLoggedUser = req.userId;
    <span class="hljs-keyword">const</span> post = <span class="hljs-keyword">await</span> ChatMessageModel.createPostInChatRoom(roomId, messagePayload, currentLoggedUser);
    <span class="hljs-built_in">global</span>.io.sockets.in(roomId).emit(<span class="hljs-string">'new message'</span>, { <span class="hljs-attr">message</span>: post });
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>, post });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">error</span>: error })
  }
},
</code></pre><p>Cool, let's discuss what we are doing here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/z1C0Sl2wmJU" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Operators discussed in this video are:</p>
<ul>
<li><a target="_blank" href="https://docs.mongodb.com/manual/reference/operator/aggregation/match/">$match</a></li>
<li><a target="_blank" href="https://docs.mongodb.com/manual/reference/operator/aggregation/last/">$last</a></li>
<li><a target="_blank" href="https://docs.mongodb.com/manual/reference/operator/update/addToSet/">$addToSet</a></li>
<li><a target="_blank" href="https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/">$lookup</a></li>
<li><a target="_blank" href="https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/">$unwind</a></li>
<li><a target="_blank" href="https://docs.mongodb.com/manual/reference/operator/aggregation/group/">$group</a></li>
</ul>
<h3 id="heading-see-conversation-for-a-chat-room-by-its-id-get-request">See conversation for a chat room by it's id [Get request]</h3>
<p>Now that we have</p>
<ul>
<li>Created a chat room</li>
<li>Are able to add messages in that chat room</li>
</ul>
<p>Let's see the entire conversation for that chat as well (with pagination).</p>
<p>For your route <code>.get('/:roomId', chatRoom.getConversationByRoomId)</code> in <code>routes/chatRoom.js</code> open its controller in the file <code>controllers/chatRoom.js</code> and add the following content to the chat room:</p>
<pre><code>getConversationByRoomId: <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { roomId } = req.params;
    <span class="hljs-keyword">const</span> room = <span class="hljs-keyword">await</span> ChatRoomModel.getChatRoomByRoomId(roomId)
    <span class="hljs-keyword">if</span> (!room) {
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({
        <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-attr">message</span>: <span class="hljs-string">'No room exists for this id'</span>,
      })
    }
    <span class="hljs-keyword">const</span> users = <span class="hljs-keyword">await</span> UserModel.getUserByIds(room.userIds);
    <span class="hljs-keyword">const</span> options = {
      <span class="hljs-attr">page</span>: <span class="hljs-built_in">parseInt</span>(req.query.page) || <span class="hljs-number">0</span>,
      <span class="hljs-attr">limit</span>: <span class="hljs-built_in">parseInt</span>(req.query.limit) || <span class="hljs-number">10</span>,
    };
    <span class="hljs-keyword">const</span> conversation = <span class="hljs-keyword">await</span> ChatMessageModel.getConversationByRoomId(roomId, options);
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({
      <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
      conversation,
      users,
    });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, error });
  }
},
</code></pre><p>Next let's create a new static method in our <code>ChatRoomModel</code> file called <code>getChatRoomByRoomId</code> in <code>models/ChatRoom.js</code>:</p>
<pre><code>chatRoomSchema.statics.getChatRoomByRoomId = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">roomId</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> room = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.findOne({ <span class="hljs-attr">_id</span>: roomId });
    <span class="hljs-keyword">return</span> room;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">throw</span> error;
  }
}
</code></pre><p>Very straightforward – we are getting the room by roomId here.</p>
<p>Next in our <code>UserModel</code>, create a static method called <code>getUserByIds</code> in the file <code>models/User.js</code>:</p>
<pre><code>userSchema.statics.getUserByIds = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">ids</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> users = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.find({ <span class="hljs-attr">_id</span>: { <span class="hljs-attr">$in</span>: ids } });
    <span class="hljs-keyword">return</span> users;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">throw</span> error;
  }
}
</code></pre><p>The operator used here is <a target="_blank" href="https://docs.mongodb.com/manual/reference/operator/query/in/">$in</a> – I'll talk about this in a bit.</p>
<p>And then at last, go to your <code>ChatMessage</code> model in <code>models/ChatMessage.js</code> and write a new static method called <code>getConversationByRoomId</code>:</p>
<pre><code>chatMessageSchema.statics.getConversationByRoomId = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">chatRoomId, options = {}</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.aggregate([
      { <span class="hljs-attr">$match</span>: { chatRoomId } },
      { <span class="hljs-attr">$sort</span>: { <span class="hljs-attr">createdAt</span>: <span class="hljs-number">-1</span> } },
      <span class="hljs-comment">// do a join on another table called users, and </span>
      <span class="hljs-comment">// get me a user whose _id = postedByUser</span>
      {
        <span class="hljs-attr">$lookup</span>: {
          <span class="hljs-attr">from</span>: <span class="hljs-string">'users'</span>,
          <span class="hljs-attr">localField</span>: <span class="hljs-string">'postedByUser'</span>,
          <span class="hljs-attr">foreignField</span>: <span class="hljs-string">'_id'</span>,
          <span class="hljs-attr">as</span>: <span class="hljs-string">'postedByUser'</span>,
        }
      },
      { <span class="hljs-attr">$unwind</span>: <span class="hljs-string">"$postedByUser"</span> },
      <span class="hljs-comment">// apply pagination</span>
      { <span class="hljs-attr">$skip</span>: options.page * options.limit },
      { <span class="hljs-attr">$limit</span>: options.limit },
      { <span class="hljs-attr">$sort</span>: { <span class="hljs-attr">createdAt</span>: <span class="hljs-number">1</span> } },
    ]);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">throw</span> error;
  }
}
</code></pre><p>Let's discuss all that we have done so far:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/cnwOMrVMv0c" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p><strong><a target="_blank" href="https://github.com/adeelibr/node-playground/tree/master/chapter-1-chat">All the source code is available here</a>.</strong></p>
<h3 id="heading-mark-an-entire-conversation-as-read-feature-similar-to-whatsapp">Mark an entire conversation as read (feature similar to WhatsApp)</h3>
<p>Once the other person is logged in and they view a conversation for a room id, we need to mark that conversation as read from their side.</p>
<p>To do this, in your <code>routes/chatRoom.js</code> for the route </p>
<pre><code>put(<span class="hljs-string">'/:roomId/mark-read'</span>, chatRoom.markConversationReadByRoomId)
</code></pre><p>go to its appropriate controller in <code>controllers/chatRoom.js</code> and add the following content in the <code>markConversationReadByRoomId</code> controller.</p>
<pre><code>markConversationReadByRoomId: <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { roomId } = req.params;
    <span class="hljs-keyword">const</span> room = <span class="hljs-keyword">await</span> ChatRoomModel.getChatRoomByRoomId(roomId)
    <span class="hljs-keyword">if</span> (!room) {
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({
        <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-attr">message</span>: <span class="hljs-string">'No room exists for this id'</span>,
      })
    }

    <span class="hljs-keyword">const</span> currentLoggedUser = req.userId;
    <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> ChatMessageModel.markMessageRead(roomId, currentLoggedUser);
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">data</span>: result });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.log(error);
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>, error });
  }
},
</code></pre><p>All we are doing here is first checking if the room exists or not. If it does, we proceed further. We take in the <code>req.user.id</code> as <code>currentLoggedUser</code> and pass it to the following function:</p>
<pre><code>ChatMessageModel.markMessageRead(roomId, currentLoggedUser);
</code></pre><p>Which in our <code>ChatMessage</code> model is defined like this:</p>
<pre><code>chatMessageSchema.statics.markMessageRead = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">chatRoomId, currentUserOnlineId</span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.updateMany(
      {
        chatRoomId,
        <span class="hljs-string">'readByRecipients.readByUserId'</span>: { <span class="hljs-attr">$ne</span>: currentUserOnlineId }
      },
      {
        <span class="hljs-attr">$addToSet</span>: {
          <span class="hljs-attr">readByRecipients</span>: { <span class="hljs-attr">readByUserId</span>: currentUserOnlineId }
        }
      },
      {
        <span class="hljs-attr">multi</span>: <span class="hljs-literal">true</span>
      }
    );
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">throw</span> error;
  }
}
</code></pre><p>A possible use case is that the user might not have read the last 15 messages once they open up a specific room conversation. They should all be marked as read. So we're using the <code>this.updateMany</code> function by mongoose.</p>
<p>The query itself is defined in 2 steps:</p>
<ul>
<li>Find</li>
<li>Update</li>
</ul>
<p>And there can be multiple statements be updated.</p>
<p>To find a section, do this:</p>
<pre><code>{
  chatRoomId,
  <span class="hljs-string">'readByRecipients.readByUserId'</span>: { <span class="hljs-attr">$ne</span>: currentUserOnlineId }
},
</code></pre><p>This says I want to find all the message posts in the <code>chatmessages</code> collection where <code>chatRoomId</code> matches and <code>readByRecipients</code> array does not. The <code>userId</code> that I am passing to this function is <code>currentUserOnlineId</code>.</p>
<p>Once it has all those documents where the criteria matches, it's then time to update them:</p>
<pre><code>{
  <span class="hljs-attr">$addToSet</span>: {
    <span class="hljs-attr">readByRecipients</span>: { <span class="hljs-attr">readByUserId</span>: currentUserOnlineId }
  }
},
</code></pre><p><code>$addToSet</code> will just push a new entry to the <code>readByRecipients</code> array. This is like <code>Array.push</code> but for mongo. </p>
<p>Next we want to tell <code>mongoose</code> to not just update the first record it finds, but also to update all the records where the condition matches. So doing this:</p>
<pre><code>{
  <span class="hljs-attr">multi</span>: <span class="hljs-literal">true</span>
}
</code></pre><p>And that is all – we return the data as is.</p>
<p>Let's run this API.</p>
<p>Start up the server:</p>
<pre><code>npm start;
</code></pre><p>Open your postman and create a new <code>PUT</code> request to test this route <code>ocalhost:3000/room/&lt;room=id-here&gt;/mark-read</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/Screenshot-2020-06-16-at-23.20.53.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-bonus-section">Bonus Section</h3>
<ul>
<li>How to delete a chat room and all its related messages</li>
<li>How to delete a message by its message id</li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/GHhOIg5ZDa4" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>And we are done! Wow that was a lot of learning today.</p>
<p>You can find the source code of this tutorial <a target="_blank" href="https://github.com/adeelibr/node-playground/tree/master/chapter-1-chat">here</a>.</p>
<p>Reach out to me on twitter with your feedback – I would love to hear if you have any suggestions for improvements: <a target="_blank" href="https://twitter.com/adeelibr">twitter.com/adeelibr</a></p>
<p>If you liked to this article, please do give the <a target="_blank" href="https://github.com/adeelibr/node-playground/tree/master/chapter-1-chat">github repository</a> a star and subscribe to my <a target="_blank" href="https://www.youtube.com/channel/UCGHFI8lm4QzUzFH5nnzqkjA">youtube channel</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Multiplayer Card Game with Phaser 3, Express, and Socket.IO ]]>
                </title>
                <description>
                    <![CDATA[ By M. S. Farzan I'm a tabletop game developer, and am continually looking for ways to digitize game experiences.  In this tutorial, we're going to build a multiplayer card game using Phaser 3, Express, and Socket.IO. In terms of prerequisites, you'll... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-multiplayer-card-game-with-phaser-3-express-and-socket-io/</link>
                <guid isPermaLink="false">66d851e78da7a7c34f4c9223</guid>
                
                    <category>
                        <![CDATA[ ES6 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express JS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Game Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GameDev ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ phaser 3 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SocketIO ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 25 Mar 2020 20:57:51 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/03/Client-2-2.PNG" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By M. S. Farzan</p>
<p>I'm a <a target="_blank" href="https://www.nightpathpub.com/entromancy">tabletop game</a> developer, and am continually looking for ways to digitize game experiences.  In this tutorial, we're going to build a multiplayer card game using <a target="_blank" href="http://phaser.io/">Phaser 3</a>, <a target="_blank" href="https://expressjs.com/">Express</a>, and <a target="_blank" href="https://socket.io/">Socket.IO</a>.</p>
<p>In terms of prerequisites, you'll want to make sure that you have <a target="_blank" href="https://nodejs.org/en/">Node</a>/<a target="_blank" href="https://www.npmjs.com/">NPM</a> and <a target="_blank" href="https://github.com/">Git</a> installed and configured on your machine.  Some experience with JavaScript would be helpful, and you may want to run through the <a target="_blank" href="http://phaser.io/tutorials/making-your-first-phaser-3-game">basic Phaser tutorial</a> before tackling this one.</p>
<p>Major kudos to Scott Westover for <a target="_blank" href="https://gamedevacademy.org/create-a-basic-multiplayer-game-in-phaser-3-with-socket-io-part-1/">his tutorial on the topic</a>, Kal_Torak and the Phaser community for answering all my questions, and my good friend Mike for helping me conceptualize the architecture of this project.</p>
<p>Note: we'll be using assets and colors from my tabletop card game, <em><a target="_blank" href="https://www.nightpathpub.com/hacker-battles">Entromancy: Hacker Battles</a></em>.  If you prefer, you can use your own images (or even <a target="_blank" href="http://phaser.io/examples/v3/view/game-objects/shapes/rectangle">Phaser rectangles</a>) and colors, and you can access the entire project code on <a target="_blank" href="https://github.com/sominator/multiplayer-card-project">GitHub</a>.</p>
<p>If you'd prefer a more visual tutorial, you can also follow along with the companion video to this article:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/fEwAgKBgoJM" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>Let's get started!</p>
<h2 id="heading-the-game">The Game</h2>
<p>Our simple card game will feature a Phaser client that will handle most of the game logic and doing things like dealing cards, providing drag-and-drop functionality, and so on.</p>
<p>On the back end, we'll spin up an Express server that will utilize Socket.IO to communicate between clients and make it so that when one player plays a card, it shows up in another player's client, and vice-versa.</p>
<p>Our goal for this project is to create a basic framework for a multiplayer card game that you can build upon and adjust to suit your own game's logic.</p>
<p>First, let's tackle the client!</p>
<h2 id="heading-the-client">The Client</h2>
<p>To scaffold our client, we're going to clone the semi-official Phaser 3 Webpack Project Template on <a target="_blank" href="https://github.com/photonstorm/phaser3-project-template">GitHub</a>.</p>
<p>Open your favorite command line interface and create a new folder:</p>
<pre><code class="lang-cli">mkdir multiplayer-card-project
cd multiplayer-card-project
</code></pre>
<p>Clone the git project:</p>
<pre><code class="lang-cli">git clone https://github.com/photonstorm/phaser3-project-template.git
</code></pre>
<p>This command will download the template in a folder called "phaser3-project-template" within /multiplayer-card-project.  If you want to follow along with our tutorial's file structure, go ahead and change that template folder's name to "client."</p>
<p>Navigate into that new directory and install all dependencies:</p>
<pre><code class="lang-cli">cd client
npm install
</code></pre>
<p>Your project folder structure should look something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/File-Structure-1-4.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Before we muck with the files, let's go back to our CLI and enter the following command in the /client folder:</p>
<pre><code class="lang-cli">npm start
</code></pre>
<p>Our Phaser template utilizes Webpack to spin up a local server that in turn serves up a simple game app in our browser (usually at http://localhost:8080).  Neat!</p>
<p>Let's open our project in your favorite code editor and make some changes to fit our card game.  Delete everything in /client/src/assets and replace them with the card images from <a target="_blank" href="https://github.com/sominator/multiplayer-card-project/tree/master/client/src/assets">GitHub</a>.</p>
<p>In the /client/src directory, add a folder called "scenes" and another called "helpers."</p>
<p>In /client/src/scenes, add an empty file called "game.js".</p>
<p>In /client/src/helpers, add three empty files: "card.js", "dealer.js", and "zone.js".</p>
<p>Your project structure should now look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/File-Structure-2.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Cool!  Your client might be throwing you errors because we deleted some things, but not to worry.  Open /src/index.js, which is the main entry point to our front end app. Enter the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Phaser <span class="hljs-keyword">from</span> <span class="hljs-string">"phaser"</span>;
<span class="hljs-keyword">import</span> Game <span class="hljs-keyword">from</span> <span class="hljs-string">"./scenes/game"</span>;

<span class="hljs-keyword">const</span> config = {
    <span class="hljs-attr">type</span>: Phaser.AUTO,
    <span class="hljs-attr">parent</span>: <span class="hljs-string">"phaser-example"</span>,
    <span class="hljs-attr">width</span>: <span class="hljs-number">1280</span>,
    <span class="hljs-attr">height</span>: <span class="hljs-number">780</span>,
    <span class="hljs-attr">scene</span>: [
        Game
    ]
};

<span class="hljs-keyword">const</span> game = <span class="hljs-keyword">new</span> Phaser.Game(config);
</code></pre>
<p>All we've done here is restructure the boilerplate to utilize Phaser's "scene" system so that we can separate our game scenes rather than try to cram everything in one file.  Scenes can be useful if you're creating multiple game worlds, building things like instruction screens, or generally trying to keep things tidy.</p>
<p>Let's move to /src/scenes/game.js and write some code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Game</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Phaser</span>.<span class="hljs-title">Scene</span> </span>{
    <span class="hljs-keyword">constructor</span>() {
        <span class="hljs-built_in">super</span>({
            <span class="hljs-attr">key</span>: <span class="hljs-string">'Game'</span>
        });
    }

    preload() {
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'cyanCardFront'</span>, <span class="hljs-string">'src/assets/CyanCardFront.png'</span>);
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'cyanCardBack'</span>, <span class="hljs-string">'src/assets/CyanCardBack.png'</span>);
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'magentaCardFront'</span>, <span class="hljs-string">'src/assets/MagentaCardFront.png'</span>);
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'magentaCardBack'</span>, <span class="hljs-string">'src/assets/MagentaCardBack.png'</span>);
    }

    create() {
        <span class="hljs-built_in">this</span>.dealText = <span class="hljs-built_in">this</span>.add.text(<span class="hljs-number">75</span>, <span class="hljs-number">350</span>, [<span class="hljs-string">'DEAL CARDS'</span>]).setFontSize(<span class="hljs-number">18</span>).setFontFamily(<span class="hljs-string">'Trebuchet MS'</span>).setColor(<span class="hljs-string">'#00ffff'</span>).setInteractive();
    }

    update() {

    }
}
</code></pre>
<p>We're taking advantage of <a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-github-and-es6-features-to-create-and-structure-your-code/">ES6 classes</a> to create a new Game scene, which incorporates preload(), create() and update() functions.</p>
<p>preload() is used to...well...preload any assets that we'll be using for our game.</p>
<p>create() is run when the game starts up, and where we'll be establishing much of our user interface and game logic.</p>
<p>update() is called once per frame, and we won't be making use of it in our tutorial (but it may be useful in your own game depending on its requirements).</p>
<p>Within the create() function, we've created a bit of text that says "DEAL CARDS" and set it to be interactive:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Deal-Cards.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Very cool.  Let's create a bit of placeholder code to understand how we want this whole thing to work once it's up and running.  Add the following to your create() function:</p>
<pre><code class="lang-javascript">        <span class="hljs-keyword">let</span> self = <span class="hljs-built_in">this</span>;

        <span class="hljs-built_in">this</span>.card = <span class="hljs-built_in">this</span>.add.image(<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-string">'cyanCardFront'</span>).setScale(<span class="hljs-number">0.3</span>, <span class="hljs-number">0.3</span>).setInteractive();
        <span class="hljs-built_in">this</span>.input.setDraggable(<span class="hljs-built_in">this</span>.card);

        <span class="hljs-built_in">this</span>.dealCards = <span class="hljs-function">() =&gt;</span> {

        }

        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerdown'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealCards();
        })

        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerover'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealText.setColor(<span class="hljs-string">'#ff69b4'</span>);
        })

        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerout'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealText.setColor(<span class="hljs-string">'#00ffff'</span>);
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'drag'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dragX, dragY</span>) </span>{
            gameObject.x = dragX;
            gameObject.y = dragY;
        })
</code></pre>
<p>We've added a lot of structure, but not much has happened.  Now, when our mouse hovers over the "DEAL CARDS" text, it's highlighted in cyberpunk hot pink, and there's a random card on our screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Card.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We've placed the image at the (x, y) coordinates of (300, 300), set its scale to be a bit smaller, and made it interactive and draggable.  We've also added a little bit of logic to determine what should happen when dragged: it should follow the (x, y) coordinates of our mouse.</p>
<p>We've also created an empty dealCards() function that will be called when we click on our "DEAL CARDS" text.  Additionally, we've saved "this" - meaning the scene in which we're currently working - into a variable called "self" so that we can use it throughout our functions without worrying about scope.</p>
<p>Our Game scene is going to get messy fast if we don't start moving things around, so let's delete the code block that begins with "this.card" and move to /src/helpers/card.js to write:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Card</span> </span>{
    <span class="hljs-keyword">constructor</span>(scene) {
        <span class="hljs-built_in">this</span>.render = <span class="hljs-function">(<span class="hljs-params">x, y, sprite</span>) =&gt;</span> {
            <span class="hljs-keyword">let</span> card = scene.add.image(x, y, sprite).setScale(<span class="hljs-number">0.3</span>, <span class="hljs-number">0.3</span>).setInteractive();
            scene.input.setDraggable(card);
            <span class="hljs-keyword">return</span> card;
        }
    }
}
</code></pre>
<p>We've created a new class that accepts a scene as a parameter, and features a render() function that accepts (x, y) coordinates and a sprite.  Now, we can call this function from elsewhere and pass it the necessary parameters to create cards.</p>
<p>Let's import the card at the top of our Game scene:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Card <span class="hljs-keyword">from</span> <span class="hljs-string">'../helpers/card'</span>;
</code></pre>
<p> And enter the following code within our empty dealCards() function:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.dealCards = <span class="hljs-function">() =&gt;</span> {
            <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++) {
                <span class="hljs-keyword">let</span> playerCard = <span class="hljs-keyword">new</span> Card(<span class="hljs-built_in">this</span>);
                playerCard.render(<span class="hljs-number">475</span> + (i * <span class="hljs-number">100</span>), <span class="hljs-number">650</span>, <span class="hljs-string">'cyanCardFront'</span>);
            }
        }
</code></pre>
<p>When we click on the "DEAL CARDS" button, we now iterate through a for loop that creates cards and renders them sequentially on screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Cards.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>NICE.  We can drag those cards around the screen, but it might be nice to limit where they can be dropped to support our game logic.</p>
<p>Let's move over to /src/helpers/zone.js and add a new class:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Zone</span> </span>{
    <span class="hljs-keyword">constructor</span>(scene) {
        <span class="hljs-built_in">this</span>.renderZone = <span class="hljs-function">() =&gt;</span> {
            <span class="hljs-keyword">let</span> dropZone = scene.add.zone(<span class="hljs-number">700</span>, <span class="hljs-number">375</span>, <span class="hljs-number">900</span>, <span class="hljs-number">250</span>).setRectangleDropZone(<span class="hljs-number">900</span>, <span class="hljs-number">250</span>);
            dropZone.setData({ <span class="hljs-attr">cards</span>: <span class="hljs-number">0</span> });
            <span class="hljs-keyword">return</span> dropZone;
        };
        <span class="hljs-built_in">this</span>.renderOutline = <span class="hljs-function">(<span class="hljs-params">dropZone</span>) =&gt;</span> {
            <span class="hljs-keyword">let</span> dropZoneOutline = scene.add.graphics();
            dropZoneOutline.lineStyle(<span class="hljs-number">4</span>, <span class="hljs-number">0xff69b4</span>);
            dropZoneOutline.strokeRect(dropZone.x - dropZone.input.hitArea.width / <span class="hljs-number">2</span>, dropZone.y - dropZone.input.hitArea.height / <span class="hljs-number">2</span>, dropZone.input.hitArea.width, dropZone.input.hitArea.height)
        }
    }
}
</code></pre>
<p>Phaser has built-in dropzones that allow us to dictate where game objects can be dropped, and we've set up one here and provided it with an outline.  We've also added a tiny bit of data called "cards" to the dropzone that we'll use later.</p>
<p>Let's import our new zone into the Game scene:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Zone <span class="hljs-keyword">from</span> <span class="hljs-string">'../helpers/zone'</span>;
</code></pre>
<p> And call it in within the create() function:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.zone = <span class="hljs-keyword">new</span> Zone(<span class="hljs-built_in">this</span>);
        <span class="hljs-built_in">this</span>.dropZone = <span class="hljs-built_in">this</span>.zone.renderZone();
        <span class="hljs-built_in">this</span>.outline = <span class="hljs-built_in">this</span>.zone.renderOutline(<span class="hljs-built_in">this</span>.dropZone);
</code></pre>
<p>Not too shabby!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Zone.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We need to add a bit of logic to determine how cards should be dropped into the zone.  Let's do that below the "this.input.on('drag')" function:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'dragstart'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject</span>) </span>{
            gameObject.setTint(<span class="hljs-number">0xff69b4</span>);
            self.children.bringToTop(gameObject);
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'dragend'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dropped</span>) </span>{
            gameObject.setTint();
            <span class="hljs-keyword">if</span> (!dropped) {
                gameObject.x = gameObject.input.dragStartX;
                gameObject.y = gameObject.input.dragStartY;
            }
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'drop'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dropZone</span>) </span>{
            dropZone.data.values.cards++;
            gameObject.x = (dropZone.x - <span class="hljs-number">350</span>) + (dropZone.data.values.cards * <span class="hljs-number">50</span>);
            gameObject.y = dropZone.y;
            gameObject.disableInteractive();
        })
</code></pre>
<p>Starting at the bottom of the code, when a card is dropped, we increment the "cards" data value on the dropzone, and assign the (x, y) coordinates of the card to the dropzone based on how many cards are already on it.  We also disable interactivity on cards after they're dropped so that they can't be retracted:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Zone-Dropped.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We've also made it so that our cards have a different tint when dragged, and if they're not dropped over the dropzone, they'll return to their starting positions.</p>
<p>Although our client isn't quite complete, we've done as much as we can before implementing the back end.  We can now deal cards, drag them around the screen, and drop them in a dropzone. But to move forward, we'll need to set up a server than can coordinate our multiplayer functionality.</p>
<h2 id="heading-the-server">The Server</h2>
<p>Let's open up a new command line at our root directory (above /client) and type:</p>
<pre><code class="lang-cli">npm init
npm install --save express socket.io nodemon
</code></pre>
<p>We've initialized a new package.json and installed Express, Socket.IO, and <a target="_blank" href="https://nodemon.io/">Nodemon</a> (which will watch our server and restart it upon changes).</p>
<p>In our code editor, let's change the "scripts" section of our package.json to say:</p>
<pre><code class="lang-javascript">  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"nodemon server.js"</span>
  },
</code></pre>
<p>Excellent.  We're ready to put our server together!  Create an empty file called "server.js" in our root directory and enter the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> server = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>)();
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>).createServer(server);
<span class="hljs-keyword">const</span> io = <span class="hljs-built_in">require</span>(<span class="hljs-string">'socket.io'</span>)(http);

io.on(<span class="hljs-string">'connection'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">socket</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A user connected: '</span> + socket.id);

    socket.on(<span class="hljs-string">'disconnect'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A user disconnected: '</span> + socket.id);
    });
});

http.listen(<span class="hljs-number">3000</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server started!'</span>);
});
</code></pre>
<p>We're importing Express and Socket.IO, asking for the server to listen on port 3000. When a client connects to or disconnects from that port, we'll log the event to the console with the client's socket id.</p>
<p>Open a new command line interface and start the server:</p>
<pre><code class="lang-cli">npm run start
</code></pre>
<p>Our server should now be running on localhost:3000, and Nodemon will watch our back end files for any changes.  Not much else will happen except for the console log that the "Server started!"</p>
<p>In our other open command line interface, let's navigate back to our /client directory and install the client version of Socket.IO:</p>
<pre><code class="lang-cli">cd client
npm install --save socket.io-client
</code></pre>
<p>We can now import it in our Game scene:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> io <span class="hljs-keyword">from</span> <span class="hljs-string">'socket.io-client'</span>;
</code></pre>
<p>Great!  We've just about wired up our front and back ends.  All we need to do is write some code in the create() function:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.socket = io(<span class="hljs-string">'http://localhost:3000'</span>);

        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'connect'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Connected!'</span>);
        });
</code></pre>
<p>We're initializing a new "socket" variable that points to our local port 3000 and logs to the browser console upon connection.</p>
<p>Open and close a couple of browsers at http://localhost:8080 (where our Phaser client is being served) and you should see the following in your command line interface:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Console.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>YAY.  Let's start adding logic to our server.js file that will serve the needs of our card game.  Replace the existing code with the following:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> server = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>)();
<span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>).createServer(server);
<span class="hljs-keyword">const</span> io = <span class="hljs-built_in">require</span>(<span class="hljs-string">'socket.io'</span>)(http);
<span class="hljs-keyword">let</span> players = [];

io.on(<span class="hljs-string">'connection'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">socket</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A user connected: '</span> + socket.id);

    players.push(socket.id);

    <span class="hljs-keyword">if</span> (players.length === <span class="hljs-number">1</span>) {
        io.emit(<span class="hljs-string">'isPlayerA'</span>);
    };

    socket.on(<span class="hljs-string">'dealCards'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        io.emit(<span class="hljs-string">'dealCards'</span>);
    });

    socket.on(<span class="hljs-string">'cardPlayed'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">gameObject, isPlayerA</span>) </span>{
        io.emit(<span class="hljs-string">'cardPlayed'</span>, gameObject, isPlayerA);
    });

    socket.on(<span class="hljs-string">'disconnect'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'A user disconnected: '</span> + socket.id);
        players = players.filter(<span class="hljs-function"><span class="hljs-params">player</span> =&gt;</span> player !== socket.id);
    });
});

http.listen(<span class="hljs-number">3000</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server started!'</span>);
});
</code></pre>
<p>We've initialized an empty array called "players" and add a socket id to it every time a client connects to the server, while also deleting the socket id upon disconnection.</p>
<p>If a client is the first to connect to the server, we ask Socket.IO to "<a target="_blank" href="https://socket.io/get-started/chat/#Emitting-events">emit</a>" an event that they're going to be Player A.  Subsequently, when the server receives an event called "dealCards" or "cardPlayed", it should emit back to the clients that they should update accordingly.</p>
<p>Believe it or not, that's all the code we need to get our server working!  Let's turn our attention back to the Game scene.  Right at the top of the create() function, type the following:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.isPlayerA = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.opponentCards = [];
</code></pre>
<p>Under the code block that starts with "this.socket.on(connect)", write:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'isPlayerA'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.isPlayerA = <span class="hljs-literal">true</span>;
        })
</code></pre>
<p>Now, if our client is the first to connect to the server, the server will emit an event that tells the client that it will be Player A.  The client socket receives that event and turns our "isPlayerA" boolean from false to true.</p>
<p>Note: from this point forward, you may need to reload your browser page (set to http://localhost:8080), rather than having Webpack do it automatically for you, for the client to correctly disconnect from and reconnect to the server.</p>
<p>We need to reconfigure our dealCards() logic to support the multiplayer aspect of our game, given that we want the client to deal us a certain set of cards that may be different from our opponent's.  Additionally, we want to render the backs of our opponent's cards on our screen, and vice versa.</p>
<p>We'll move to the empty /src/helpers/dealer.js file, import card.js, and create a new class:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Card <span class="hljs-keyword">from</span> <span class="hljs-string">'./card'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dealer</span> </span>{
    <span class="hljs-keyword">constructor</span>(scene) {
        <span class="hljs-built_in">this</span>.dealCards = <span class="hljs-function">() =&gt;</span> {
            <span class="hljs-keyword">let</span> playerSprite;
            <span class="hljs-keyword">let</span> opponentSprite;
            <span class="hljs-keyword">if</span> (scene.isPlayerA) {
                playerSprite = <span class="hljs-string">'cyanCardFront'</span>;
                opponentSprite = <span class="hljs-string">'magentaCardBack'</span>;
            } <span class="hljs-keyword">else</span> {
                playerSprite = <span class="hljs-string">'magentaCardFront'</span>;
                opponentSprite = <span class="hljs-string">'cyanCardBack'</span>;
            };
            <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++) {
                <span class="hljs-keyword">let</span> playerCard = <span class="hljs-keyword">new</span> Card(scene);
                playerCard.render(<span class="hljs-number">475</span> + (i * <span class="hljs-number">100</span>), <span class="hljs-number">650</span>, playerSprite);

                <span class="hljs-keyword">let</span> opponentCard = <span class="hljs-keyword">new</span> Card(scene);
                scene.opponentCards.push(opponentCard.render(<span class="hljs-number">475</span> + (i * <span class="hljs-number">100</span>), <span class="hljs-number">125</span>, opponentSprite).disableInteractive());
            }
        }
    }
}
</code></pre>
<p>With this new class, we're checking whether the client is Player A, and determining what sprites should be used in either case.</p>
<p>Then, we deal cards to our client, while rendering the backs of our opponent's cards at the top the screen and adding them to the opponentCards array that we initialized in our Game scene.</p>
<p>In /src/scenes/game.js, import the Dealer:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Dealer <span class="hljs-keyword">from</span> <span class="hljs-string">'../helpers/dealer'</span>;
</code></pre>
<p>Then replace our dealCards() function with:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.dealer = <span class="hljs-keyword">new</span> Dealer(<span class="hljs-built_in">this</span>);
</code></pre>
<p>Under code block that begins with "this.socket.on('isPlayerA')", add the following:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'dealCards'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealer.dealCards();
            self.dealText.disableInteractive();
        })
</code></pre>
<p>We also need to update our dealText function to match these changes:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerdown'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.socket.emit(<span class="hljs-string">"dealCards"</span>);
        })
</code></pre>
<p>Phew!  We've created a new Dealer class that will handle dealing cards to us and rendering our opponent's cards to the screen.  When the client socket receives the "dealcards" event from the server, it will call the dealCards() function from this new class, and disable the dealText so that we can't just keep generating cards for no reason.</p>
<p>Finally, we've changed the dealText functionality so that when it's pressed, the client emits an event to the server that we want to deal cards, which ties everything together.</p>
<p>Fire up two separate browsers pointed to http://localhost:8080 and hit "DEAL CARDS" on one of them.  You should see different sprites on either screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Client-1.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Client-2.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Note again that if you're having issues with this step, you may have to close one of your browsers and reload the first one to ensure that both clients have disconnected from the server, which should be logged to your command line console.</p>
<p>We still need to figure out how to render our dropped cards in our opponent's client, and vice-versa.  We can do all of that in our game scene!  Update the code block that begins with "this.input.on('drop')" with one line at the end:</p>
<pre><code class="lang-javascript">        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'drop'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dropZone</span>) </span>{
            dropZone.data.values.cards++;
            gameObject.x = (dropZone.x - <span class="hljs-number">350</span>) + (dropZone.data.values.cards * <span class="hljs-number">50</span>);
            gameObject.y = dropZone.y;
            gameObject.disableInteractive();
            self.socket.emit(<span class="hljs-string">'cardPlayed'</span>, gameObject, self.isPlayerA);
        })
</code></pre>
<p>When a card is dropped in our client, the socket will emit an event called "cardPlayed", passing the details of the game object and the client's isPlayerA boolean (which could be true or false, depending on whether the client was the first to connect to the server).</p>
<p>Recall that, in our server code, Socket.IO simply receives the "cardPlayed" event and emits the same event back up to all of the clients, passing the same information about the game object and isPlayerA from the client that initiated the event<em>.</em></p>
<p>Let's write what should happen when a client receives a "cardPlayed" event from the server, below the "this.socket.on('dealCards')" code block:</p>
<pre><code class="lang-javascript">         <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'cardPlayed'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">gameObject, isPlayerA</span>) </span>{
            <span class="hljs-keyword">if</span> (isPlayerA !== self.isPlayerA) {
                <span class="hljs-keyword">let</span> sprite = gameObject.textureKey;
                self.opponentCards.shift().destroy();
                self.dropZone.data.values.cards++;
                <span class="hljs-keyword">let</span> card = <span class="hljs-keyword">new</span> Card(self);
                card.render(((self.dropZone.x - <span class="hljs-number">350</span>) + (self.dropZone.data.values.cards * <span class="hljs-number">50</span>)), (self.dropZone.y), sprite).disableInteractive();
            }
        })
</code></pre>
<p>The code block first compares the isPlayerA boolean it receives from the server against the client's own isPlayerA, which is a check to determine whether the client that is receiving the event is the same one that generated it.</p>
<p>Let's think that through a bit further, as it exposes a key component to how our client - server relationship works, using Socket.IO as the connector.</p>
<p>Suppose that Client A connects to the server first, and is told through the "isPlayerA" event that it should change its isPlayerA boolean to <strong>true</strong>.  That's going to determine what kind of cards it generates when a user clicks "DEAL CARDS" through that client.</p>
<p>If Client B connects to the server second, it's never told to alter its isPlayerA boolean, which stays <strong>false</strong>.  That will also determine what kind of cards it generates.</p>
<p>When Client A drops a card, it emits a "cardPlayed" event to the server, passing information about the card that was dropped, and its isPlayerA boolean, which is <strong>true</strong>.  The server then relays all that information back up to all clients with its own "cardPlayed" event.</p>
<p>Client A receives that event from the server, and notes that the isPlayerA boolean from the server is <strong>true</strong>, which means that the event was generated by Client A itself. Nothing special happens.</p>
<p>Client B receives the same event from the server, and notes that the isPlayerA boolean from the server is <strong>true</strong>, although Client B's own isPlayerA is <strong>false</strong>.  Because of this difference, it executes the rest of the code block.  </p>
<p>The ensuing code stores the "texturekey" - basically, the image - of the game object that it receives from the server into a variable called "sprite". It destroys one of the opponent card backs that are rendered at the top of the screen, and increments the "cards" data value in the dropzone so that we can keep placing cards from left to right.  </p>
<p>The code then generates a new card in the dropzone that uses the sprite variable to create the same card that was dropped in the other client (if you had data attached to that game object, you could use a similar approach to attach it here as well).</p>
<p>Your final /src/scenes/game.js code should look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> io <span class="hljs-keyword">from</span> <span class="hljs-string">'socket.io-client'</span>;
<span class="hljs-keyword">import</span> Card <span class="hljs-keyword">from</span> <span class="hljs-string">'../helpers/card'</span>;
<span class="hljs-keyword">import</span> Dealer <span class="hljs-keyword">from</span> <span class="hljs-string">"../helpers/dealer"</span>;
<span class="hljs-keyword">import</span> Zone <span class="hljs-keyword">from</span> <span class="hljs-string">'../helpers/zone'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Game</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Phaser</span>.<span class="hljs-title">Scene</span> </span>{
    <span class="hljs-keyword">constructor</span>() {
        <span class="hljs-built_in">super</span>({
            <span class="hljs-attr">key</span>: <span class="hljs-string">'Game'</span>
        });
    }

    preload() {
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'cyanCardFront'</span>, <span class="hljs-string">'src/assets/CyanCardFront.png'</span>);
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'cyanCardBack'</span>, <span class="hljs-string">'src/assets/CyanCardBack.png'</span>);
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'magentaCardFront'</span>, <span class="hljs-string">'src/assets/magentaCardFront.png'</span>);
        <span class="hljs-built_in">this</span>.load.image(<span class="hljs-string">'magentaCardBack'</span>, <span class="hljs-string">'src/assets/magentaCardBack.png'</span>);
    }

    create() {
        <span class="hljs-built_in">this</span>.isPlayerA = <span class="hljs-literal">false</span>;
        <span class="hljs-built_in">this</span>.opponentCards = [];

        <span class="hljs-built_in">this</span>.zone = <span class="hljs-keyword">new</span> Zone(<span class="hljs-built_in">this</span>);
        <span class="hljs-built_in">this</span>.dropZone = <span class="hljs-built_in">this</span>.zone.renderZone();
        <span class="hljs-built_in">this</span>.outline = <span class="hljs-built_in">this</span>.zone.renderOutline(<span class="hljs-built_in">this</span>.dropZone);

        <span class="hljs-built_in">this</span>.dealer = <span class="hljs-keyword">new</span> Dealer(<span class="hljs-built_in">this</span>);

        <span class="hljs-keyword">let</span> self = <span class="hljs-built_in">this</span>;

        <span class="hljs-built_in">this</span>.socket = io(<span class="hljs-string">'http://localhost:3000'</span>);

        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'connect'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Connected!'</span>);
        });

        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'isPlayerA'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.isPlayerA = <span class="hljs-literal">true</span>;
        })

        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'dealCards'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealer.dealCards();
            self.dealText.disableInteractive();
        })

        <span class="hljs-built_in">this</span>.socket.on(<span class="hljs-string">'cardPlayed'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">gameObject, isPlayerA</span>) </span>{
            <span class="hljs-keyword">if</span> (isPlayerA !== self.isPlayerA) {
                <span class="hljs-keyword">let</span> sprite = gameObject.textureKey;
                self.opponentCards.shift().destroy();
                self.dropZone.data.values.cards++;
                <span class="hljs-keyword">let</span> card = <span class="hljs-keyword">new</span> Card(self);
                card.render(((self.dropZone.x - <span class="hljs-number">350</span>) + (self.dropZone.data.values.cards * <span class="hljs-number">50</span>)), (self.dropZone.y), sprite).disableInteractive();
            }
        })

        <span class="hljs-built_in">this</span>.dealText = <span class="hljs-built_in">this</span>.add.text(<span class="hljs-number">75</span>, <span class="hljs-number">350</span>, [<span class="hljs-string">'DEAL CARDS'</span>]).setFontSize(<span class="hljs-number">18</span>).setFontFamily(<span class="hljs-string">'Trebuchet MS'</span>).setColor(<span class="hljs-string">'#00ffff'</span>).setInteractive();

        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerdown'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.socket.emit(<span class="hljs-string">"dealCards"</span>);
        })

        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerover'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealText.setColor(<span class="hljs-string">'#ff69b4'</span>);
        })

        <span class="hljs-built_in">this</span>.dealText.on(<span class="hljs-string">'pointerout'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
            self.dealText.setColor(<span class="hljs-string">'#00ffff'</span>);
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'drag'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dragX, dragY</span>) </span>{
            gameObject.x = dragX;
            gameObject.y = dragY;
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'dragstart'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject</span>) </span>{
            gameObject.setTint(<span class="hljs-number">0xff69b4</span>);
            self.children.bringToTop(gameObject);
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'dragend'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dropped</span>) </span>{
            gameObject.setTint();
            <span class="hljs-keyword">if</span> (!dropped) {
                gameObject.x = gameObject.input.dragStartX;
                gameObject.y = gameObject.input.dragStartY;
            }
        })

        <span class="hljs-built_in">this</span>.input.on(<span class="hljs-string">'drop'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">pointer, gameObject, dropZone</span>) </span>{
            dropZone.data.values.cards++;
            gameObject.x = (dropZone.x - <span class="hljs-number">350</span>) + (dropZone.data.values.cards * <span class="hljs-number">50</span>);
            gameObject.y = dropZone.y;
            gameObject.disableInteractive();
            self.socket.emit(<span class="hljs-string">'cardPlayed'</span>, gameObject, self.isPlayerA);
        })
    }

    update() {

    }
}
</code></pre>
<p>Save everything, open two browsers, and hit "DEAL CARDS".  When you drag and drop a card in one client, it should appear in the dropzone of the other, while also deleting a card back, signifying that a card has been played:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Card-Played-1.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Card-Played-2.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>That's it!  You should now have a functional template for your multiplayer card game, which you can use to add your own cards, art, and game logic.</p>
<p>One first step could be to add to your Dealer class by making it shuffle an array of cards and return a random one (hint: check out <a target="_blank" href="https://photonstorm.github.io/phaser3-docs/Phaser.Math.RandomDataGenerator.html#shuffle__anchor">Phaser.Math.RND.shuffle([array])</a>).</p>
<p>Happy coding!</p>
<p>If you enjoyed this article, please consider <a target="_blank" href="https://www.nightpathpub.com/">checking out my games and books</a>, <a target="_blank" href="https://www.youtube.com/msfarzan?sub_confirmation=1">subscribing to my YouTube channel</a>, or <a target="_blank" href="https://discord.gg/RF6k3nB">joining the <em>Entromancy</em> Discord</a>.</p>
<p>M. S. Farzan, Ph.D. has written and worked for high-profile video game companies and editorial websites such as Electronic Arts, Perfect World Entertainment, Modus Games, and MMORPG.com, and has served as the Community Manager for games like <em>Dungeons &amp; Dragons Neverwinter</em> and <em>Mass Effect: Andromeda</em>. He is the Creative Director and Lead Game Designer of <em><a target="_blank" href="https://www.nightpathpub.com/rpg">Entromancy: A Cyberpunk Fantasy RPG</a></em> and author of <em><a target="_blank" href="http://nightpathpub.com/books">The Nightpath Trilogy</a></em>. Find M. S. Farzan on Twitter <a target="_blank" href="https://twitter.com/sominator">@sominator</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Full Stack RPG Character Generator with MongoDB, Express, Vue, and Node (the MEVN Stack) ]]>
                </title>
                <description>
                    <![CDATA[ By M. S. Farzan I'm a tabletop game developer, and enjoy making apps that have the potential to perform some service related to gaming. In this article, we'll walk through the steps to create a roleplaying game character generator using MongoDB, Expr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-full-stack-mevn-app/</link>
                <guid isPermaLink="false">66d851dfe0db794d56c01bf3</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Back end development  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ full stack ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mongoose ]]>
                    </category>
                
                    <category>
                        <![CDATA[ node ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ REST ]]>
                    </category>
                
                    <category>
                        <![CDATA[ REST API ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vue ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 09 Mar 2020 18:50:41 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9c3a740569d1a4ca30ca.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By M. S. Farzan</p>
<p>I'm a <a target="_blank" href="https://www.nightpathpub.com/">tabletop game</a> developer, and enjoy making apps that have the potential to perform some service related to gaming. In this article, we'll walk through the steps to create a roleplaying game character generator using <a target="_blank" href="https://www.mongodb.com/">MongoDB</a>, <a target="_blank" href="https://expressjs.com/">Express</a>, <a target="_blank" href="http://vuejs.org/">Vue</a>, and <a target="_blank" href="https://nodejs.org/en/">Node</a> (also known as the "MEVN" stack). </p>
<p>Prerequisites: this tutorial presumes that you have Node/<a target="_blank" href="https://www.npmjs.com/">NPM</a> and MongoDB installed and configured, with a code editor and <a target="_blank" href="https://en.wikipedia.org/wiki/Command-line_interface">CLI</a> (or <a target="_blank" href="https://www.freecodecamp.org/news/how-to-set-up-an-integrated-development-environment-ide/">IDE</a>) ready to go.</p>
<p>If you'd prefer to follow along with a visual tutorial, you can check out the companion video to this article below:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/i5XUgda08qk" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>I should also mention that this tutorial would not have been possible without Bennett Dungan's article on <a target="_blank" href="https://dev.to/beznet/build-a-rest-api-with-node-express-mongodb-4ho4">building a REST API</a>, Aneeta Sharma's tutorial on <a target="_blank" href="https://medium.com/@anaida07/mevn-stack-application-part-1-3a27b61dcae0">full stack MEVN web apps</a>, and Matt Maribojoc's article on <a target="_blank" href="https://medium.com/@mattmaribojoc/creating-a-todo-app-with-a-mevn-full-stack-part-1-da0f4df7e15">the same topic</a>.  </p>
<p>I used each of these articles in addition to official documentation (for <a target="_blank" href="https://vuejs.org/v2/guide/">Vue</a>, <a target="_blank" href="https://expressjs.com/en/starter/installing.html">Express</a>, and a whole lot more) in learning to create my own MEVN apps (you can read more about my journey with web APIs <a target="_blank" href="https://www.freecodecamp.org/news/i-built-a-web-api-with-express-flask-aspnet/">here</a>). </p>
<p>You can access the entire repository for this tutorial on <a target="_blank" href="https://github.com/sominator/mevn-character-generator">GitHub</a>.</p>
<h2 id="heading-the-front-end">The Front End</h2>
<p>Our app is going to allow us to create new roleplaying game characters and view them altogether, with the following stack:</p>
<ul>
    <li>Vue Client</li>
    <li>Node/Express Server</li>
    <li>MongoDB Database</li>
</ul>

<p>The Vue Client will make <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods">HTTP requests</a> to the Node/Express Server (or "<a target="_blank" href="https://en.wikipedia.org/wiki/Application_programming_interface">API</a>"), which will in turn communicate with our MongoDB Database to send data back up the stack.</p>
<p>We'll begin by opening a command line, creating a new directory for our project, and navigating into that directory:</p>
<pre><code class="lang-cli">mkdir mevn-character-generator
cd mevn-character-generator
</code></pre>
<p>We'll then install the <a target="_blank" href="https://cli.vuejs.org/">Vue CLI</a> globally to help us scaffold a basic app: </p>
<pre><code class="lang-cli">npm install -g @vue/cli
</code></pre>
<p>Next, we'll use the Vue CLI to create a new app called "Client" within our mevn-character-generator directory:</p>
<pre><code class="lang-cli">vue create client
</code></pre>
<p>You can just hit "enter" at the prompt to keep going.</p>
<p>We can run our app by first navigating into the /client folder:</p>
<pre><code class="lang-cli">cd client
npm run serve
</code></pre>
<p>When the script has completed running, we can now open a browser page and navigate to the URL indicated by our terminal (usually http://localhost:8080 or 8081).  We should see something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Vue-Template.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Nice! The Vue CLI has scaffolded a basic app for us, and is rendering it right into the browser. It'll also reload the page automatically upon file changes, and throw errors if something in the code looks amiss.</p>
<p>Let's open the project directory in our code editor to take a look at the file structure, which should look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/03/Client-Directory.PNG" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you're OCD like I am, you can go ahead and delete the "favicon.ico" file and "/assets" folder as we won't need them for this project.</p>
<p>Diving into /src/main.js, we see:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Vue <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./App.vue'</span>

Vue.config.productionTip = <span class="hljs-literal">false</span>

<span class="hljs-keyword">new</span> Vue({
  <span class="hljs-attr">render</span>: <span class="hljs-function"><span class="hljs-params">h</span> =&gt;</span> h(App),
}).$mount(<span class="hljs-string">'#app'</span>)
</code></pre>
<p>This file is the main entry point for our client. It tells the browser to mount our App.vue file to the div with id "#app" in /public/index.html.</p>
<p>Let's look at /src/App.vue (I've omitted some code for readability):</p>
<pre><code class="lang-javascript">&lt;template&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Vue logo"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./assets/logo.png"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">HelloWorld</span> <span class="hljs-attr">msg</span>=<span class="hljs-string">"Welcome to Your Vue.js App"</span>/&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
<span class="hljs-keyword">import</span> HelloWorld <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/HelloWorld.vue'</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'App'</span>,
  <span class="hljs-attr">components</span>: {
    HelloWorld
  }
}
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span>
#app {
...
}
<span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span></span>
</code></pre>
<p>App.vue is a typical Vue <a target="_blank" href="https://vuejs.org/v2/guide/components.html">component</a>, with , </p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Express.js Security Tips: How You Can Save and Secure Your App ]]>
                </title>
                <description>
                    <![CDATA[ Take 7 steps to make sure that your app is invincible Is your phone locked? Do you have a pin-code, password, fingerprint, or FaceID? I am 99 percent sure that you do. And it is clear why – you care about your safety. Nowadays, keeping your phone pro... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/express-js-security-tips/</link>
                <guid isPermaLink="false">66be14b2b52e57dc7e9d5544</guid>
                
                    <category>
                        <![CDATA[ Express ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oleh Romanyuk ]]>
                </dc:creator>
                <pubDate>Thu, 10 Oct 2019 13:03:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/10/PWA-min.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <h1 id="heading-take-7-steps-to-make-sure-that-your-app-is-invincible">Take 7 steps to make sure that your app is invincible</h1>
<p>Is your phone locked? Do you have a pin-code, password, fingerprint, or FaceID? I am 99 percent sure that you do. And it is clear why – you care about your safety. Nowadays, keeping your phone protected is as important as brushing your teeth in the morning.</p>
<p>For diligent and mindful software developers, keeping their app secure is equally important to protecting their phones. If you are a developer and you choose to neglect it – please, reconsider your approach. If you are a project owner and your development team says that data safety can wait, please, reconsider your team.</p>
<p>In this article, I want to talk about how to make sure that your <a target="_blank" href="https://keenethics.com/tech-back-end-express">Express.js</a> project is safe and invincible to malicious attacks.</p>
<p>There are 7 simple and not very simple measures to take for the purpose of data security:</p>
<ol>
<li><strong>Use reliable versions of Express.js</strong></li>
<li><strong>Secure the connection and data</strong></li>
<li><strong>Protect your cookies</strong></li>
<li><strong>Secure your dependencies</strong></li>
<li><strong>Validate the input of your users</strong></li>
<li><strong>Protect your system against brute force</strong></li>
<li><strong>Control user access</strong></li>
</ol>
<p>Let’s have a closer look at each.</p>
<h2 id="heading-1-use-reliable-versions-of-expressjs"><strong>1. Use reliable versions of Express.js</strong></h2>
<p>Deprecated or outdated versions of Express.js are a no go. The 2nd and 3rd versions of Express are no longer supported. In these, safety or performance issues are not fixed anymore. </p>
<p>As a developer, you absolutely have to <a target="_blank" href="https://expressjs.com/en/guide/migrating-4.html">migrate to Express 4</a>. This version is a revolution! It is quite different in terms of the routing system, middleware, and other minor aspects.</p>
<h2 id="heading-2-secure-the-connection-and-data"><strong>2. Secure the connection and data</strong></h2>
<p>To secure HTTP headers, you can make use of <a target="_blank" href="https://helmetjs.github.io/">Helmet.js</a> – a helpful Node.js module. It is a collection of 13 middleware functions for setting HTTP response headers. In particular, there are functions for setting Content Security Policy, handling Certificate Transparency, preventing clickjacking, disabling client-side caching, or adding some small XSS protections.</p>
<pre><code class="lang-js">npm install helmet --save
</code></pre>
<p>Even if you do not want to use all the functions of Helmet, the absolute minimum that you must do is to disable X-Powered-By header:</p>
<pre><code class="lang-js">app.disable(<span class="hljs-string">'x-powered-by'</span>)
</code></pre>
<p>This header can be used to detect that the application is powered by Express, which lets hackers conduct a precise attack. Surely, X-Powered-By header is not the only way to identify an Express-run application, but it is probably the most common and simple one.</p>
<p>To protect your system from HTTP parameter pollution attacks, you can use <a target="_blank" href="https://www.npmjs.com/package/hpp">HPP</a>. This middleware puts aside such parameters as req.query and req.body and selects the latest parameter value instead. The installation command looks as follows:</p>
<pre><code class="lang-js">npm install hpp --save
</code></pre>
<p>To encrypt data which is being sent from the client to the server, use Transport Layer Security (TLS). TLS is a cryptographic protocol for securing the computer network, the descendant of the Secure Socket Layer (SSL) encryption. TLS can be handled with <a target="_blank" href="https://www.nginx.com/">Nginx</a> – a free but effective HTTP server – and <a target="_blank" href="https://letsencrypt.org/about/">Let’s Encrypt</a> – a free TLS certificate.</p>
<h2 id="heading-3-protect-your-cookies"><strong>3. Protect your cookies</strong></h2>
<p>In Express.js 4, there are two cookie session modules:</p>
<ul>
<li>express-session (in Express.js 3, it was express.session)</li>
<li>cookie-session (in Express.js 3, it was express.cookieSession)</li>
</ul>
<p>The express-session module stores session ID in the cookie and session data on the server. The cookie-session stores all the session data to the cookie.</p>
<p>In general, cookie-session is more efficient. Yet, if the session data you need to store is complex and likely to exceed 4096 bytes per cookie, use express-session. Another reason to use express-session is when you need to keep the cookie data invisible to the client.</p>
<p>Besides, you should set cookie security options, namely:</p>
<ul>
<li>secure</li>
<li>httpOnly</li>
<li>domain</li>
<li>path</li>
<li>expires</li>
</ul>
<p>If “secure” is set to “true”, the browser will send cookies only via HTTPS. If “httpOnly” is set to “true”, the cookie will be sent not via client JS but via HTTP(S). The value of “domain” indicates the domain of the cookie. If the cookie domain matches the server domain, “path” is used to indicate the cookie path. If the cookie path matches the request path, the cookie will be sent in the request. Finally, as the name itself suggests, the value of “expires” stands for the time when the cookies will expire.</p>
<p>Another important recommendation is not to use the default session cookie name. It may enable hackers to detect the server and to run a targeted attack. Instead, use generic cookie names.</p>
<h2 id="heading-4-secure-your-dependencies"><strong>4. Secure your dependencies</strong></h2>
<p>No doubt, npm is a powerful web development tool. However, to ensure the highest level of security, consider using only the 6th version of it – <a target="_blank" href="https://www.npmjs.com/package/npm/v/6.0.1">npm@6</a>. The older ones may contain some serious dependency safety vulnerabilities, which will endanger your entire app. Also, to analyze the tree of dependencies, use the following command:</p>
<pre><code class="lang-js">npm audit
</code></pre>
<p>npm audit can help to fix real problems in your project. It checks all your dependencies in dependencies, devDependencies, bundledDependencies, and optionalDependencies, but not your peerDependencies. <a target="_blank" href="https://www.npmjs.com/advisories">Here</a> you can read about all current vulnerabilities in any npm packages.</p>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/2LwpppvohhSerxOi2K7yNp/5a7869f23e9474fe9fe6b6e61a956322/Screenshot_2019-10-07_at_5.07.57_PM.png?fm=png&amp;q=85&amp;w=1000" alt="Securing dependencies" width="600" height="400" loading="lazy"></p>
<p>Another tool to ensure dependency safety is <a target="_blank" href="https://snyk.io/">Snyk</a>. Snyk runs the application check to identify whether it contains any vulnerability listed in Snyk’s open-source database. To conduct the check, run three simple steps.</p>
<h3 id="heading-step-1-install-snyk">Step 1. Install Snyk</h3>
<pre><code class="lang-js">npm install -g snyk
cd your-app
</code></pre>
<h3 id="heading-step-2-run-a-test">Step 2. Run a test</h3>
<pre><code class="lang-js">snyk test
</code></pre>
<h3 id="heading-step-3-learn-how-to-fix-the-issue">Step 3. Learn how to fix the issue</h3>
<pre><code class="lang-js">snyk wizard
</code></pre>
<p>Wizard is a Snyk method, which explains the nature of the dependency vulnerability and offers ways of fixing it.</p>
<h2 id="heading-5-validate-the-input-of-your-users"><strong>5. Validate the input of your users</strong></h2>
<p>Controlling user input is an extremely important part for server-side development. This is a no less important problem than unauthorized requests, which will be described in the seventh part of this article.</p>
<p>First of all, wrong user input can break your server when some values are undefined and you do not have error handling for a specific endpoint. However, different ORM systems can have unpredictable behavior when you try to set undefined, null, or other data types in the database.</p>
<p>For example, destroyAll method in Loopback.js ORM (Node.js framework) can destroy all data in a table of the database: when it does not match any records it deletes everything as described <a target="_blank" href="https://www.npmjs.com/package/npm/v/6.0.1">here</a>. Imagine that you can lose all data in a production table just because you have ignored input validation.</p>
<h3 id="heading-use-bodyobject-validation-for-intermediate-inspections">Use body/object validation for intermediate inspections</h3>
<p>To start with, you can use body/object validation for intermediate inspections. For example, we use ajv validator which is the fastest JSON Schema validator for Node.js.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Ajv = <span class="hljs-built_in">require</span>(<span class="hljs-string">'ajv'</span>); 
<span class="hljs-keyword">const</span> ajv = <span class="hljs-keyword">new</span> Ajv({<span class="hljs-attr">allErrors</span>: <span class="hljs-literal">true</span>}); 
<span class="hljs-keyword">const</span> speaker = { 
  <span class="hljs-string">'type'</span>: <span class="hljs-string">'object'</span>, 
  <span class="hljs-string">'required'</span>: [
    <span class="hljs-string">'id'</span>, 
    <span class="hljs-string">'name'</span>
  ],
  <span class="hljs-string">'properties'</span>: { 
    <span class="hljs-string">'id'</span>: {
      <span class="hljs-string">'type'</span>: <span class="hljs-string">'integer'</span>, 
    }, 
    <span class="hljs-string">'name'</span>: { 
      <span class="hljs-string">'type'</span>: <span class="hljs-string">'string'</span>,
    }, 
  }, 
};
<span class="hljs-keyword">const</span> conversation = { 
  <span class="hljs-attr">type</span>: <span class="hljs-string">'object'</span>, 
  <span class="hljs-attr">required</span>: [
    <span class="hljs-string">'duration'</span>, 
    <span class="hljs-string">'monologues'</span>
  ], 
  <span class="hljs-attr">properties</span>: { 
    <span class="hljs-attr">duration</span>: { 
      <span class="hljs-attr">type</span>: <span class="hljs-string">'integer'</span>,
    }, 
    <span class="hljs-attr">monologues</span>: { 
      <span class="hljs-attr">type</span>: <span class="hljs-string">'array'</span>, 
      <span class="hljs-attr">items</span>: monolog, 
    }, 
  }, 
};
<span class="hljs-keyword">const</span> body = { 
  <span class="hljs-attr">type</span>: <span class="hljs-string">'object'</span>, 
  <span class="hljs-attr">required</span>: [
    <span class="hljs-string">'speakers'</span>, 
    <span class="hljs-string">'conversations'</span>
  ], 
  <span class="hljs-attr">properties</span>: { 
    <span class="hljs-attr">speakers</span>: { 
      <span class="hljs-attr">type</span>: <span class="hljs-string">'array'</span>, 
      <span class="hljs-attr">items</span>: speaker, 
    }, 
    <span class="hljs-attr">conversations</span>: { 
      <span class="hljs-attr">type</span>: <span class="hljs-string">'array'</span>, 
      <span class="hljs-attr">items</span>: conversation, 
    }, 
  }, 
}; 
<span class="hljs-keyword">const</span> validate = ajv.compile(body); 
<span class="hljs-keyword">const</span> isValidTranscriptBody = <span class="hljs-function"><span class="hljs-params">transcriptBody</span> =&gt;</span> { 
  <span class="hljs-keyword">const</span> isValid = validate(transcriptBody);
  <span class="hljs-keyword">if</span> (!isValid) { 
    <span class="hljs-built_in">console</span>.error(validate.errors); 
  } 
  <span class="hljs-keyword">return</span> isValid; 
};
</code></pre>
<h3 id="heading-handle-errors">Handle errors</h3>
<p>Now, imagine that you forgot to check a certain object and you do some operations with the undefined property. Or you use a certain library and you get an error. It can break your instance, and the server will crash. Then, the attacker can ping a specific endpoint where there is this vulnerability and can stop your server for a long time. </p>
<p>The simplest way to do an error handling is to use try-catch construction:</p>
<pre><code class="lang-js"><span class="hljs-keyword">try</span> { 
  <span class="hljs-keyword">const</span> data = body;
  <span class="hljs-keyword">if</span> (data.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Client Error'</span>); 
  <span class="hljs-keyword">const</span> beacons = <span class="hljs-keyword">await</span>  <span class="hljs-built_in">this</span>.beaconLogService.filterBeacon(data); 
  <span class="hljs-keyword">if</span> (beacons.length &gt; <span class="hljs-number">0</span>) { 
    <span class="hljs-keyword">const</span> max = beacons.reduce(<span class="hljs-function">(<span class="hljs-params">prev, current</span>) =&gt;</span> (prev.rssi &gt; current.rssi) ? prev : current); 
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.beaconLogService.save({ 
      ...max,
      <span class="hljs-attr">userId</span>: headers[<span class="hljs-string">'x-uuid'</span>] 
    }); 
    <span class="hljs-keyword">return</span> { 
      <span class="hljs-attr">data</span>: { 
        <span class="hljs-attr">status</span>: <span class="hljs-string">'Saved'</span>, 
        <span class="hljs-attr">position</span>: max 
      }, 
    }; 
  } 
  <span class="hljs-keyword">return</span> { 
    <span class="hljs-attr">data</span>: { 
      <span class="hljs-attr">status</span>: <span class="hljs-string">'Not valid object, 
    }, 
  }; 
} 
catch(err) { 
  this.logger.error(err.message, err.stack); 
  throw new HttpException('</span>Server <span class="hljs-built_in">Error</span><span class="hljs-string">',     HttpStatus.INTERNAL_SERVER_ERROR); 
}</span>
</code></pre>
<p>Feel free to use a new Error(‘message’) constructor for error handling or even extend this class for your own purpose!</p>
<h3 id="heading-use-joi">Use JOI</h3>
<p>The main lesson here is that you should always validate user input so you don't fall victim to man-in-the-middle attacks. Another way to do it is with the help of <a target="_blank" href="https://www.npmjs.com/package/@hapi/joi">@hapi/joi</a> – a part of the hapi ecosystem and a powerful JS data validation library.</p>
<p>Pay attention here that the module <a target="_blank" href="https://www.npmjs.com/package/joi">joi</a> has been deprecated. For this reason, the following command is a no go:</p>
<pre><code class="lang-js">npm install joi
</code></pre>
<p>Instead, use this one:</p>
<pre><code class="lang-js">npm install @hapi/joi
</code></pre>
<h3 id="heading-use-express-validator">Use express-validator</h3>
<p>One more way to validate user input is to use express-validator – a set of express.js middlewares, which comprises validator.js and function sanitizer. To install it, run the following command:</p>
<pre><code class="lang-js">npm install --save express-validator
</code></pre>
<h3 id="heading-sanitize-user-input">Sanitize user input</h3>
<p>Also, an important measure to take is to sanitize user input to protect the system from a MongoDB operator injection. For this, you should install and use express-mongo-sanitize:</p>
<pre><code class="lang-js">npm install express-mongo-sanitize
</code></pre>
<h3 id="heading-protect-your-app-against-csrf">Protect your app against CSRF</h3>
<p>Besides, you should protect your app against cross-site request forgery (CSRF). CSRF is when unauthorized commands are sent from a trusted user. You can do this with the help of <a target="_blank" href="https://www.npmjs.com/package/csurf">csurf</a>. Prior to that, you need to make sure that session middleware for cookies is configured as described earlier in this article. To install this Node.js module, run the command:</p>
<pre><code class="lang-js">npm install csurf
</code></pre>
<h2 id="heading-6-protect-your-system-against-brute-force"><strong>6. Protect your system against brute force</strong></h2>
<p>A brute force attack is the simplest and most common way to get access to a website or a server. The hacker (in most cases automatically, rarely manually) tries various usernames and passwords repeatedly to break into the system.</p>
<p>These attacks can be prevented with the help of <a target="_blank" href="https://github.com/animir/node-rate-limiter-flexible">rate-limiter-flexible</a> package. This package is fast, flexible, and suitable for any Node framework.</p>
<p>To install, run the following command:</p>
<pre><code class="lang-js">npm i --save rate-limiter-flexible
yarn add rate-limiter-flexible
</code></pre>
<p>This method has a simpler but more primitive alternative: <a target="_blank" href="https://www.npmjs.com/package/express-rate-limit">express-rate-limit</a>. The only thing it does is limiting repeated requests to public APIs or to password reset.</p>
<pre><code class="lang-js">npm install --save express-rate-limit
</code></pre>
<h2 id="heading-7-control-user-access"><strong>7. Control user access</strong></h2>
<p>Among the authentication methods, there are tokens, Auth0, and JTW. Let’s focus on the third one! JTW (JSON Web Tokens) are used to transfer authentication data in client-server applications. Tokens are created by the server, signed with a secret key, and transferred to a client. Then, the client uses these tokens to confirm identity.</p>
<p><a target="_blank" href="https://www.npmjs.com/package/express-jwt-permissions">Express-jwt-permissions</a> is a tool used together with <a target="_blank" href="https://github.com/auth0/express-jwt">express-jwt</a> to check permissions of a certain token. These permissions are an array of strings inside the token:</p>
<pre><code class="lang-js"><span class="hljs-string">"permissions"</span>: [
  <span class="hljs-string">"status"</span>,
  <span class="hljs-string">"user:read"</span>,
  <span class="hljs-string">"user:write"</span>
]
</code></pre>
<p>To install the tool, run the following command:</p>
<pre><code class="lang-js">npm install express-jwt-permissions --save
</code></pre>
<h2 id="heading-to-wrap-up"><strong>To Wrap Up</strong></h2>
<p>Here, I have listed the essential Express.js security best practices and some tools that can be used along the way.</p>
<h3 id="heading-just-to-review"><strong>Just to review:</strong></h3>
<p><img src="https://images.ctfassets.net/6xhdtf1foerq/2LwpppvohhSerxOi2K7yNp/5a7869f23e9474fe9fe6b6e61a956322/Screenshot_2019-10-07_at_5.07.57_PM.png?fm=png&amp;q=85&amp;w=1000" alt="Securing dependencies" width="600" height="400" loading="lazy"></p>
<p>I strongly recommend that you make sure that your application is resistant to malicious attacks. Otherwise, your business and your users may suffer significant losses.</p>
<h2 id="heading-do-you-have-an-idea-for-expressjs-project">Do you have an idea for Express.js project?</h2>
<p>My company KeenEthics is experienced in <a target="_blank" href="https://keenethics.com/tech-back-end-express">express js development</a>. In case you need a free estimate of a similar project, feel free to <a target="_blank" href="https://keenethics.com/contacts">get in touch</a><em>.</em></p>
<p>If you have enjoyed the article, you should definitely continue with a piece on data safety in outsourcing to Ukraine: <a target="_blank" href="https://keenethics.com/blog/1543388400000-your-data-is-safe-in-ukraine?utm_source=freecodecamp&amp;utm_medium=freecodecamp&amp;utm_campaign=freecodecamp">KeenEthics Team on Guard: Your Data is Safe in Ukraine</a>. The original article posted on KeenEthics blog can be found here: <a target="_blank" href="https://keenethics.com/blog/express-js-security-tips">express js security tips</a>.</p>
<h2 id="heading-ps">P.S.</h2>
<p>A huge shout-out to <a target="_blank" href="https://www.linkedin.com/in/andrushchak-volodia-167430125/">Volodia Andrushchak</a>, Full-Stack Software Developer @KeenEthics for helping me with the article.</p>
<p>The original article posted on KeenEthics blog can be found here: <a target="_blank" href="https://keenethics.com/blog/express-js-security-tips">Express.js Security Tips: Save Your App!</a></p>
<p># </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A step-by-step intro to end-point testing ]]>
                </title>
                <description>
                    <![CDATA[ I've been playing around with testing lately. One thing I tried to do was to test the endpoints of my Express application. Setting up the test was the hard part. People who write about tests don't actually teach you how they set it up. I could not fi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/end-point-testing/</link>
                <guid isPermaLink="false">66c4c72a99f22436b71945e7</guid>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Testing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zell Liew ]]>
                </dc:creator>
                <pubDate>Wed, 28 Aug 2019 23:51:55 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9ca097740569d1a4ca49a0.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I've been playing around with testing lately. One thing I tried to do was to test the endpoints of my Express application.</p>
<p>Setting up the test was the hard part. People who write about tests don't actually teach you how they set it up. I could not find any useful information about this, and I had to try and figure it out.</p>
<p>So today, I want to share the setup I created for myself. Hopefully, this can help you when you create your own tests.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><a class="post-section-overview" href="#heading-setting-up-jest-and-supertest">Setting up Jest and Supertest</a></li>
<li><a class="post-section-overview" href="#heading-connecting-jest-and-mongoose">Connecting Jest and Mongoose</a></li>
<li><a class="post-section-overview" href="#heading-seeding-a-database">Seeding a database</a></li>
</ol>
<h2 id="part1">Setting up Jest and Supertest</h2>

<p>First, let's talk about the stack.</p>
<h3 id="heading-the-stack">The Stack</h3>
<ul>
<li>I created my app with Express.</li>
<li>I used Mongoose to connect to MongoDB</li>
<li>I used Jest as my test framework.</li>
</ul>
<p>You might have expected Express and Mongoose because everyone else seems to use those two frameworks. I used them too.</p>
<p>But why Jest and not other test frameworks?</p>
<h3 id="heading-why-jest">Why Jest</h3>
<p>I don't like Facebook, so I didn't want to try anything that was created by Facebook's team. I know it sounds silly, but that was the truth.</p>
<p>Before Jest, I tried out all sorts of test frameworks. I tried Tap, Tape, Mocha, Jasmine, and AVA. Each test framework has its own pros and cons. I almost ended up with AVA, but I didn't go with AVA because I found it hard to set up. Eventually, I tried Jest out because Kent C. Dodds recommended it.</p>
<p>I fell in love with Jest after trying it out. I love it because:</p>
<ol>
<li>It's easy to setup</li>
<li>The <a target="_blank" href="https://egghead.io/lessons/javascript-use-jest-s-interactive-watch-mode">watch-mode</a> is amazing</li>
<li>When you <code>console.log</code> something, it actually shows up without any difficulty (this was a bitch with AVA).</li>
</ol>
<h3 id="heading-setting-up-jest">Setting up Jest</h3>
<p>First, you need to install Jest.</p>
<pre><code class="lang-js">npm install jest --save-dev
</code></pre>
<p>Next, you want to add tests scripts to your <code>package.json</code> file. It helps to add the <code>test</code> and <code>test:watch</code> scripts (for one-off testing and watch-mode respectively).</p>
<pre><code class="lang-js"><span class="hljs-string">"scripts"</span>: {
  <span class="hljs-string">"test"</span>: <span class="hljs-string">"jest"</span>,
  <span class="hljs-string">"test:watch"</span>: <span class="hljs-string">"jest --watch"</span>
},
</code></pre>
<p>You can choose to write your test files in one of the following formats. Jest picks them up for you automatically.</p>
<ol>
<li><code>js</code> files in the <code>__tests__</code> folder</li>
<li>files named with <code>test.js</code> (like <code>user.test.js</code>)</li>
<li>files named with <code>spec.js</code> (like <code>user.spec.js</code>)</li>
</ol>
<p>You can place your files however you like. When I tested endpoints, I put the test files together with my endpoints. I found this easier to manage.</p>
<pre><code class="lang-bash">- routes
  |- users/
    |- index.js
    |- users.test.js
</code></pre>
<h3 id="heading-writing-your-first-test">Writing your first test</h3>
<p>Jest includes <code>describe</code>, <code>it</code> and <code>expect</code> for you in every test file. You don't have to <code>require</code> them.</p>
<ul>
<li><code>describe</code> lets you wrap many tests together under one umbrella. (It is used for organizing your tests).</li>
<li><code>it</code> lets you run a test.</li>
<li><code>expect</code> lets you perform assertions. The test passes if all assertions passes.</li>
</ul>
<p>Here's an example of a test that fails. In this example, I <code>expect</code> that <code>1</code> should be strictly equal to <code>2</code>. Since <code>1 !== 2</code>, the test fails.</p>
<pre><code class="lang-js"><span class="hljs-comment">// This test fails because 1 !== 2</span>
it(<span class="hljs-string">"Testing to see if Jest works"</span>, <span class="hljs-function">() =&gt;</span> {
  expect(<span class="hljs-number">1</span>).toBe(<span class="hljs-number">2</span>);
});
</code></pre>
<p>You'll see a failing message from Jest if you run Jest.</p>
<pre><code class="lang-js">npm run test:watch
</code></pre>
<figure><img src="https://zellwk.com/images/2019/endpoint-testing/test-fail.png" alt="Output from Terminal. Test fails." width="600" height="400" loading="lazy"></figure>

<p>You can make the test pass by expecting <code>1 === 1</code>.</p>
<pre><code class="lang-js"><span class="hljs-comment">// This passes because 1 === 1</span>
it(<span class="hljs-string">"Testing to see if Jest works"</span>, <span class="hljs-function">() =&gt;</span> {
  expect(<span class="hljs-number">1</span>).toBe(<span class="hljs-number">1</span>);
});
</code></pre>
<figure><img src="https://zellwk.com/images/2019/endpoint-testing/test-pass.png" alt="Output from Terminal. Test successful." width="600" height="400" loading="lazy"></figure>

<p>This is the most basic of tests. It's not useful at all because we haven't testing anything real yet.</p>
<h2 id="heading-asynchronous-tests">Asynchronous tests</h2>
<p>You need to send a request to test an endpoint. Requests are asynchronous, which means you must be able to conduct asynchronous tests.</p>
<p>This is easy with Jest. There are two steps:</p>
<ol>
<li>Add the <code>async</code> keyword</li>
<li>Call <code>done</code> when you're done with your tests</li>
</ol>
<p>Here's what it can look like:</p>
<pre><code class="lang-js">it(<span class="hljs-string">"Async test"</span>, <span class="hljs-keyword">async</span> done =&gt; {
  <span class="hljs-comment">// Do your async tests here</span>

  done();
});
</code></pre>
<p>Note: <a target="_blank" href="https://zellwk.com/blog/async-await">Here's an article</a> on Async/await in JavaScript if you don't know how to use it.</p>
<h2 id="heading-testing-endpoints">Testing Endpoints</h2>
<p>You can use Supertest to test endpoints. First, you need to install Supertest.</p>
<pre><code class="lang-bash">npm install supertest --save-dev
</code></pre>
<p>Before you can test endpoints, you need to setup the server so Supertest can use it in your tests.</p>
<p>Most tutorials teach you to <code>listen</code> to the Express app in the server file, like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> app = express();

<span class="hljs-comment">// Middlewares...</span>
<span class="hljs-comment">// Routes...</span>

app.listen(<span class="hljs-number">3000</span>);
</code></pre>
<p>This doesn't work because it starts listening to one port. If you try to write many test files, you'll get an error that says "port in use".</p>
<p>You want to allow each test file to start a server on their own. To do this, you need to export <code>app</code> without listening to it.</p>
<pre><code class="lang-js"><span class="hljs-comment">// server.js</span>
<span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> app = express();

<span class="hljs-comment">// Middlewares...</span>
<span class="hljs-comment">// Routes...</span>

<span class="hljs-built_in">module</span>.exports = app;
</code></pre>
<p>For development or production purposes, you can listen to your <code>app</code> like normal in a different file like <code>start.js</code>.</p>
<pre><code class="lang-js"><span class="hljs-comment">// start.js</span>
<span class="hljs-keyword">const</span> app = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./server.js"</span>);
app.listen(<span class="hljs-number">3000</span>);
</code></pre>
<h3 id="heading-using-supertest">Using Supertest</h3>
<p>To use Supertest, you require your app and supertest in the test file.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> app = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./server"</span>); <span class="hljs-comment">// Link to your server file</span>
<span class="hljs-keyword">const</span> supertest = <span class="hljs-built_in">require</span>(<span class="hljs-string">"supertest"</span>);
<span class="hljs-keyword">const</span> request = supertest(app);
</code></pre>
<p>Once you do this, you get the ability to send GET, POST, PUT, PATCH and DELETE requests. Before we send a request, we need to have an endpoint. Let's say we have a <code>/test</code> endpoint.</p>
<pre><code class="lang-js">app.get(<span class="hljs-string">"/test"</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {
  res.json({ <span class="hljs-attr">message</span>: <span class="hljs-string">"pass!"</span> });
});
</code></pre>
<p>To send a GET request to <code>/test</code>, you use the <code>.get</code> method from Supertest.</p>
<pre><code class="lang-js">it(<span class="hljs-string">"Gets the test endpoint"</span>, <span class="hljs-keyword">async</span> done =&gt; {
  <span class="hljs-comment">// Sends GET Request to /test endpoint</span>
  <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> request.get(<span class="hljs-string">"/test"</span>);

  <span class="hljs-comment">// ...</span>
  done();
});
</code></pre>
<p>Supertest gives you a response from the endpoint. You can test both HTTP status and the body (whatever you send through <code>res.json</code>) like this:</p>
<pre><code class="lang-js">it(<span class="hljs-string">"gets the test endpoint"</span>, <span class="hljs-keyword">async</span> done =&gt; {
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> request.get(<span class="hljs-string">"/test"</span>);

  expect(response.status).toBe(<span class="hljs-number">200</span>);
  expect(response.body.message).toBe(<span class="hljs-string">"pass!"</span>);
  done();
});
</code></pre>
<figure><img src="https://zellwk.com/images/2019/endpoint-testing/test-endpoint-pass.png" alt="First endpoint test passes." width="600" height="400" loading="lazy"></figure>


<h2 id="part2">Connecting Jest and Mongoose</h2>

<p>The hard part about testing a backend application is setting up a test database. It can be complicated.</p>
<p>Today, I want to share how I setup Jest and Mongoose.</p>
<h3 id="heading-setting-up-mongoose-with-jest">Setting up Mongoose with Jest</h3>
<p>Jest gives you a warning if you try to use Mongoose with Jest.</p>
<figure><img src="https://zellwk.com/images/2019/jest-and-mongoose/mongoose-jest-warning.png" alt="Warning if you try to use Mongoose with Jest" width="600" height="400" loading="lazy"></figure>

<p>If you don't want to see this error, you need to set <code>testEnvironment</code> to <code>node</code> in your <code>package.json</code> file.</p>
<pre><code class="lang-js"><span class="hljs-string">"jest"</span>: {
  <span class="hljs-string">"testEnvironment"</span>: <span class="hljs-string">"node"</span>
}
</code></pre>
<h3 id="heading-setting-up-mongoose-in-a-test-file">Setting up Mongoose in a test file</h3>
<p>You want to connect to a database before you begin any tests. You can use the <code>beforeAll</code> hook to do so.</p>
<pre><code class="lang-js">beforeAll(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-comment">// Connect to a Mongo DB</span>
});
</code></pre>
<p>To connect to a MongoDB, you can use Mongoose's <code>connect</code> command.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mongoose"</span>);
<span class="hljs-keyword">const</span> databaseName = <span class="hljs-string">"test"</span>;

beforeAll(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> url = <span class="hljs-string">`mongodb://127.0.0.1/<span class="hljs-subst">${databaseName}</span>`</span>;
  <span class="hljs-keyword">await</span> mongoose.connect(url, { <span class="hljs-attr">useNewUrlParser</span>: <span class="hljs-literal">true</span> });
});
</code></pre>
<p>This creates a connection to the database named <code>test</code>. You can name your database anything. You'll learn how to clean them up later.</p>
<p>Note: Make sure you have an active local MongoDB Connection before you test. Your tests will fail if you don't have an active local MongoDB Connection. <a target="_blank" href="https://zellwk.com/blog/local-mongodb">Read this</a> to learn how to create a local MongoDB connection.</p>
<h3 id="heading-creating-databases-for-each-test-file">Creating databases for each test file</h3>
<p>When you test, you want to connect to a different database for each test file, because:</p>
<ol>
<li>Jest runs each test file asynchronously. You won't know which file comes first.</li>
<li>You don't want tests to share the same database. You don't want data from one test file to spill over to the next test file.</li>
</ol>
<p>To connect to a different database, you change the name of the database.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Connects to database called avengers</span>
beforeAll(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> url = <span class="hljs-string">`mongodb://127.0.0.1/avengers`</span>;
  <span class="hljs-keyword">await</span> mongoose.connect(url, { <span class="hljs-attr">useNewUrlParser</span>: <span class="hljs-literal">true</span> });
});
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// Connects to database power-rangers</span>
beforeAll(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> url = <span class="hljs-string">`mongodb://127.0.0.1/power-rangers`</span>;
  <span class="hljs-keyword">await</span> mongoose.connect(url, { <span class="hljs-attr">useNewUrlParser</span>: <span class="hljs-literal">true</span> });
});
</code></pre>
<h3 id="heading-sending-a-post-request">Sending a POST request</h3>
<p>Let's say you want to create a user for your app. The user has a name and an email address. Your Mongoose Schema might look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mongoose"</span>);
<span class="hljs-keyword">const</span> Schema = mongoose.Schema;

<span class="hljs-keyword">const</span> userSchema = <span class="hljs-keyword">new</span> Schema({
  <span class="hljs-attr">name</span>: <span class="hljs-built_in">String</span>,
  <span class="hljs-attr">email</span>: {
    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">require</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>
  }
});

<span class="hljs-built_in">module</span>.exports = mongoose.model(<span class="hljs-string">"User"</span>, userSchema);
</code></pre>
<p>To create a user, you need to save the <code>name</code> and <code>email</code> into MongoDB. Your route and controller might look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/User"</span>); <span class="hljs-comment">// Link to your user model</span>

app.post(<span class="hljs-string">"/signup"</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">const</span> { name, email } = req.body;
  <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">new</span> User({ name, email });
  <span class="hljs-keyword">const</span> ret = <span class="hljs-keyword">await</span> user.save();
  res.json(ret);
});
</code></pre>
<p>To save the user into the database, you can send a POST request to <code>signup</code>. To send a post request, you use the <code>post</code> method. To send data along with the POST request, you use the <code>send</code> method. In your tests, it'll look like this.</p>
<pre><code class="lang-js">it(<span class="hljs-string">"Should save user to database"</span>, <span class="hljs-keyword">async</span> done =&gt; {
  <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> request.post(<span class="hljs-string">"/signup"</span>).send({
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Zell"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"testing@gmail.com"</span>
  });
  done();
});
</code></pre>
<p>Note: If you run this code two times, you'll get an <code>E1100 duplicate key error</code>. This error occurred because:</p>
<ol>
<li>We said the <code>email</code> should be <code>unique</code> in the Schema above.</li>
<li>We tried to create another user with <code>testing@gmail.com</code>. even though one already exists in the database. (The first one was created when you sent the first request).</li>
</ol>
<figure><img src="https://zellwk.com/images/2019/jest-and-mongoose/duplicate-error.png" alt="Duplicate key error." width="600" height="400" loading="lazy"></figure>

<h2 id="heading-cleaning-up-the-database-between-tests">Cleaning up the database between tests</h2>
<p>You want to remove entries from the database between each test. This ensures you always start with an empty database.</p>
<p>You can do this with the <code>afterEach</code> hook.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Cleans up database between each test</span>
afterEach(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">await</span> User.deleteMany();
});
</code></pre>
<p>In this code above, we only cleared the <code>User</code> collection in the database. In a real scenario, you want to clear all collections. You can use the following code to do so:</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">removeAllCollections</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> collections = <span class="hljs-built_in">Object</span>.keys(mongoose.connection.collections);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> collectionName <span class="hljs-keyword">of</span> collections) {
    <span class="hljs-keyword">const</span> collection = mongoose.connection.collections[collectionName];
    <span class="hljs-keyword">await</span> collection.deleteMany();
  }
}

afterEach(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">await</span> removeAllCollections();
});
</code></pre>
<h3 id="heading-testing-the-endpoint">Testing the Endpoint</h3>
<p>Let's begin our tests. In this test, we will send a POST request to the <code>/signup</code> endpoint. We want to make sure:</p>
<ol>
<li>The user gets saved to the database</li>
<li>The returned object contains information about the user</li>
</ol>
<h3 id="heading-checking-if-the-user-was-saved-to-the-database">Checking if the user was saved to the database</h3>
<p>To check whether the user gets saved into the database, you search the database for the user.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/User"</span>); <span class="hljs-comment">// Link to your user model</span>

it(<span class="hljs-string">"Should save user to database"</span>, <span class="hljs-keyword">async</span> done =&gt; {
  <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> request.post(<span class="hljs-string">"/signup"</span>).send({
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Zell"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"testing@gmail.com"</span>
  });

  <span class="hljs-comment">// Searches the user in the database</span>
  <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findOne({ <span class="hljs-attr">email</span>: <span class="hljs-string">"testing@gmail.com"</span> });

  done();
});
</code></pre>
<p>If you <code>console.log</code> user, you should see something like this:</p>
<figure><img src="https://zellwk.com/images/2019/jest-and-mongoose/user.png" alt="User object from MongoDB." width="600" height="400" loading="lazy"></figure>

<p>This means our user got saved to the database. If we want to confirm the user has a name and an email, we can do <code>expect</code> them to be true.</p>
<pre><code class="lang-js">it(<span class="hljs-string">"Should save user to database"</span>, <span class="hljs-keyword">async</span> done =&gt; {
  <span class="hljs-comment">// Sends request...</span>

  <span class="hljs-comment">// Searches the user in the database</span>
  <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findOne({ <span class="hljs-attr">email</span>: <span class="hljs-string">"testing@gmail.com"</span> });
  expect(user.name).toBeTruthy();
  expect(user.email).toBeTruthy();

  done();
});
</code></pre>
<h4 id="heading-checking-if-the-returned-object-contains-the-information-about-the-user">Checking if the returned object contains the information about the user</h4>
<p>We want to make sure the returned object contains the user's name and email address. To do this, we check the response from the post request.</p>
<pre><code class="lang-js">it(<span class="hljs-string">"Should save user to database"</span>, <span class="hljs-keyword">async</span> done =&gt; {
  <span class="hljs-comment">// Sends request...</span>

  <span class="hljs-comment">// Searches the user in the database...</span>

  <span class="hljs-comment">// Ensures response contains name and email</span>
  expect(res.body.name).toBeTruthy();
  expect(res.body.email).toBeTruthy();
  done();
});
</code></pre>
<p>We're done with our tests now. We want to delete the database from MongoDB.</p>
<h3 id="heading-deleting-the-database">Deleting the database</h3>
<p>To delete the database, you need to ensure there are 0 collections in the database. We can do this by dropping each collection we used.</p>
<p>We'll do after all our tests have run, in the <code>afterAll</code> hook.</p>
<pre><code class="lang-js">afterAll(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-comment">// Removes the User collection</span>
  <span class="hljs-keyword">await</span> User.drop();
});
</code></pre>
<p>To drop all your collections you can use this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dropAllCollections</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> collections = <span class="hljs-built_in">Object</span>.keys(mongoose.connection.collections);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> collectionName <span class="hljs-keyword">of</span> collections) {
    <span class="hljs-keyword">const</span> collection = mongoose.connection.collections[collectionName];
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> collection.drop();
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-comment">// This error happens when you try to drop a collection that's already dropped. Happens infrequently.</span>
      <span class="hljs-comment">// Safe to ignore.</span>
      <span class="hljs-keyword">if</span> (error.message === <span class="hljs-string">"ns not found"</span>) <span class="hljs-keyword">return</span>;

      <span class="hljs-comment">// This error happens when you use it.todo.</span>
      <span class="hljs-comment">// Safe to ignore.</span>
      <span class="hljs-keyword">if</span> (error.message.includes(<span class="hljs-string">"a background operation is currently running"</span>))
        <span class="hljs-keyword">return</span>;

      <span class="hljs-built_in">console</span>.log(error.message);
    }
  }
}

<span class="hljs-comment">// Disconnect Mongoose</span>
afterAll(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">await</span> dropAllCollections();
});
</code></pre>
<p>Finally, you want to close the Mongoose connection to end the test. Here's how you can do it:</p>
<pre><code class="lang-js">afterAll(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">await</span> dropAllCollections();
  <span class="hljs-comment">// Closes the Mongoose connection</span>
  <span class="hljs-keyword">await</span> mongoose.connection.close();
});
</code></pre>
<p>That's everything you need to do to setup Mongoose with Jest!</p>
<h3 id="heading-refactoring">Refactoring</h3>
<p>There's a lot of code that goes into <code>beforeEach</code>, <code>afterEach</code>, and <code>afterAll</code> hooks. We will be using them for every test file. It makes sense to create a setup file for these hooks.</p>
<pre><code class="lang-js"><span class="hljs-comment">// test-setup.js</span>
<span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mongoose"</span>);
mongoose.set(<span class="hljs-string">"useCreateIndex"</span>, <span class="hljs-literal">true</span>);
mongoose.promise = <span class="hljs-built_in">global</span>.Promise;

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">removeAllCollections</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> collections = <span class="hljs-built_in">Object</span>.keys(mongoose.connection.collections);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> collectionName <span class="hljs-keyword">of</span> collections) {
    <span class="hljs-keyword">const</span> collection = mongoose.connection.collections[collectionName];
    <span class="hljs-keyword">await</span> collection.deleteMany();
  }
}

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dropAllCollections</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> collections = <span class="hljs-built_in">Object</span>.keys(mongoose.connection.collections);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> collectionName <span class="hljs-keyword">of</span> collections) {
    <span class="hljs-keyword">const</span> collection = mongoose.connection.collections[collectionName];
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> collection.drop();
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-comment">// Sometimes this error happens, but you can safely ignore it</span>
      <span class="hljs-keyword">if</span> (error.message === <span class="hljs-string">"ns not found"</span>) <span class="hljs-keyword">return</span>;
      <span class="hljs-comment">// This error occurs when you use it.todo. You can</span>
      <span class="hljs-comment">// safely ignore this error too</span>
      <span class="hljs-keyword">if</span> (error.message.includes(<span class="hljs-string">"a background operation is currently running"</span>))
        <span class="hljs-keyword">return</span>;
      <span class="hljs-built_in">console</span>.log(error.message);
    }
  }
}

<span class="hljs-built_in">module</span>.exports = {
  setupDB(databaseName) {
    <span class="hljs-comment">// Connect to Mongoose</span>
    beforeAll(<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">const</span> url = <span class="hljs-string">`mongodb://127.0.0.1/<span class="hljs-subst">${databaseName}</span>`</span>;
      <span class="hljs-keyword">await</span> mongoose.connect(url, { <span class="hljs-attr">useNewUrlParser</span>: <span class="hljs-literal">true</span> });
    });

    <span class="hljs-comment">// Cleans up database between each test</span>
    afterEach(<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">await</span> removeAllCollections();
    });

    <span class="hljs-comment">// Disconnect Mongoose</span>
    afterAll(<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">await</span> dropAllCollections();
      <span class="hljs-keyword">await</span> mongoose.connection.close();
    });
  }
};
</code></pre>
<p>You can import the setup file for each test like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { setupDB } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../test-setup"</span>);

<span class="hljs-comment">// Setup a Test Database</span>
setupDB(<span class="hljs-string">"endpoint-testing"</span>);

<span class="hljs-comment">// Continue with your tests...</span>
</code></pre>
<p>There's one more thing I want to show you.</p>
<p>When you create tests, you want to seed the database with fake data.</p>
<h3 id="part3">Seeding a database</h3>

<p>When you write tests for the backend, you need to test for four different kinds of operations:</p>
<ol>
<li>Create (for adding things to the database)</li>
<li>Read (for getting things from the database)</li>
<li>Update (for changing the database)</li>
<li>Delete (for deleting things from the database)</li>
</ol>
<p>The easiest type to test for is create operations. You put something into the database and test whether it's there.</p>
<p>For the other three types of operations, you need to put something into the database <em>before</em> you write the test.</p>
<h3 id="heading-putting-things-into-the-database">Putting things into the database</h3>
<p>The process where you add things to a database is called <strong>seeding a database</strong>.</p>
<p>Let's say you want to add three users to the database. These users contain a name and an email address.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> users = [
  {
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Zell"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"testing1@gmail.com"</span>
  },
  {
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Vincy"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"testing2@gmail.com"</span>
  },
  {
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Shion"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"testing3@gmail.com"</span>
  }
];
</code></pre>
<p>You can use your models to seed the database at the start of the test.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/User"</span>); <span class="hljs-comment">// Link to User model</span>

it(<span class="hljs-string">"does something"</span>, <span class="hljs-keyword">async</span> done =&gt; {
  <span class="hljs-comment">// Add users to the database</span>
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> u <span class="hljs-keyword">of</span> users) {
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">new</span> User(u);
    <span class="hljs-keyword">await</span> user.save();
  }

  <span class="hljs-comment">// Create the rest of your test here</span>
});
</code></pre>
<p>If you need these users for every test, the best way is to add them through the <code>beforeEach</code> hook. The <code>beforeEach</code> hook runs before every <code>it</code> declaration.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Seed the database with users</span>
beforeEach(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">for</span> (u <span class="hljs-keyword">of</span> users) {
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">new</span> User(u);
    <span class="hljs-keyword">await</span> user.save();
  }
});
</code></pre>
<p>You can also use Mongoose's <code>create</code> function to do the same thing. It runs <code>new Model()</code> and <code>save()</code>, so the code below and the one above does the same thing.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Seed the database with users</span>
beforeEach(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">await</span> User.create(users);
});
</code></pre>
<h3 id="heading-create-vs-insertmany">create vs insertMany</h3>
<p>Mongoose has a second method to help you seed the database. This method is called <code>insertMany</code>. <code>insertMany</code> is faster than <code>create</code>, because:</p>
<ul>
<li><code>insertMany</code> sends one operation to the server</li>
<li><code>create</code> sends one operation for each document</li>
</ul>
<p>However, <code>insertMany</code> does not run the <code>save</code> middleware.</p>
<h4 id="heading-is-triggering-the-save-middleware-important">Is triggering the save middleware important?</h4>
<p>This depends on your seed data. If your seed data needs to go through the <code>save</code> middleware, you need to use <code>create</code>. For example, let's say you want to save a user's password into the database. You have this data:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> users = [
  {
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Zell"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"testing1@gmail.com"</span>,
    <span class="hljs-attr">password</span>: <span class="hljs-string">"12345678"</span>
  },
  {
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Vincy"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"testing2@gmail.com"</span>,
    <span class="hljs-attr">password</span>: <span class="hljs-string">"12345678"</span>
  },
  {
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Shion"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"testing3@gmail.com"</span>,
    <span class="hljs-attr">password</span>: <span class="hljs-string">"12345678"</span>
  }
];
</code></pre>
<p>When we save a user's password into the database, we want to hash the password for security reasons. We usually hash the password through the <code>save</code> middleware.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Hashes password automatically</span>
userSchema.pre(<span class="hljs-string">"save"</span>, <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">next</span>) </span>{
  <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isModified(<span class="hljs-string">"password"</span>)) <span class="hljs-keyword">return</span> next();
  <span class="hljs-keyword">const</span> salt = bcrypt.genSaltSync(<span class="hljs-number">10</span>);
  <span class="hljs-keyword">const</span> hashedPassword = bcrypt.hashSync(password, salt);
  <span class="hljs-built_in">this</span>.password = hashedPassword;
});
</code></pre>
<p>If you use <code>create</code>, you'll get users with hashed passwords:</p>
<figure><img src="https://zellwk.com/images/2019/seed-database/create.png" alt="Create runs the save middleware." width="600" height="400" loading="lazy"></figure>

<p>If you use <code>insertMany</code>, you'll get users without hashed passwords:</p>
<figure><img src="https://zellwk.com/images/2019/seed-database/insert-many.png" alt="InsertMany does not run the save middleware." width="600" height="400" loading="lazy"></figure>

<h3 id="heading-when-to-use-create-when-to-use-insertmany">When to use create, when to use insertMany</h3>
<p>Since <code>insertMany</code> is faster than <code>create</code>, you want to use <code>insertMany</code> whenever you can.</p>
<p>Here's how I do it:</p>
<ol>
<li>If seed data does not require the <code>save</code> middleware, use <code>insertMany</code>.</li>
<li>If seed data requires <code>save</code> middleware, use <code>create</code>. Then, overwrite seed data so it no longer requires the <code>save</code> middleware.</li>
</ol>
<p>For the password example above, I would run <code>create</code> first. Then, I copy-paste the hashed password seed data. Then, I'll run <code>insertMany</code> from this point onwards.</p>
<p>If you want to overwrite complicated seed data, you might want to get JSON straight from MongoDB. To do this, you can use <code>mongoexport</code>:</p>
<pre><code class="lang-js">mongoexport --db &lt;databaseName&gt; --collection &lt;collectionName&gt; --jsonArray --pretty --out output.json
</code></pre>
<p>This says:</p>
<ol>
<li>Export <code>&lt;collection&gt;</code> from <code>&lt;databaseName&gt;</code></li>
<li>Creates output as a JSON Array, prettified, in a file called <code>output.json</code>. This file will be placed in the folder where you run the command.</li>
</ol>
<h3 id="heading-seeding-multiple-test-files-and-collections">Seeding multiple test files and collections</h3>
<p>You want a place to store your seed data so you can use them across all your tests and collections. Here's a system I use:</p>
<ol>
<li>I name my seed files according to their models. I seed a <code>User</code> model with the <code>user.seed.js</code> file.</li>
<li>I put my seed files in the <code>seeds</code> folder</li>
<li>I loop through each seed file to seed the database.</li>
</ol>
<p>To loop through each seed file, you need to use the <code>fs</code> module. <code>fs</code> stands for filesystem.</p>
<p>The easiest way to loop through the files is to create an <code>index.js</code> file in the same <code>seeds</code> folder. Once you have the <code>index.js</code> file, you can use the following code to look for all files with <code>*.seed.js</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">"fs"</span>);
<span class="hljs-keyword">const</span> util = <span class="hljs-built_in">require</span>(<span class="hljs-string">"util"</span>);

<span class="hljs-comment">// fs.readdir is written with callbacks.</span>
<span class="hljs-comment">// This line converts fs.readdir into a promise</span>
<span class="hljs-keyword">const</span> readDir = util.promisify(fs.readdir);

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">seedDatabase</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Gets list of files in the directory</span>
  <span class="hljs-comment">// `__dirname` points to the `seeds/` folder</span>
  <span class="hljs-keyword">const</span> dir = <span class="hljs-keyword">await</span> readDir(__dirname);

  <span class="hljs-comment">// Gets a list of files that matches *.seed.js</span>
  <span class="hljs-keyword">const</span> seedFiles = dir.filter(<span class="hljs-function"><span class="hljs-params">f</span> =&gt;</span> f.endsWith(<span class="hljs-string">".seed.js"</span>));
}
</code></pre>
<p>Once you have a list of seed files, you can loop through each seed file to seed the database. Here, I use a <code>for...of</code> loop to keep things simple.</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">seedDatabase</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> file <span class="hljs-keyword">of</span> seedFiles) {
    <span class="hljs-comment">// Seed the database</span>
  }
}
</code></pre>
<p>To seed the database, we need to find the correct Mongoose model from the name of the seed file. A file called <code>user.seed.js</code> should seed the <code>User</code> model. This means:</p>
<ol>
<li>We must find <code>user</code> from <code>user.seed.js</code></li>
<li>We must capitalize <code>user</code> into <code>User</code></li>
</ol>
<p>Here's a crude version that does what's required. (If you want to, you can make the code more robust with regex instead of <code>split</code>).</p>
<pre><code class="lang-js"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> file <span class="hljs-keyword">of</span> seedFiles) {
  <span class="hljs-keyword">const</span> fileName = file.split(<span class="hljs-string">".seed.js"</span>)[<span class="hljs-number">0</span>];
  <span class="hljs-keyword">const</span> modelName = toTitleCase(fileName);
  <span class="hljs-keyword">const</span> model = mongoose.models[modelName];
}
</code></pre>
<p>Next, we want to make sure each file has a Model that corresponds to it. If the model cannot be found, we want to throw an error.</p>
<pre><code class="lang-js"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> file <span class="hljs-keyword">of</span> seedFiles) {
  <span class="hljs-comment">//...</span>
  <span class="hljs-keyword">if</span> (!model) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`Cannot find Model '<span class="hljs-subst">${modelName}</span>'`</span>);
}
</code></pre>
<p>If there's a corresponding model, we want to seed the database with the contents in the seed file. To do this, we need to read the seed file first. Here, since I used the <code>.js</code> extension, I can simply require the file.</p>
<pre><code class="lang-js"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> file <span class="hljs-keyword">of</span> seedFiles) {
  <span class="hljs-comment">//...</span>
  <span class="hljs-keyword">const</span> fileContents = <span class="hljs-built_in">require</span>(path.join(__dirname, file));
}
</code></pre>
<p>For this to work, my seed files must export an array of data.</p>
<pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = [
  {
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Zell"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"testing1@gmail.com"</span>,
    <span class="hljs-attr">password</span>: <span class="hljs-string">"12345678"</span>
  },
  {
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Vincy"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"testing2@gmail.com"</span>,
    <span class="hljs-attr">password</span>: <span class="hljs-string">"12345678"</span>
  },
  {
    <span class="hljs-attr">name</span>: <span class="hljs-string">"Shion"</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-string">"testing3@gmail.com"</span>,
    <span class="hljs-attr">password</span>: <span class="hljs-string">"12345678"</span>
  }
];
</code></pre>
<p>Once I have the contents of the seed file, I can run <code>create</code> or <code>insertMany</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">seedDatabase</span>(<span class="hljs-params">runSaveMiddleware = false</span>) </span>{
  <span class="hljs-comment">// ...</span>
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> file <span class="hljs-keyword">of</span> seedFiles) {
    <span class="hljs-comment">// ...</span>

    runSaveMiddleware
      ? model.create(fileContents)
      : model.insertMany(fileContents);
  }
}
</code></pre>
<p>Here's the whole <code>seedDatabase</code> code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">"fs"</span>);
<span class="hljs-keyword">const</span> util = <span class="hljs-built_in">require</span>(<span class="hljs-string">"util"</span>);
<span class="hljs-keyword">const</span> readDir = util.promisify(fs.readdir).bind(fs);
<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);
<span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mongoose"</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toTitleCase</span>(<span class="hljs-params">str</span>) </span>{
  <span class="hljs-keyword">return</span> str.replace(<span class="hljs-regexp">/\w\S*/g</span>, <span class="hljs-function"><span class="hljs-params">txt</span> =&gt;</span> {
    <span class="hljs-keyword">return</span> txt.charAt(<span class="hljs-number">0</span>).toUpperCase() + txt.substr(<span class="hljs-number">1</span>).toLowerCase();
  });
}

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">seedDatabase</span>(<span class="hljs-params">runSaveMiddleware = false</span>) </span>{
  <span class="hljs-keyword">const</span> dir = <span class="hljs-keyword">await</span> readDir(__dirname);
  <span class="hljs-keyword">const</span> seedFiles = dir.filter(<span class="hljs-function"><span class="hljs-params">f</span> =&gt;</span> f.endsWith(<span class="hljs-string">".seed.js"</span>));

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> file <span class="hljs-keyword">of</span> seedFiles) {
    <span class="hljs-keyword">const</span> fileName = file.split(<span class="hljs-string">".seed.js"</span>)[<span class="hljs-number">0</span>];
    <span class="hljs-keyword">const</span> modelName = toTitleCase(fileName);
    <span class="hljs-keyword">const</span> model = mongoose.models[modelName];

    <span class="hljs-keyword">if</span> (!model) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`Cannot find Model '<span class="hljs-subst">${modelName}</span>'`</span>);
    <span class="hljs-keyword">const</span> fileContents = <span class="hljs-built_in">require</span>(path.join(__dirname, file));

    runSaveMiddleware
      ? <span class="hljs-keyword">await</span> model.create(fileContents)
      : <span class="hljs-keyword">await</span> model.insertMany(fileContents);
  }
}
</code></pre>
<h3 id="heading-why-js-not-json">Why JS, not JSON?</h3>
<p>It's the industry norm to use JSON to store data. In this case, I find it easier to use JavaScript objects because:</p>
<ol>
<li>I don't have to write opening and closing double-quotes for each property.</li>
<li>I don't have to use double-quotes at all! (It's easier to write single-quotes because there's no need to press the shift key).</li>
</ol>
<pre><code class="lang-js"><span class="hljs-comment">// Which is easier to write. JavaScript objects or JSON?</span>

<span class="hljs-comment">// JavaScript objects</span>
<span class="hljs-built_in">module</span>.exports = [
  {
    <span class="hljs-attr">objectName</span>: <span class="hljs-string">"property"</span>
  }
][
  <span class="hljs-comment">// JSON</span>
  {
    <span class="hljs-attr">objectName</span>: <span class="hljs-string">"property"</span>
  }
];
</code></pre>
<p>If you want to use JSON, make sure you change <code>seedDatabase</code> to work with JSON. (I'll let you work through the code yourself).</p>
<h2 id="heading-adjusting-the-setupdb-function">Adjusting the setupDB function</h2>
<p>Earlier, I created a <code>setupDB</code> function to help set up databases for my tests. <code>seedDatabase</code> goes into the <code>setupDB</code> function since seeding is part of the setting up process.</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">seedDatabase</span>(<span class="hljs-params">runSaveMiddleware = false</span>) </span>{
  <span class="hljs-comment">// ...</span>
}

<span class="hljs-built_in">module</span>.exports = {
  setupDB(databaseName, runSaveMiddleware = <span class="hljs-literal">false</span>) {
    <span class="hljs-comment">// Connect to Mongoose</span>
    beforeAll(<span class="hljs-comment">/*...*/</span>);

    <span class="hljs-comment">// Seed Data</span>
    beforeEach(<span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">await</span> seedDatabase(runSaveMiddleware);
    });

    <span class="hljs-comment">// Cleans up database between each test</span>
    afterEach(<span class="hljs-comment">/*...*/</span>);

    <span class="hljs-comment">// Disconnect Mongoose</span>
    afterAll(<span class="hljs-comment">/*...*/</span>);
  }
};
</code></pre>
<h3 id="heading-a-github-repository">A Github Repository</h3>
<p>I created a <a target="_blank" href="https://github.com/zellwk/endpoint-testing-example">Github repository</a> to go with this article. I hope this demo code helps you start testing your applications.</p>
<hr>

<p>Thanks for reading. This article was originally posted on <a target="_blank" href="https://zellwk.com/blog/endpoint-testing">my blog</a>. Sign up for <a target="_blank" href="https://zellwk.com">my newsletter</a> if you want more articles to help you become a better frontend developer.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to choose which validator to use: a comparison between Joi & express-validator ]]>
                </title>
                <description>
                    <![CDATA[ By Shailesh Shekhawat Imagine you have an e-commerce website and you’re allowing users to create accounts using their name and email. You want to make sure they sign up with real names, not something like cool_dud3. That's where we use validation to ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-choose-which-validator-to-use-a-comparison-between-joi-express-validator-ac0b910c1a8c/</link>
                <guid isPermaLink="false">66d4614e7df3a1f32ee7f8aa</guid>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 09 May 2019 16:28:17 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*s3Fzn57ud8r82T56w9biWg.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Shailesh Shekhawat</p>
<p>Imagine you have an e-commerce website and you’re allowing users to create accounts using their name and email. You want to make sure they sign up with real names, not something like cool_dud3.</p>
<p>That's where we use validation to validate inputs and make sure input data follows certain rules.</p>
<p>In the market, we already have a bunch of validation libraries, but I will compare two important validation libraries: <a target="_blank" href="https://github.com/hapijs/joi">Joi</a> and <a target="_blank" href="https://github.com/express-validator/express-validator">express-validator</a> for <strong>express.js based applications</strong>.</p>
<p>This comparison is useful when you have decided to use external input validation library for your application built on <strong>expressjs</strong> and are somewhat not sure which one to use.</p>
<h3 id="heading-who-is-what">Who is what?</h3>
<h4 id="heading-joi">Joi</h4>
<p>Joi allows you to create <em>blueprints</em> or <em>schemas</em> for JavaScript objects (an object that stores information) to ensure <em>validation</em> of key information.</p>
<h4 id="heading-express-validator">Express-validator</h4>
<p><em>express-validator</em> is a set of <a target="_blank" href="http://expressjs.com/">express.js</a> middlewares that wraps <a target="_blank" href="https://github.com/chriso/validator.js">validator.js</a> validator and sanitizer functions.</p>
<p>So by definition, we can say that:</p>
<ul>
<li>Joi can be used for creating schemas (just like we use mongoose for creating NoSQL schemas) and you can use it with plain Javascript objects. It's like a plug n play library and is easy to use.</li>
<li>On the other hand, <em>express-validator</em> uses <a target="_blank" href="https://github.com/chriso/validator.js">validator.js</a> to validate expressjs routes, and it's mainly built for express.js applications. This makes this library more niche and provides out of box custom validation and sanitization. Also, I find it easy to understand personally :)</li>
</ul>
<p>Too many methods and API's for doing certain validation in Joi might make you feel overwhelmed so you might end up closing the tab.</p>
<p>But I may be wrong — so let’s keep opinions aside and compare both libraries.</p>
<h3 id="heading-instantiation">Instantiation</h3>
<h4 id="heading-joi-1">Joi</h4>
<p>In Joi<em>,</em> you need to use <code>**Joi.object()**</code> to instantiate a Joi schema object to work with.</p>
<p>All schemas require <code>Joi.object()</code>to process validation and other Joi features.</p>
<p>You need to separately read <code>req.body</code> , <code>req.params</code> , <code>req.query</code> to request body, params, and query.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Joi = <span class="hljs-built_in">require</span>(<span class="hljs-string">'joi'</span>);

<span class="hljs-keyword">const</span> schema = Joi.object().keys({
   <span class="hljs-comment">// validate fields here</span>
})
</code></pre>
<h4 id="heading-express-validator-1">Express-validator</h4>
<p>You can just require <em>express-validator</em> and start using its methods. You don't need to read values from <code>req.body</code> , <code>req.params</code> , and <code>req.query</code> separately.</p>
<p>You just need to use the <code>param, query, body</code> methods below to validate inputs respectively as you can see here:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> {
  param, query, cookies, header 
  body, validationResult } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-validator/check'</span>)

app.post(<span class="hljs-string">'/user'</span>, [   

<span class="hljs-comment">// validate fields here</span>

], <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
<span class="hljs-keyword">const</span> errors = validationResult(req);

  <span class="hljs-keyword">if</span> (!errors.isEmpty()) {     
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">422</span>).json({ <span class="hljs-attr">errors</span>: errors.array() });   
  }
}
</code></pre>
<h4 id="heading-field-is-required">Field is required</h4>
<p>Let’s take a very basic example where we want to make sure that a <code>username</code> should be required <code>string</code> and is <code>alphaNumeric</code> with <code>min</code> and <code>max</code> characters.</p>
<ul>
<li><strong>Joi:</strong></li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Joi = <span class="hljs-built_in">require</span>(<span class="hljs-string">'joi'</span>);
<span class="hljs-keyword">const</span> schema = Joi.object().keys({
    <span class="hljs-attr">username</span>: Joi.string().alphanum().min(<span class="hljs-number">3</span>).max(<span class="hljs-number">30</span>).required()
})

app.post(<span class="hljs-string">'/user'</span>, <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {   
  <span class="hljs-keyword">const</span> result = Joi.validate(req.body, schema)
  <span class="hljs-keyword">if</span> (result.error) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">error</span>: result.error });
  }
});
</code></pre>
<ul>
<li><strong>Express-validator</strong></li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { body, validationResult } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-validator/check'</span>)

app.post(<span class="hljs-string">'/user'</span>, [   
 body(<span class="hljs-string">'username'</span>)
  .isString()
  .isAlphanumeric()
  .isLength({<span class="hljs-attr">min</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">max</span>: <span class="hljs-number">30</span>})
  .exists(), 
], <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> errors = validationResult(req);

  <span class="hljs-keyword">if</span> (!errors.isEmpty()) {     
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">422</span>).json({ <span class="hljs-attr">errors</span>: errors.array() });   
  }
}
</code></pre>
<h3 id="heading-sanitization">Sanitization</h3>
<p>Sanitization is basically checking input to make sure it's free of noise, for example, we all have used <code>.trim()</code> on string to remove spaces.</p>
<p>Or if you have faced a situation where a number is coming in as <code>"1"</code> so in those cases, we want to sanitize and convert the type during runtime.</p>
<p>Sadly, Joi doesn’t provide sanitization out of the box but <em>express-validator</em> does.</p>
<h4 id="heading-example-converting-to-mongodbs-objectid">Example: converting to MongoDB’s ObjectID</h4>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { sanitizeParam } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-validator/filter'</span>);  

app.post(<span class="hljs-string">'/object/:id'</span>,  
   sanitizeParam(<span class="hljs-string">'id'</span>)
  .customSanitizer(<span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> {
     <span class="hljs-keyword">return</span> ObjectId(value); 
}), <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {   <span class="hljs-comment">// Handle the request });</span>
</code></pre>
<h3 id="heading-custom-validation">Custom Validation</h3>
<h4 id="heading-joi-extendextension">Joi: <strong>.extend(</strong><code>extension</code><strong>)</strong></h4>
<p>This creates a new Joi instance customized with the extension(s) you provide included.</p>
<p>The extension makes use of some common structures that need to be described first:</p>
<ul>
<li><code>value</code> - the value being processed by Joi.</li>
<li><code>state</code> - an object containing the current context of validation.</li>
<li><code>key</code> - the key of the current value.</li>
<li><code>path</code> - the full path of the current value.</li>
<li><code>parent</code> - the potential parent of the current value.</li>
<li><code>options</code> - options object provided through <code>[any().options()](https://github.com/hapijs/joi/blob/master/API.md#anyoptionsoptions)</code> or <code>[Joi.validate()](https://github.com/hapijs/joi/blob/master/API.md#validatevalue-schema-options-callback)</code>.</li>
</ul>
<h4 id="heading-extension">Extension</h4>
<p><code>extension</code> can be:</p>
<ul>
<li>a single extension object</li>
<li>a factory function generating an extension object</li>
<li>or an array of those</li>
</ul>
<p>Extension objects use the following parameters:</p>
<ul>
<li><code>name</code> - name of the new type you are defining, this can be an existing type. Required.</li>
<li><code>base</code> - an existing Joi schema to base your type on. Defaults to <code>Joi.any()</code>.</li>
<li><code>coerce</code> - an optional function that runs before the base, usually serves when you want to coerce values of a different type than your base. It takes 3 arguments <code>value</code>, <code>state</code> and <code>options</code>.</li>
<li><code>pre</code> - an optional function that runs first in the validation chain, usually serves when you need to cast values. It takes 3 arguments <code>value</code>, <code>state</code> and <code>options</code>.</li>
<li><code>language</code> - an optional object to add error definitions. Every key will be prefixed by the type name.</li>
<li><code>describe</code> - an optional function taking the fully formed description to post-process it.</li>
<li><code>rules</code> - an optional array of rules to add.</li>
<li><code>name</code> - name of the new rule. Required.</li>
<li><code>params</code> - an optional object containing Joi schemas of each parameter ordered. You can also pass a single Joi schema as long as it is a <code>Joi.object()</code>. Of course some methods such as <code>pattern</code> or <code>rename</code> won't be useful or won't work at all in this given context.</li>
<li><code>setup</code> - an optional function that takes an object with the provided parameters to allow for internal manipulation of the schema when a rule is set. You can optionally return a new Joi schema that will be taken as the new schema instance. At least one of either <code>setup</code> or <code>validate</code> must be provided.</li>
<li><code>validate</code> - an optional function to validate values that takes 4 parameters <code>params</code>, <code>value</code>, <code>state</code> and <code>options</code>. At least one of <code>setup</code> or <code>validate</code> must be provided.</li>
<li><code>description</code> - an optional string or function taking the parameters as an argument to describe what the rule is doing.</li>
</ul>
<p><strong>Example</strong>:</p>
<pre><code class="lang-js">joi.extend(<span class="hljs-function">(<span class="hljs-params">joi</span>) =&gt;</span> ({
    <span class="hljs-attr">base</span>: joi.object().keys({
        <span class="hljs-attr">name</span>: joi.string(),
        <span class="hljs-attr">age</span>: joi.number(),
        <span class="hljs-attr">adult</span>: joi.bool().optional(),
    }),
    <span class="hljs-attr">name</span>: <span class="hljs-string">'person'</span>,
    <span class="hljs-attr">language</span>: {
        <span class="hljs-attr">adult</span>: <span class="hljs-string">'needs to be an adult'</span>,
    },
<span class="hljs-attr">rules</span>: [
        {
            <span class="hljs-attr">name</span>: <span class="hljs-string">'adult'</span>,
            validate(params, value, state, options) {

                <span class="hljs-keyword">if</span> (!value.adult) {
                    <span class="hljs-comment">// Generate an error, state and options need to be passed</span>
                    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.createError(<span class="hljs-string">'person.adult'</span>, {}, state, options);
                }

                <span class="hljs-keyword">return</span> value; <span class="hljs-comment">// Everything is OK</span>
            }
        }
    ]
})
</code></pre>
<h4 id="heading-express-validator-2">Express-validator</h4>
<p>A custom validator may be implemented by using the chain method <code>[.custom()](https://express-validator.github.io/docs/validation-chain-api.html#customvalidator)</code>. It takes a validator function.</p>
<p>Custom validators may return Promises to indicate an async validation (which will be awaited upon), or <code>throw</code> any value/reject a promise to <a target="_blank" href="https://express-validator.github.io/docs/custom-error-messages.html#custom-validator-level">use a custom error message</a>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> {
  param, query, cookies, header 
  body, validationResult } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-validator/check'</span>)

app.get(<span class="hljs-string">'/user/:userId'</span>, [   
 param(<span class="hljs-string">'userId'</span>)
  .exists()
  .isMongoId()
  .custom(<span class="hljs-function"><span class="hljs-params">val</span> =&gt;</span> UserSchema.isValidUser(val)), 
], <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {

<span class="hljs-keyword">const</span> errors = validationResult(req);

  <span class="hljs-keyword">if</span> (!errors.isEmpty()) {     
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">422</span>).json({ <span class="hljs-attr">errors</span>: errors.array() });   
  }
}
</code></pre>
<h3 id="heading-conditional-validation">Conditional Validation</h3>
<p><em>express-validator</em> does not support conditional validation as of now, but there is a PR for that already you can check <a target="_blank" href="https://github.com/express-validator/express-validator/pull/658">https://github.com/express-validator/express-validator/pull/658</a></p>
<p>Let’s see how it works in Joi:</p>
<h4 id="heading-anywhencondition-options"><code>any.when(condition, options)</code></h4>
<p><code>**any:**</code> Generates a schema object that matches any data type.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> schema = Joi.object({
    <span class="hljs-attr">a</span>: Joi.any().valid(<span class="hljs-string">'x'</span>),
    <span class="hljs-attr">b</span>: Joi.any()
}).when(
    Joi.object({ <span class="hljs-attr">b</span>: Joi.exist() })
    .unknown(), {
    <span class="hljs-attr">then</span>: Joi.object({
        <span class="hljs-attr">a</span>: Joi.valid(<span class="hljs-string">'y'</span>)
    }),
    <span class="hljs-attr">otherwise</span>: Joi.object({
        <span class="hljs-attr">a</span>: Joi.valid(<span class="hljs-string">'z'</span>)
    })
});
</code></pre>
<h4 id="heading-alternativeswhencondition-options"><code>alternatives.when(condition, options)</code></h4>
<p>Adds a conditional alternative schema type, either based on another key (not the same as <code>any.when()</code>) value, or a schema peeking into the current value, where:</p>
<ul>
<li><code>condition</code> - the key name or <a target="_blank" href="https://github.com/hapijs/joi/blob/master/API.md#refkey-options">reference</a>, or a schema.</li>
<li><code>options</code> - an object with:</li>
<li><code>is</code> - the required condition joi type. Forbidden when <code>condition</code> is a schema.</li>
<li><code>then</code> - the alternative schema type to try if the condition is true. Required if <code>otherwise</code> is missing.</li>
<li><code>otherwise</code> - the alternative schema type to try if the condition is false. Required if <code>then</code> is missing.</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> schema = Joi
     .alternatives()
     .when(Joi.object({ <span class="hljs-attr">b</span>: <span class="hljs-number">5</span> }).unknown(), {
        <span class="hljs-attr">then</span>: Joi.object({
           <span class="hljs-attr">a</span>: Joi.string(),
           <span class="hljs-attr">b</span>: Joi.any()
      }),
      <span class="hljs-attr">otherwise</span>: Joi.object({
        <span class="hljs-attr">a</span>: Joi.number(),
        <span class="hljs-attr">b</span>: Joi.any()
      })
});
</code></pre>
<h3 id="heading-nested-validation">Nested Validation</h3>
<p>When you want to validate an array of objects/items or just object keys</p>
<p>Both libraries support nested validation</p>
<p>Now what about express-validator?</p>
<h4 id="heading-wildcards">Wildcards</h4>
<p>Wildcards allow you to iterate over an array of items or object keys and validate each item or its properties.</p>
<p>The <code>*</code> character is also known as a wildcard.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>); 
<span class="hljs-keyword">const</span> { check } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-validator/check'</span>); 
<span class="hljs-keyword">const</span> { sanitize } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-validator/filter'</span>);  
<span class="hljs-keyword">const</span> app = express(); 

app.use(express.json());  
app.post(<span class="hljs-string">'/addresses'</span>, [   
    check(<span class="hljs-string">'addresses.*.postalCode'</span>).isPostalCode(),
    sanitize(<span class="hljs-string">'addresses.*.number'</span>).toInt() 
], 
<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {   <span class="hljs-comment">// Handle the request });</span>
</code></pre>
<p><strong>Joi</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> schema = Joi.object().keys({
    <span class="hljs-attr">addresses</span>: Joi.array().items(
        Joi.object().keys({
            <span class="hljs-attr">postalCode</span>: Joi.string().required(),
        }),
    )
});
</code></pre>
<h3 id="heading-custom-error-messages">Custom Error Messages</h3>
<h4 id="heading-joi-2">Joi</h4>
<h4 id="heading-anyerrorerr-options"><code>any.error(err, [options])</code></h4>
<p>Overrides the default joi error with a custom error</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> schema = Joi.string().error(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Was REALLY expecting a string'</span>));
</code></pre>
<h4 id="heading-express-validator-3">Express-validator</h4>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { check } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-validator/check'</span>); 

app.post(<span class="hljs-string">'/user'</span>, [   
   <span class="hljs-comment">// ...some other validations...   </span>
   check(<span class="hljs-string">'password'</span>)     
   .isLength({ <span class="hljs-attr">min</span>: <span class="hljs-number">5</span> }).withMessage(<span class="hljs-string">'must be at 5 chars long'</span>)
   .matches(<span class="hljs-regexp">/\d/</span>).withMessage(<span class="hljs-string">'must contain a number'</span>) 
], 
<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {   <span class="hljs-comment">// Handle the request somehow });</span>
</code></pre>
<h3 id="heading-conclusion">Conclusion</h3>
<p>I covered the most important parts of both libraries and you can decide yourself which one you want to use. Please let me know in the comments below if I left out anything important in the comparison.</p>
<p>I hope you find it helpful when deciding the next input validation module for your express.js application.</p>
<p>I wrote an in-depth article on it here: <a target="_blank" href="https://medium.freecodecamp.org/how-to-make-input-validation-simple-and-clean-in-your-express-js-app-ea9b5ff5a8a7">how to validate inputs</a>. Do check it out.</p>
<p><em>Don’t hesitate to clap if you considered this a worthwhile read!</em></p>
<p><em>Originally published at <a target="_blank" href="https://101node.io/blog/javascript-validators-comparison-using-joi-vs-express-validator/">101node.io</a> on March 31, 2019.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Express.js in this complete course ]]>
                </title>
                <description>
                    <![CDATA[ In this full Express.js course from Buzz Team, you will learn how to develop a web app from scratch using Node.js, Express.js, PostgreSQL, and Bootstrap. The web app is a full CRUD application that is used for collecting sales leads.   This course is... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-express-js-in-this-complete-course/</link>
                <guid isPermaLink="false">66b20444a2135cc2539a21b6</guid>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Tue, 12 Feb 2019 19:57:49 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/ghost/2019/02/nodeexpress.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this full Express.js course from Buzz Team, you will learn how to develop a web app from scratch using Node.js, Express.js, PostgreSQL, and Bootstrap. The web app is a full CRUD application that is used for collecting sales leads.  </p>
<p>This course is the perfect way to become familiar with Express.js and how to use it with Node.js. Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.</p>
<p>The code from this project is a good starting place for you to develop your own project.</p>
<p>You can watch the full video on the <a target="_blank" href="https://www.youtube.com/watch?v=G8uL0lFFoN0">freeCodeCamp.org YouTube channel</a> (2.5 hour watch).</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to deploy a React app with an Express server on Heroku ]]>
                </title>
                <description>
                    <![CDATA[ By Ashish Nandan Singh Hello, world! Recently I had to deploy a website to Heroku for one of the pieces of freelance work I was doing. I think this process may be somewhat difficult, and a detailed tutorial or article on how to do this should help. S... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-deploy-a-react-app-with-an-express-server-on-heroku-32244fe5a250/</link>
                <guid isPermaLink="false">66c3517df41767c3c96bad17</guid>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Heroku ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 18 Dec 2018 21:35:14 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*j8DELPVuI_w8045sxmHQsA.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ashish Nandan Singh</p>
<p>Hello, world! Recently I had to deploy a website to Heroku for one of the pieces of freelance work I was doing. I think this process may be somewhat difficult, and a detailed tutorial or article on how to do this should help. So this one is going to be very simple and hopefully very short.</p>
<p>We will start by creating an Express app, which will act as our server. Once the server is done, we will create a simple create-react-app application, connect the server with the frontend and, finally, deploy the whole thing to a hosting platform such as Heroku.</p>
<p>Before we go any further, I want you to understand that in the world of web development almost everything is up to one’s preference. Some of you may disagree on certain things, you may continue the way you want to do things, and that’s totally fine. Up to the point when we’re breaking the application I consider everything to be fine.</p>
<p>Let’s get started.</p>
<h3 id="heading-create-a-nodeexpress-app">Create a Node/Express app</h3>
<p>Start by creating a folder for the overall project. This folder will contain the client side application — our React app in this case. Navigate to the directory in your terminal and type the commands below.</p>
<pre><code>$ touch server.js$ npm init
</code></pre><p>The last command from the above snippet will take you through some of the steps and will initialise your project with a <code>package.json</code> file. If you are totally new to this, you can consider this file to be a ledger where you keep the record of all the dependencies you’ll be using across the build process of your application.</p>
<p>Moving on, now that we have the <code>package.json</code> file ready, we can start by adding our dependency for the project.</p>
<p>Adding Express:</p>
<pre><code>$ npm i -g express --save
</code></pre><p>This will add Express as a dependency to your package.json. Now that we have this, all we need is one more dependency and that is for hot reloading of the app whenever we make some change to the code:</p>
<pre><code>$ npm i -g nodemon --save --dev
</code></pre><p>This will add nodemon to the app. If you would like to read more about nodemon, you can check <a target="_blank" href="https://nodemon.io/">this</a> link for more information.</p>
<p>Now that we have these added, we are all set to create our most basic server in Express. Let’s see how that’s done.</p>
<pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);<span class="hljs-keyword">const</span> app = express();<span class="hljs-keyword">const</span> port = process.env.PORT || <span class="hljs-number">5000</span>;
</code></pre><pre><code><span class="hljs-comment">//Route setupapp.get('/', (req, res) =&gt; {    res.send('root route');</span>
</code></pre><pre><code>})
</code></pre><pre><code><span class="hljs-comment">//Start serverapp.listen(port, (req, res) =&gt; {</span>
</code></pre><pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-string">`server listening on port: <span class="hljs-subst">${port}</span>`</span>)
</code></pre><pre><code> });
</code></pre><p>That’s it. Just navigate to the terminal, make sure you are in the root directory of the project, and type:</p>
<pre><code>$ nodemon &lt;name-<span class="hljs-keyword">of</span>-the-file&gt; (index.js/server.js)
</code></pre><p>In our case since we named it <code>server.js</code> it would be <code>nodemon server.js</code> <em>.</em> This will start the server on port 5000 of your computer locally. If you go visit the browser and open <a target="_blank" href="https://localhost:5000/">https://localhost:5000/</a> you will see the text “root route”, which means the server has started. In case you face any issues, feel free to add them in the comments below.</p>
<p>Now that the server is set up and is working, let’s proceed towards getting the React app setup.</p>
<h3 id="heading-react-app">React app</h3>
<pre><code>$ npm i -g create-react-app$ create-react-app &lt;name-<span class="hljs-keyword">of</span>-the-app&gt;
</code></pre><p>For the purpose of this tutorial we will name the app “client,” so our command will look like this <code>create-react-app client</code><em>.</em></p>
<p>Once this is done, the setup will take some time and will create a nice little folder inside your main application with the name “client”.</p>
<p>We will not make any major changes in the overall React application for now — that is outside the scope of this tutorial.</p>
<p>Now the challenge is that we need to call and connect with our server running on the localhost. To do that we need to make an API call.</p>
<h4 id="heading-adding-a-proxy">Adding a proxy</h4>
<p>React gives us the ability to do so by adding a proxy value to our <code>package.json</code> file. Navigate to the <code>package.json</code> file in your directory and add the piece of code below.</p>
<pre><code><span class="hljs-string">"proxy"</span>: <span class="hljs-string">"http://localhost:5000"</span>,
</code></pre><p>In our case, the server is running at port 5000, hence the 5000 in the proxy value. The value may vary if you are using a different port altogether.</p>
<p>Now we need to call the Express-defined endpoints, or API endpoints, from our React components. What that really means is that now we can simply call “api/users/all” from our client side, which will then proxy our request and it will look like this “https://localhost:5000/api/users/all". This saves us from making a cross origin request, which most of the modern browsers do not allow for security reasons.</p>
<p>Next we will make some changes to the <code>src/app.js</code> file.</p>
<pre><code><span class="hljs-keyword">import</span> React, { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;<span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>;<span class="hljs-keyword">import</span> Navbar <span class="hljs-keyword">from</span> <span class="hljs-string">'./Components/Layout/Navbar'</span>;<span class="hljs-keyword">import</span> { BrowserRouter <span class="hljs-keyword">as</span> Router, Route } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;<span class="hljs-keyword">import</span> Footer <span class="hljs-keyword">from</span> <span class="hljs-string">'./Components/Layout/Footer'</span>;<span class="hljs-keyword">import</span> Home <span class="hljs-keyword">from</span> <span class="hljs-string">'./Components/Layout/Home'</span>;<span class="hljs-keyword">import</span> Social <span class="hljs-keyword">from</span> <span class="hljs-string">'./Components/social/Social'</span>;
</code></pre><pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> </span>{  <span class="hljs-keyword">constructor</span>(props) {    <span class="hljs-built_in">super</span>(props);    <span class="hljs-built_in">this</span>.state = {}    <span class="hljs-built_in">this</span>.connecToServer = <span class="hljs-built_in">this</span>.connecToServer.bind(<span class="hljs-built_in">this</span>);  }
</code></pre><pre><code>  connecToServer() {    fetch(<span class="hljs-string">'/'</span>);  }
</code></pre><pre><code>  componentDidMount() {    <span class="hljs-built_in">this</span>.connecToServer();  }
</code></pre><pre><code>  render() {    <span class="hljs-keyword">return</span> (      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Router</span>&gt;</span>      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>         <span class="hljs-tag">&lt;<span class="hljs-name">Navbar</span> /&gt;</span>         <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">exact</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">component</span>=<span class="hljs-string">{Home}</span> /&gt;</span>         <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">exact</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/social"</span> <span class="hljs-attr">component</span>=<span class="hljs-string">{Social}</span> /&gt;</span>         <span class="hljs-tag">&lt;<span class="hljs-name">Footer</span> /&gt;</span>      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>      <span class="hljs-tag">&lt;/<span class="hljs-name">Router</span>&gt;</span></span>    );  }}
</code></pre><pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre><p>What we did was to create a constructor, and bind the value of this in our function which will make the fetch API call. Then we call the function as soon as the component is mounted. Next we have the render function which has the overall markup for the app. So that was the last change we will do in React or our frontend application.</p>
<p>Your <code>package.json</code> file should look like the code snippet below.</p>
<pre><code>{  <span class="hljs-string">"name"</span>: <span class="hljs-string">"project-name"</span>,  <span class="hljs-string">"version"</span>: <span class="hljs-string">"0.1.0"</span>,  <span class="hljs-string">"private"</span>: <span class="hljs-literal">true</span>,  <span class="hljs-string">"dependencies"</span>: {    <span class="hljs-string">"react"</span>: <span class="hljs-string">"^16.6.3"</span>,    <span class="hljs-string">"react-dom"</span>: <span class="hljs-string">"^16.6.3"</span>,    <span class="hljs-string">"react-scripts"</span>: <span class="hljs-string">"2.1.1"</span>,    <span class="hljs-string">"react-router-dom"</span>: <span class="hljs-string">"^4.3.1"</span>  },
</code></pre><pre><code>  <span class="hljs-string">"scripts"</span>: {    <span class="hljs-string">"start"</span>: <span class="hljs-string">"react-scripts start"</span>,    <span class="hljs-string">"build"</span>: <span class="hljs-string">"react-scripts build"</span>,    <span class="hljs-string">"test"</span>: <span class="hljs-string">"react-scripts test"</span>,    <span class="hljs-string">"eject"</span>: <span class="hljs-string">"react-scripts eject"</span>  },
</code></pre><pre><code>  <span class="hljs-string">"eslintConfig"</span>: {    <span class="hljs-string">"extends"</span>: <span class="hljs-string">"react-app"</span>  },
</code></pre><pre><code>  <span class="hljs-string">"proxy"</span>: <span class="hljs-string">"http://localhost:5000"</span>,
</code></pre><pre><code>  <span class="hljs-string">"browserslist"</span>: [    <span class="hljs-string">"&gt;0.2%"</span>,    <span class="hljs-string">"not dead"</span>,    <span class="hljs-string">"not ie &lt;= 11"</span>,    <span class="hljs-string">"not op_mini all"</span>  ]}
</code></pre><p>Now let’s pause for a minute and think about what we need to do next…. any thoughts?</p>
<p>Some of you are right by thinking we need to make sure our React files are being served by our Express server. Let’s make some modifications to the <code>server.js</code> file to make sure that the React files get served by the Express server.</p>
<h4 id="heading-server-file-change">Server file change</h4>
<pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);<span class="hljs-keyword">const</span> app = express();<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);<span class="hljs-keyword">const</span> port = process.env.PORT || <span class="hljs-number">5000</span>;
</code></pre><pre><code><span class="hljs-comment">//Static file declarationapp.use(express.static(path.join(__dirname, 'client/build')));</span>
</code></pre><pre><code><span class="hljs-comment">//production modeif(process.env.NODE_ENV === 'production') {  app.use(express.static(path.join(__dirname, 'client/build')));  //  app.get('*', (req, res) =&gt; {    res.sendfile(path.join(__dirname = 'client/build/index.html'));  })}</span>
</code></pre><pre><code><span class="hljs-comment">//build modeapp.get('*', (req, res) =&gt; {  res.sendFile(path.join(__dirname+'/client/public/index.html'));})</span>
</code></pre><pre><code><span class="hljs-comment">//start serverapp.listen(port, (req, res) =&gt; {  console.log( `server listening on port: ${port}`);})</span>
</code></pre><p>In the above code snippet, first you need to use the inbuilt path module in node and declare the static folder you would like to use in this Express server.</p>
<p>Then you check if the process <strong>is production</strong>, which it will be once the app is deployed to Heroku. Under this condition you would like to serve the <code>index.html</code> file from the build folder <strong>and not</strong> the public folder.</p>
<p>If it’s <strong>not the production mode,</strong> and you are testing some feature and your server is running on the localhost, you would like the <code>index.html</code> from the public folder to be served.</p>
<p>Now we need to make sure that first we start our Express server and then go about starting our React server. Now there are a lot of ways to do this, and for the simplicity of this tutorial we will be using a module called <code>concurrently</code> to run both the servers with one command.</p>
<p>Make sure you are in the root directory, and then run the command below from your terminal.</p>
<pre><code>npm i concurrently --save
</code></pre><p>After doing this, let’s make some changes to the scripts we have in our Express server <code>package.json</code> files.</p>
<pre><code><span class="hljs-string">"scripts"</span>: {    <span class="hljs-string">"client-install"</span>: <span class="hljs-string">"npm install --prefix client"</span>,    <span class="hljs-string">"start"</span>: <span class="hljs-string">"node index.js"</span>,    <span class="hljs-string">"server"</span>: <span class="hljs-string">"nodemon index.js"</span>,    <span class="hljs-string">"client"</span>: <span class="hljs-string">"npm start --prefix client"</span>,    <span class="hljs-string">"dev"</span>: <span class="hljs-string">"concurrently \"npm run server\" \"npm run client\""</span>,
</code></pre><pre><code>}
</code></pre><ul>
<li><code>npm run client-install</code> will install all the dependencies for the React application</li>
<li><code>npm start</code> will start the server and not reload after detecting any change</li>
<li><code>npm run server</code> will start the server, listen for any changes in the code, and hot reload the page on browser to reflect the change.</li>
<li><code>npm run client</code> will run the React application without starting the server</li>
<li><code>npm run dev</code> will concurrently run the server and then run the client on your browser</li>
</ul>
<h3 id="heading-heroku-setup">Heroku setup</h3>
<p>Make sure you have an account on Heroku. If you don’t, you can make one using your GitHub credentials very quickly.</p>
<p>Next we will install the Heroku CLI , which will help us deploy the application right from our terminal. <a target="_blank" href="https://devcenter.heroku.com/articles/heroku-cli">Click here</a> to get install instructions on both macOS and Windows.</p>
<pre><code>$ heroku login
</code></pre><p>Enter the login credentials for Herkou and then:</p>
<pre><code>$ heroku create
</code></pre><p>This will create an application for you. If you visit the Heroku dashboard now, it will have the application there.</p>
<p>Now we need to make sure we have a build folder in our project before we push the project to the Heroku repository. Add the script below into your <code>package.json</code> file.</p>
<pre><code><span class="hljs-string">"scripts"</span>: {    <span class="hljs-string">"client-install"</span>: <span class="hljs-string">"npm install --prefix client"</span>,
</code></pre><pre><code>    <span class="hljs-string">"start"</span>: <span class="hljs-string">"node server.js"</span>,
</code></pre><pre><code>    <span class="hljs-string">"server"</span>: <span class="hljs-string">"nodemon server.js"</span>,
</code></pre><pre><code>    <span class="hljs-string">"client"</span>: <span class="hljs-string">"npm start --prefix client"</span>,
</code></pre><pre><code>    <span class="hljs-string">"dev"</span>: <span class="hljs-string">"concurrently \"npm run server\" \"npm run client\""</span>,
</code></pre><pre><code>    <span class="hljs-string">"heroku-postbuild"</span>:      <span class="hljs-string">"NPM_CONFIG_PRODUCTION=false npm install --prefix client        &amp;&amp; npm run build --prefix client"</span>  },
</code></pre><p>After doing this, save the file and push the entire project repository to your Heroku application branch.</p>
<pre><code><span class="hljs-comment">//add remote</span>
</code></pre><pre><code>$ heroku git:remote -a application-name
</code></pre><pre><code>$ git add .
</code></pre><pre><code>$ git commit -am <span class="hljs-string">'prepare to deploy'</span>
</code></pre><pre><code>$ git push heroku master
</code></pre><p>And that should be it.</p>
<p>Once this is all done, you will get a URL for your live hosted project. Share and showcase what you can build using these technologies.</p>
<p>If you have any questions or comments feel free to add your comment or connect directly.</p>
<p>Github: <a target="_blank" href="https://github.com/ashishcodes4">https://github.com/ashishcodes4</a></p>
<p>Twitter: <a target="_blank" href="https://twitter.com/ashishnandansin">https://twitter.com/ashishnandansin</a></p>
<p>LinkedIn: <a target="_blank" href="https://www.linkedin.com/in/ashish-nandan-singh-490987130/">https://www.linkedin.com/in/ashish-nandan-singh-490987130/</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Writing Scalable Architecture For Nodejs ]]>
                </title>
                <description>
                    <![CDATA[ By Zafar Saleem Writing backend logic for any project these days is pretty easy, thanks to full stack JavaScript. This is especially so with the introduction of dozens of frameworks for both client side and server side implementation. One of the most... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/writing-scalable-architecture-for-node-js-2b58e0523d7f/</link>
                <guid isPermaLink="false">66c367aab737bb2ce7073237</guid>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 04 Dec 2018 01:36:32 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*VR3E6lnDj4LuHhdM1sWFQw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Zafar Saleem</p>
<p>Writing backend logic for any project these days is pretty easy, thanks to full stack JavaScript. This is especially so with the introduction of dozens of frameworks for both client side and server side implementation.</p>
<p>One of the most popular Node.js frameworks is <a target="_blank" href="https://expressjs.com/">Express.js</a>. It offers an easy approach to building applications at different scales. However, as a project grows, it becomes hard to scale at some point.</p>
<p>Many developers tend to keep adding new route files and models for new services and API end points. This approach works, but it really makes it hard for future engineers to scale and add new services.</p>
<p>In this blog I am going to build a login and registration system that uses JWT authentication with scalable architecture. For those who prefer to get right into the code, go ahead and <a target="_blank" href="https://github.com/zafar-saleem/NodeScalableArchitecture">clone this repository.</a></p>
<p>There will be four parts in this blog.</p>
<ol>
<li>Basic Architecture Setup</li>
<li>Registration</li>
<li>Login</li>
<li>Dashboard</li>
</ol>
<p>This blog assumes that you <a target="_blank" href="https://nodejs.org/en/download/">already installed Node.js</a> in your system. Let’s get into the first step — basic architecture setup.</p>
<h4 id="heading-basic-architecture-setup">Basic architecture setup</h4>
<p>First things first, make a new directory on your file system and call it <code>auth</code> (or anything you like).</p>
<pre><code>mkdir auth
</code></pre><p>Now <code>cd</code> into that directory and create a package.json file. Add the lines below into it.</p>
<pre><code>{    <span class="hljs-string">"name"</span>: <span class="hljs-string">"auth"</span>,    <span class="hljs-string">"version"</span>: <span class="hljs-string">"0.0.0"</span>,    <span class="hljs-string">"private"</span>: <span class="hljs-literal">true</span>,    <span class="hljs-string">"main"</span>: <span class="hljs-string">"index.js"</span>,    <span class="hljs-string">"scripts"</span>: {      <span class="hljs-string">"start"</span>: <span class="hljs-string">"node index.js"</span>    },    <span class="hljs-string">"dependencies"</span>: {      <span class="hljs-string">"bcrypt"</span>: <span class="hljs-string">"latest"</span>,      <span class="hljs-string">"body-parser"</span>: <span class="hljs-string">"^1.18.2"</span>,      <span class="hljs-string">"cookie-parser"</span>: <span class="hljs-string">"~1.4.3"</span>,      <span class="hljs-string">"express"</span>: <span class="hljs-string">"~4.15.5"</span>,      <span class="hljs-string">"jsonwebtoken"</span>: <span class="hljs-string">"^8.1.1"</span>,      <span class="hljs-string">"mongoose"</span>: <span class="hljs-string">"^5.0.3"</span>,      <span class="hljs-string">"lodash"</span>: <span class="hljs-string">"^4.17.11"</span>,      <span class="hljs-string">"morgan"</span>: <span class="hljs-string">"^1.9.0"</span>,      <span class="hljs-string">"passport"</span>: <span class="hljs-string">"^0.4.0"</span>,      <span class="hljs-string">"passport-jwt"</span>: <span class="hljs-string">"^3.0.1"</span>,      <span class="hljs-string">"serve-favicon"</span>: <span class="hljs-string">"~2.4.5"</span>    }  }
</code></pre><p>The most important part of the file above is the <code>dependencies</code> property. These are the dependencies required for the project. They will be used as middleware later in this blog.</p>
<p>Now go ahead and run the command below to install all of these dependencies. You may need to wait a few seconds.</p>
<pre><code>npm install
</code></pre><p>Once it installs all of above dependencies, go ahead and create an <code>index.js</code> file in your root folder, like below:</p>
<pre><code>touch index.js
</code></pre><p>This particular file is only responsible to start the server. To do that, add below code into it:</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> server = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./server'</span>)();<span class="hljs-keyword">const</span> config = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./configs'</span>);<span class="hljs-keyword">const</span> db = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./configs/db'</span>);
</code></pre><pre><code>server.create(config, db);server.start();
</code></pre><p>As you can see, this file requires three files:</p>
<ol>
<li>server</li>
<li>config</li>
<li>db</li>
</ol>
<p>We will create these next.</p>
<p>The code above then calls the <code>create</code> method on the server module. Finally, it calls the <code>start</code> method, which starts the server.</p>
<h4 id="heading-1-create-the-server-folder">1. Create the <code>server</code> folder</h4>
<pre><code>mkdir server
</code></pre><p>Once done, <code>cd</code> into that folder and create another <code>index.js</code> file.</p>
<pre><code>touch index.js
</code></pre><p>Now add the code below into this file:</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);<span class="hljs-keyword">const</span> bodyParser = <span class="hljs-built_in">require</span>(<span class="hljs-string">'body-parser'</span>);<span class="hljs-keyword">const</span> logger = <span class="hljs-built_in">require</span>(<span class="hljs-string">'morgan'</span>);<span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mongoose'</span>);<span class="hljs-keyword">const</span> passport = <span class="hljs-built_in">require</span>(<span class="hljs-string">'passport'</span>);<span class="hljs-keyword">const</span> cookieParser = <span class="hljs-built_in">require</span>(<span class="hljs-string">'cookie-parser'</span>);
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-keyword">let</span> server = express(),      create,      start;
</code></pre><pre><code>   create = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">config, db</span>) </span>{      <span class="hljs-keyword">let</span> routes = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./routes'</span>);
</code></pre><pre><code>       <span class="hljs-comment">// Server settings       server.set('env', config.env);       server.set('port', config.port);       server.set('hostname', config.hostname);</span>
</code></pre><pre><code>       <span class="hljs-comment">// Returns middleware that parses json       server.use(bodyParser.json());       server.use(bodyParser.urlencoded({ extended: false }));       server.use(cookieParser());       server.use(logger('dev'));       server.use(passport.initialize());       mongoose.connect(db.database);       require('../configs/passport')(passport);</span>
</code></pre><pre><code>       <span class="hljs-comment">// Set up routes       routes.init(server);   };</span>
</code></pre><pre><code>   start = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{       <span class="hljs-keyword">let</span> hostname = server.get(<span class="hljs-string">'hostname'</span>),       port = server.get(<span class="hljs-string">'port'</span>);
</code></pre><pre><code>       server.listen(port, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Express server listening on - http://'</span> + hostname + <span class="hljs-string">':'</span> + port);        });    };
</code></pre><pre><code>    <span class="hljs-keyword">return</span> {       <span class="hljs-attr">create</span>: create,       <span class="hljs-attr">start</span>: start    };};
</code></pre><p>In this file, we first require all of the dependencies needed for this project. Note that more dependencies can be added into this file whenever required.</p>
<p>Then we export an anonymous function from this module using <code>module.exports</code>. Inside that function, create three variables: <code>server</code>, <code>create</code> and <code>start</code>.</p>
<p>The <code>server</code> variable is for the Express.js server. So, call the <code>express()</code> function and assign that to <code>server</code>. We will assign anonymous functions to the <code>create</code> and <code>start</code> variables.</p>
<p>Now, it is time to write a <code>create</code> function with two parameters: <code>config</code> and <code>db</code>.</p>
<p>Then set a few server settings using the server.use() function i.e. env, port and hostname. Then use <code>cookieParser, bodyParser, logger and passport</code> middlewares. Then connect to <code>mongoose</code> database and finally require passport’s configuration file and call it with the required passport.</p>
<p>Passport middleware is used for authentication, which we will use later in this blog. To learn more about it click <a target="_blank" href="http://www.passportjs.org/">here</a>.</p>
<p>Now it’s time for API end points i.e. routes. Simply call the <code>init</code> function on routes and pass <code>server</code> into this.</p>
<p>Next, write the <code>start</code> function. Set <code>hostname</code> and <code>port</code> and start the server with the <code>listen</code> command inside this function.</p>
<p>Then, return both <code>create</code> and <code>start</code> functions to make them available for other modules to use.</p>
<h4 id="heading-2-create-the-config-folder">2. Create the config folder</h4>
<p>At the root level, create a <code>configs</code> folder:</p>
<pre><code>mkdir configs
</code></pre><p><code>cd</code> into that folder and create an index.js file:</p>
<pre><code>touch index.js
</code></pre><p>Add the below code to the index.js file:</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> _ = <span class="hljs-built_in">require</span>(<span class="hljs-string">'lodash'</span>);<span class="hljs-keyword">const</span> env = process.env.NODE_ENV || <span class="hljs-string">'local'</span>;<span class="hljs-keyword">const</span> envConfig = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./'</span> + env);
</code></pre><pre><code><span class="hljs-keyword">let</span> defaultConfig = {  <span class="hljs-attr">env</span>: env};
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = _.merge(defaultConfig, envConfig);
</code></pre><p>Now create a local.js file:</p>
<pre><code>touch local.js
</code></pre><p>Open it, and add the code below:</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">let</span> localConfig = {  <span class="hljs-attr">hostname</span>: <span class="hljs-string">'localhost'</span>,  <span class="hljs-attr">port</span>: <span class="hljs-number">3000</span>};
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = localConfig;
</code></pre><p>This one’s simple too. We are creating a <code>localConfig</code> object and adding a few properties such as <code>hostname</code> and <code>port</code>. Then export it to use it like we are doing in the <code>./index.js</code> file.</p>
<h4 id="heading-3-now-create-a-database">3. Now create a database</h4>
<pre><code>touch db.js
</code></pre><p>Open db.js in your favourite editor and paste the below code into it.</p>
<pre><code><span class="hljs-built_in">module</span>.exports = {   <span class="hljs-string">'secret'</span>: <span class="hljs-string">'putsomethingsecretehere'</span>,  <span class="hljs-string">'database'</span>: <span class="hljs-string">'mongodb://127.0.0.1:27017/formediumblog'</span>};
</code></pre><p>We are exporting a JavaScript object with properties <code>secret</code> and <code>database</code>. These are used to connect with a MongoDB database using middleware called mongoose.</p>
<h3 id="heading-building-the-app">Building the app</h3>
<p>Now we are done with basic setup of our project, time for the fun stuff!</p>
<p><code>cd</code> into the <code>server</code> folder and create the following folders:</p>
<pre><code>mkdir controllers models routes services
</code></pre><p>First, we will cover the <code>routes</code> folder. This folder is used to add all the end points that are available for client side use. First of all go ahead and create the <code>index.js</code> file first inside the <code>routes</code> folder.</p>
<pre><code>touch index.js
</code></pre><p>And put the below code into this file:</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> apiRoute = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./apis'</span>);
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">init</span>(<span class="hljs-params">server</span>) </span>{  server.get(<span class="hljs-string">'*'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">req, res, next</span>) </span>{    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Request was made to: '</span> + req.originalUrl);    <span class="hljs-keyword">return</span> next();  });
</code></pre><pre><code>  server.use(<span class="hljs-string">'/api'</span>, apiRoute);}
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = {  <span class="hljs-attr">init</span>: init};
</code></pre><p>First, require the <code>apiRoute</code> folder which we are going to create next. This folder will contain another folder with the version number of the API i.e. <code>v1</code> .</p>
<p>Second create an <code>init</code> function. We are calling this function from the <code>server/index.js</code> file inside the <code>create</code> function at the bottom and passing <code>server</code> as a parameter. It simply gets all the routes and returns the next callback function.</p>
<p>Then use the <code>apiRoute</code> that we are requiring above. Finally, export the init function to make this function available in the rest of the project.</p>
<p>Now go ahead create an <code>apis</code> folder. Inside that folder create a file <code>index.js</code> .</p>
<pre><code>mkdir apistouch index.js
</code></pre><p>Paste the below code into the <code>index.js</code> file.</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);<span class="hljs-keyword">const</span> v1ApiController = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./v1'</span>);
</code></pre><pre><code><span class="hljs-keyword">let</span> router = express.Router();
</code></pre><pre><code>router.use(<span class="hljs-string">'/v1'</span>, v1ApiController);
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = router;
</code></pre><p>This file requires <code>express</code> and the api version folder i.e. <code>v1</code>. Then create the router and make <code>/v1</code> end point using <code>router.use()</code> method. Finally export the router.</p>
<p>It’s time to create <code>apis/v1.js</code> file. Paste the below code inside the <code>v1.js</code> file:</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> registerController = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../controllers/apis/register'</span>);<span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);
</code></pre><pre><code><span class="hljs-keyword">let</span> router = express.Router();
</code></pre><pre><code>router.use(<span class="hljs-string">'/register'</span>, registerController);
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = router;
</code></pre><p>We need to register the controller and express.js and create a router. Then we need to expose <code>register</code> API endpoints for client side use. Finally, we must export the router from this module.</p>
<p>This is the file that we are going to keep modifying. We will require more controllers here when we create them.</p>
<p>Now we are done with the routes folder, and it is time for the controllers folder. Go ahead and CD into that folder and create a folder <code>apis</code> .</p>
<pre><code>mkdir apis
</code></pre><p>Now that we have the apis folder inside <code>controllers</code>, we are going to create the following three controllers and their respective <code>services</code>.</p>
<ol>
<li>Basic Architecture Setup</li>
<li><strong>Registration</strong></li>
<li>Login</li>
<li>Dashboard</li>
</ol>
<p>First up is the <code>registerController</code>. Go ahead and create the below file.</p>
<pre><code>touch register.js
</code></pre><p>Open this file in your favourite editor and paste the below code into it:</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);<span class="hljs-keyword">const</span> registerService = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../services/authentication/register'</span>);
</code></pre><pre><code><span class="hljs-keyword">let</span> router = express.Router();
</code></pre><pre><code>router.post(<span class="hljs-string">'/'</span>, registerService.registerUser);
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = router;
</code></pre><p>First it is requiring <code>express.js</code> and the <code>register</code> service (which we are going to write later). Then create a router using the <code>express.Router()</code> method and make a post request to the <code>'/'</code> path. Then call the registerUser method on registerService (which we are going to write later). Finally, export the router from this module.</p>
<p>Now we need to require this controller inside the <code>routes/apis/v1.js</code> file which we already did.</p>
<p>Now registering the controller is done. It is time to get to the <code>services</code> folder. CD into that folder and create an <code>authentication</code> folder. First things first, cd into <code>authentication</code> and create a <code>register.js</code> file.</p>
<pre><code>touch register.js
</code></pre><p>Then open the <code>register.js</code> file and paste the below code into it:</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);<span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../models/User'</span>);
</code></pre><pre><code><span class="hljs-keyword">const</span> httpMessages = {  <span class="hljs-attr">onValidationError</span>: {    <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,    <span class="hljs-attr">message</span>: <span class="hljs-string">'Please enter email and password.'</span>  },  <span class="hljs-attr">onUserSaveError</span>: {    <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,    <span class="hljs-attr">message</span>: <span class="hljs-string">'That email address already exists.'</span>  },  <span class="hljs-attr">onUserSaveSuccess</span>: {    <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,    <span class="hljs-attr">message</span>: <span class="hljs-string">'Successfully created new user.'</span>  }}
</code></pre><pre><code><span class="hljs-comment">// Register new usersfunction registerUser(request, response) {  let { email, password } = request.body;</span>
</code></pre><pre><code>  <span class="hljs-keyword">if</span> (!email || !password) {    response.json(httpMessages.onValidationError);  } <span class="hljs-keyword">else</span> {    <span class="hljs-keyword">let</span> newUser = <span class="hljs-keyword">new</span> User({      <span class="hljs-attr">email</span>: email,      <span class="hljs-attr">password</span>: password    });
</code></pre><pre><code>    <span class="hljs-comment">// Attempt to save the user    newUser.save(error =&gt; {      if (error) {        return response.json(httpMessages.onUserSaveError);      }      response.json(httpMessages.onUserSaveSuccess);    });  }}</span>
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = {  <span class="hljs-attr">registerUser</span>: registerUser};
</code></pre><p>In the <code>register</code> service, first we are requiring <code>expressjs</code> and <code>User</code> model. Then we are creating a JavaScript object i.e. <code>httpMessages</code> which is basically a list of all the messages we are going to send to clients via the api when the client sends the request.</p>
<p>Then the function <code>registerUser</code> which actually performs the registration process. Before saving the user there is a check if the user provided their email and password. If they did then create a newUser using the <code>new</code> keyword with the provided email and password.</p>
<p>Then simply call the <code>save</code> function on <code>newUser</code> to save that user in the database and send the appropriate response using <code>response.json</code>.</p>
<p>Finally export this function using <code>module.exports</code> to make use of it in the rest of the project. We are using this inside the <code>controllers/register.js</code> file.</p>
<p>Before testing this to see if it works, first we need to create a <code>User</code> model. Go ahead create a file <code>User.js</code> inside the <code>models</code> folder.</p>
<pre><code>touch User.js
</code></pre><p>And paste this code into the above file:</p>
<pre><code><span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mongoose'</span>);<span class="hljs-keyword">const</span> bcrypt = <span class="hljs-built_in">require</span>(<span class="hljs-string">'bcrypt'</span>);
</code></pre><pre><code><span class="hljs-keyword">const</span> UserSchema = <span class="hljs-keyword">new</span> mongoose.Schema({  <span class="hljs-attr">email</span>: {    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,    <span class="hljs-attr">lowercase</span>: <span class="hljs-literal">true</span>,    <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>,    <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>  },  <span class="hljs-attr">password</span>: {    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,    <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>  },  <span class="hljs-attr">role</span>: {    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,    <span class="hljs-attr">enum</span>: [<span class="hljs-string">'Client'</span>, <span class="hljs-string">'Manager'</span>, <span class="hljs-string">'Admin'</span>],    <span class="hljs-attr">default</span>: <span class="hljs-string">'Client'</span>  }});
</code></pre><pre><code>UserSchema.pre(<span class="hljs-string">'save'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">next</span>) </span>{  <span class="hljs-keyword">let</span> user = <span class="hljs-built_in">this</span>;
</code></pre><pre><code>   <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.isModified(<span class="hljs-string">'password'</span>) || <span class="hljs-built_in">this</span>.isNew) {      bcrypt.genSalt(<span class="hljs-number">10</span>, <span class="hljs-function">(<span class="hljs-params">err, salt</span>) =&gt;</span> {        <span class="hljs-keyword">if</span> (err) {          <span class="hljs-built_in">console</span>.log(err);          <span class="hljs-keyword">return</span> next(err);        }
</code></pre><pre><code>        bcrypt.hash(user.password, salt, <span class="hljs-function">(<span class="hljs-params">err, hash</span>) =&gt;</span> {          <span class="hljs-keyword">if</span> (err) {            <span class="hljs-built_in">console</span>.log(err);            <span class="hljs-keyword">return</span> next(err);          }
</code></pre><pre><code>          user.password = hash;          next();        });      });  } <span class="hljs-keyword">else</span> {    <span class="hljs-keyword">return</span> next();  }});
</code></pre><pre><code><span class="hljs-comment">// Create method to compare password input to password saved in databaseUserSchema.methods.comparePassword = function(pw, cb) {  bcrypt.compare(pw, this.password, function(err, isMatch) {    if (err) {      return cb(err);    }</span>
</code></pre><pre><code>    cb(<span class="hljs-literal">null</span>, isMatch);  });};
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = mongoose.model(<span class="hljs-string">'User'</span>, UserSchema);
</code></pre><p>First of all require the <code>mongoose</code> and <code>bcrypt</code> modules. Mongoose is used to create mongodb schema whereas bcrypt is used to encrypt passwords before storing them into the database.</p>
<p>Create <code>UserSchema</code> with <code>email, password and role</code> properties. Then before saving the user, perform some checks before hashing the password.</p>
<p>The final function is to compare the passwords. It compares the user’s password with the hashed password in the database.</p>
<p>Now in order to test this code, open postman (if you haven’t installed postman go ahead install it from <a target="_blank" href="https://www.getpostman.com/">here</a>). Open postman and enter the below url:</p>
<pre><code>http:<span class="hljs-comment">//localhost:3000/api/v1/register</span>
</code></pre><p>Select POST as the request, choose the body tab and <code>form-urlencoded</code> and enter the email and password. Press the send button and you should see the below success message.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/v24ai9wIGdPv0m2RrvssyzNtBa1c3MK1yA3k" alt="Image" width="800" height="498" loading="lazy"></p>
<p>Now the register part is done.</p>
<ol>
<li>Basic Architecture Setup</li>
<li>Register</li>
<li><strong>Login</strong></li>
<li>Dashboard</li>
</ol>
<p>It is time to focus on login. Create a <code>login.js</code> file inside the <code>controllers</code> folder.</p>
<pre><code>touch login.js
</code></pre><p>Now open it and paste the below code:</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);<span class="hljs-keyword">const</span> loginService = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../services/authentication/login'</span>);
</code></pre><pre><code><span class="hljs-keyword">let</span> router = express.Router();
</code></pre><pre><code>router.post(<span class="hljs-string">'/'</span>, loginService.loginUser);
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = router;
</code></pre><p>Again it’s simple and the same as the register module: after importing <code>express.js</code> and <code>loginService</code> we are creating the router and make a post request to the root path <code>'/'</code> with the <code>loginUser</code> callback function on <code>loginService</code> . Finally export the router.</p>
<p>It’s time to require <code>loginController</code> in the <code>routes/apis/v1.js</code> file. Your <code>v1.js</code> file should look like the below now.</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> registerController = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../controllers/apis/register'</span>);<span class="hljs-keyword">const</span> loginController = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../controllers/apis/login'</span>);
</code></pre><pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);
</code></pre><pre><code><span class="hljs-keyword">let</span> router = express.Router();
</code></pre><pre><code>router.use(<span class="hljs-string">'/register'</span>, registerController);router.use(<span class="hljs-string">'/login'</span>, loginController);
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = router;
</code></pre><p>Now for the login service, create a <code>login.js</code> file inside <code>services/authentication/</code>:</p>
<pre><code>touch login.js
</code></pre><p>And paste the below code into this file:</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);<span class="hljs-keyword">const</span> apiRoutes = express.Router();
</code></pre><pre><code><span class="hljs-keyword">const</span> jwt = <span class="hljs-built_in">require</span>(<span class="hljs-string">'jsonwebtoken'</span>);<span class="hljs-keyword">const</span> passport = <span class="hljs-built_in">require</span>(<span class="hljs-string">'passport'</span>);<span class="hljs-keyword">const</span> db = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../../configs/db'</span>);
</code></pre><pre><code><span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../models/User'</span>);
</code></pre><pre><code><span class="hljs-keyword">const</span> httpResponse = {  <span class="hljs-attr">onUserNotFound</span>: {    <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,    <span class="hljs-attr">message</span>: <span class="hljs-string">'User not found.'</span>  },  <span class="hljs-attr">onAuthenticationFail</span>: {    <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,    <span class="hljs-attr">message</span>: <span class="hljs-string">'Passwords did not match.'</span>  }}
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loginUser</span>(<span class="hljs-params">request, response</span>) </span>{   <span class="hljs-keyword">let</span> { email, password } = request.body;
</code></pre><pre><code>User.findOne({    <span class="hljs-attr">email</span>: email  }, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">error, user</span>) </span>{    <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">throw</span> error;
</code></pre><pre><code>    <span class="hljs-keyword">if</span> (!user) {      <span class="hljs-keyword">return</span> response.send(httpResponse.onUserNotFound);    }
</code></pre><pre><code>    <span class="hljs-comment">// Check if password matches    user.comparePassword(password, function(error, isMatch) {      if (isMatch &amp;&amp; !error) {        var token = jwt.sign(user.toJSON(), db.secret, {           expiresIn: 10080        });</span>
</code></pre><pre><code>        <span class="hljs-keyword">return</span> response.json({           <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">token</span>: <span class="hljs-string">'JWT '</span> + token        });      }
</code></pre><pre><code>      response.send(httpResponse.onAuthenticationFail);    });  });};
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = {  <span class="hljs-attr">loginUser</span>: loginUser};
</code></pre><p>First require some necessary modules such as: <code>express.js, jsonwebtoken, passport, db and User model</code>. Create a JavaScript object that has a list of messages to be sent to the client side when the http request is made to this service.</p>
<p>Create a loginUser function, and inside that create a couple of variables i.e. email and password, and assign the email and password sent by the user to these variables which are in <code>request.body</code>.</p>
<p>Then use the <code>findOne()</code> method on the <code>User</code> model to find a use based on the email sent from the client by the user. The callback function of <code>findOne()</code> accepts 2 parameters, <code>error and user</code>. First check if the above <code>findOne()</code> method throws any error — if it does then throw an error.</p>
<p>Then perform a check: if no user is found, then send the proper response with a message from the list of messages that we declared above in this module.</p>
<p>Then compare the password that the user sent with the one in the database using the <code>compare</code> function we wrote in the <code>User</code> model earlier in this blog.</p>
<p>If the password matches and it does not return an error, then we create a token using the <code>jsonwebtoken</code> module and return that token using <code>json.response()</code> to the client. Otherwise we send an <code>authenticationFail</code> message.</p>
<p>Finally export the <code>loginUser</code> function with <code>exports.module</code> so that we can use it in our controllers and anywhere else.</p>
<p>It’s time to test login functionality. Go back to postman and this time replace <code>register</code> with <code>login</code> as the api end point in the url. Enter the email and password and press the send button. You should be able to receive a token. Go ahead and copy that to the clipboard because you will use it later to access the dashboard.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/NgY6nezWpJkKbuOU7555pCd4abpZBNzzPvBd" alt="Image" width="800" height="499" loading="lazy"></p>
<ol>
<li>Basic Architecture Setup</li>
<li>Register</li>
<li>Login</li>
<li><strong>Dashboard</strong></li>
</ol>
<p>Now it’s time for the <code>dashboard.js</code> file. Create <code>dashboard.js</code> file inside<code>controllers</code> folder.</p>
<pre><code>touch dashboard.js
</code></pre><p>And open it and paste the below code:</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> passport = <span class="hljs-built_in">require</span>(<span class="hljs-string">'passport'</span>);<span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);<span class="hljs-keyword">const</span> dashboardService = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../services/dashboard/dashboard'</span>);
</code></pre><pre><code><span class="hljs-keyword">let</span> router = express.Router();
</code></pre><pre><code>router.get(<span class="hljs-string">'/'</span>, passport.authenticate(<span class="hljs-string">'jwt'</span>, { <span class="hljs-attr">session</span>: <span class="hljs-literal">false</span> }), dashboardService.getDashboard);
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = router;
</code></pre><p>This controller is different in the sense that it requires authenticated access. That is, only a logged-in user can access the dashboard service and make different http requests.</p>
<p>For that reason we are also importing passport, and for the get request we are using the <code>passport.authenticate()</code> function to <code>getDashboard</code> service.</p>
<p>Again we need to require <code>dashboardController</code> in the <code>routes/apis/v1.js</code> file. Your <code>v1.js</code> file should look like the below:</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-keyword">const</span> registerController = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../controllers/apis/register'</span>);<span class="hljs-keyword">const</span> loginController = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../controllers/apis/login'</span>);<span class="hljs-keyword">const</span> dashboardController = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../../controllers/apis/dashboard'</span>);
</code></pre><pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);
</code></pre><pre><code><span class="hljs-keyword">let</span> router = express.Router();
</code></pre><pre><code>router.use(<span class="hljs-string">'/register'</span>, registerController);router.use(<span class="hljs-string">'/login'</span>, loginController);router.use(<span class="hljs-string">'/dashboard'</span>, dashboardController);
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = router;
</code></pre><p>Now that <code>dashboardController</code> is available to be used for client side requests, it’s time to create its respective service. Go to the services folder and create a <code>dashboard</code> folder inside it. Create a <code>dashboard.js</code> file and put the below code inside this file.</p>
<pre><code><span class="hljs-meta">'use strict'</span>;
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getDashboard</span>(<span class="hljs-params">request, response</span>) </span>{  response.json(<span class="hljs-string">'This is from dashboard'</span>);}
</code></pre><pre><code><span class="hljs-built_in">module</span>.exports = {  <span class="hljs-attr">getDashboard</span>: getDashboard}
</code></pre><p>No fancy stuff going on. For demonstration purposes, I am simply responding with a text message <code>This is from dashboard</code>. Then export this method to be used in its respective controller which we already accomplished.</p>
<p>Now it’s testing time. Open postman and change the end point of the url to the dashboard. Click the headers tab and add <code>Authorization</code> and paste the JTW copied in the previous step when you logged in.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/cQtptcZskXGs8nrmEPsRlDuRxsJjxv5a9gE1" alt="Image" width="800" height="498" loading="lazy"></p>
<p>You should see the message <code>This is from dashboard</code> as a response.</p>
<p>As you can see, when we make a new service we need one controller for it and we can keep adding new services into the architecture. If you would like to change the version of the API and also keep the current one, simply add a new <code>v2.js</code> file and redirect all requests to that end point. That is one simple example.</p>
<p>I hope you liked this blog and see you next time.</p>
<p>UPDATE: If you would like to implement its client side then please <a target="_blank" href="https://medium.com/@zafarsaleem/login-using-react-redux-redux-saga-86b26c8180e">click here</a> where I used react.js to authenticate with this server.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to generate ReadMe badges with Express ]]>
                </title>
                <description>
                    <![CDATA[ By Ben Gubler I first came across this idea on this website. Since the tutorial there is a few years old, I wrote a new tutorial with updated code. If you’re in a hurry, you can find the completed code here. We all know about them or use them — ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-generate-readme-badges-with-express-and-squirrelly-77310125dca0/</link>
                <guid isPermaLink="false">66c35204765a634c3485fe1a</guid>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 30 Nov 2018 17:36:21 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*BqQhKwkKqIBn_lL-pmYHNg.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ben Gubler</p>
<p>I first came across this idea on <a target="_blank" href="https://odino.org/generating-badges-slash-shields-with-nodejs/">this</a> website. Since the tutorial there is a few years old, I wrote a new tutorial with updated code.</p>
<p><em>If you’re in a hurry, you can find the completed code <a target="_blank" href="https://github.com/nebrelbug/badge-generator">here</a>.</em></p>
<p>We all know about them or use them — the shiny badges at the top of nearly every ReadMe that say things like “<strong>build: passing</strong>”, or “<strong>size: 10KB</strong>”. This guide will teach you how to generate your own badges, with nothing but Node.js, ExpressJS, and Squirrelly.</p>
<h3 id="heading-now-for-the-tutorial">Now for the tutorial</h3>
<h4 id="heading-prerequisites">Prerequisites</h4>
<p>This tutorial assumes you have Node.js and npm (or yarn) already installed. If you don’t, go to the Node site <a target="_blank" href="https://nodejs.org/en/">here</a> (it installs with npm by default).</p>
<h4 id="heading-setup">Setup</h4>
<p>First, create a new directory and <code>cd</code> into it:</p>
<pre><code>mkdir badge-generator &amp;&amp; cd badge-generator
</code></pre><p>Next, install the necessary dependencies, <a target="_blank" href="https://expressjs.com/">Express</a> and <a target="_blank" href="https://squirrelly.js.org/">Squirrelly</a>.</p>
<p>With npm:</p>
<pre><code>npm install express squirrelly
</code></pre><p>Or for those who use yarn:</p>
<pre><code>yarn add express squirrelly
</code></pre><h4 id="heading-creating-the-server">Creating the server</h4>
<p>We’ll only need two files for our program, <strong>index.js</strong> and <strong>template.svg</strong> (which we’ll create next).</p>
<p>Create a file named <strong>index.js</strong> and paste the following code:</p>
<p>This opens a server on port 8080, and listens to requests. By the end of this tutorial, you’ll be able to make a request to <a target="_blank" href="http://localhost:8080/left-text/right-text/color"><strong>http://localhost:8080/left-text/right-text/color</strong></a> and have an awesome-looking SVG badge returned! Yay! But what’s the part of the code with <code>Sqrl</code> about?</p>
<pre><code><span class="hljs-keyword">var</span> badge = Sqrl.renderFile(path.join(__dirname, <span class="hljs-string">'template.svg'</span>), req.params)
</code></pre><p>This is where Squirrelly comes in. We want to serve an SVG image file, but the content (width, length, and text) of the image will be different each time. Squirrelly is a <strong>template engine</strong>, a program that takes a file or string called a template and inserts the data. It also does some other fancy stuff, like handling caching, but we won’t need to worry about that.</p>
<p>The code above reads the file named <code>template.svg</code> , then uses <code>req.params</code> (an object that contains the paths) to fill the template. In this case, <code>req.params</code> will look like:</p>
<pre><code>{  <span class="hljs-attr">left</span>: <span class="hljs-string">"first-part-of-the-url-path"</span>,  <span class="hljs-attr">right</span>: <span class="hljs-string">"second-part-of-the-url-path"</span>,  <span class="hljs-attr">color</span>: <span class="hljs-string">"third-part"</span>}
</code></pre><h4 id="heading-creating-a-template">Creating a template</h4>
<p>Create a new file called <code>template.svg</code>, and paste the following code:</p>
<p>You can read the full Squirrelly docs <a target="_blank" href="https://squirrelly.js.org/">here</a>, but essentially, anything between double brackets: <code>{{</code> and <code>}}</code> will be replaced by its actual value.</p>
<p>But wait: we only passed in <code>left</code> , <code>right</code> , and <code>color</code> — where did we get <code>leftWidth</code> and <code>rightWidth</code> from? That’s what the code below (at the top of the template) does; using the <code>js</code> helper (which lets you write JS inside of a template), it defines a new variable, called <code>leftWidth</code> .</p>
<pre><code>{{js(options.leftWidth = options.left.length * <span class="hljs-number">10</span>)/}}
</code></pre><p>There’s one more thing to do. Notice that line 18 looks like this:</p>
<pre><code>&lt;rect ...stuff... fill=<span class="hljs-string">"{{returnColor(options.color)/}}"</span>/&gt;
</code></pre><p>With SVG images, the fill attribute must either contain one of a few predefined colors that don’t look that great, or an <a target="_blank" href="https://en.wikipedia.org/wiki/RGB_color_model">RGB</a> or hex color. We want to use hex codes, but there’s a catch: you’ll notice that if you enter <a target="_blank" href="http://localhost:8080/ben/gubler/#fff"><strong>http://localhost:8080/some/text/#fff</strong></a> into a browser, it thinks the hex code at the end is the hash at the end of the url, and Express doesn’t recognize it.</p>
<p>What we’re going to do is create a helper (called <code>returnColor</code>) that will translate color words, like ‘brightgreen’, ‘green’, and ‘red’, into hex color codes. Paste the following anywhere into index.js:</p>
<h4 id="heading-see-if-it-works">See if it works</h4>
<p>Type <code>node index.js</code> into your terminal, then go to <a target="_blank" href="http://localhost:8080/test/badge/brightgreen">http://localhost:8080/test/badge/brightgreen</a>. If all went well, you should see a badge!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*s3-kyFWQZL_v7s8xDWn1vw.png" alt="Image" width="789" height="176" loading="lazy"></p>
<p>If anything throws an error, compare your code to the working code <a target="_blank" href="https://github.com/nebrelbug/badge-generator">here</a>.</p>
<p>You can find more information about Squirrelly below.</p>
<p><a target="_blank" href="https://squirrelly.js.org/"><strong>Squirrelly Documentation</strong></a><br><a target="_blank" href="https://squirrelly.js.org/">_Squirrelly is only 2KB gzipped, has 0 dependencies, and is blazing fast._squirrelly.js.org</a></p>
<p>Thanks for reading this guide. I hope it was helpful!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How  to write a production-ready Node and Express app ]]>
                </title>
                <description>
                    <![CDATA[ By Shailesh Shekhawat Project Structuring When I started building Node & Express applications, I didn’t know how important it was to structure your application. Express doesn’t come with strict rules or guidelines for maintaining the project structur... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-write-a-production-ready-node-and-express-app-f214f0b17d8c/</link>
                <guid isPermaLink="false">66d46158230dff016690588d</guid>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 08 Oct 2018 21:07:28 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*-1tLk1cFdmcEQfNhQ7LIUg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Shailesh Shekhawat</p>
<h3 id="heading-project-structuring">Project Structuring</h3>
<p>When I started building Node &amp; Express applications, I didn’t know how important it was to structure your application. Express doesn’t come with strict rules or guidelines for maintaining the project structure.</p>
<p>You are free to use any structure you want. When your codebase grows you end up having long <code>route</code> handlers. This makes your code hard to understand and it contains potential bugs.</p>
<p>If you’re working for a startup, most of the time you won’t have time to refractor your project or modularize it. You can end up with an endless loop of bug fixing and patching.</p>
<div class="embed-wrapper"><iframe src="https://giphy.com/embed/6csVEPEmHWhWg" width="480" height="270" class="giphy-embed" title="Embedded content" loading="lazy"></iframe></div>

<p>Over time, while working with both small teams and large teams, I realized what kind of structure can grow with your project and still be easy to maintain.</p>
<h4 id="heading-model-view-controller">Model View Controller</h4>
<p>The <a target="_blank" href="https://en.wikipedia.org/wiki/Model–view–controller">MVC</a> pattern helps in rapid and parallel development. For example, one developer can work on the view, while another one can work on creating the business logic in the controller.</p>
<p>Let’s take a look at an example of a simple user CRUD application.</p>
<pre><code>project/
  controllers/
    users.js
  util/
    plugin.js
  middlewares/
    auth.js
  models/
    user.js
  routes/
    user.js
    router.js
  public/
    js/
    css/
    img/
  views/
    users/
      index.jade
  tests/
    users/
      create-user-test.js 
      update-user-test.js
      get-user-test.js
  .gitignore
  app.js
  package.json
</code></pre><ul>
<li><strong>controllers:</strong> Define your app route handlers and business logic</li>
<li><strong>util:</strong> Writes utility/helper functions here which can be used by any controllers. For example, you can write a function like <code>mergeTwoArrays(arr1, arr2)</code>.</li>
<li><strong>middlewares:</strong> You can write middlewares to interpret all incoming requests before moving to the route handler. For example,<br><code>router.post('/login', auth, controller.login)</code> where <code>auth</code> is a middleware function defined in <code>middlewares/auth.js</code>.</li>
<li><strong>models:</strong> also a kind of middleware between your controller and the database. You can define a schema and do some validation before writing to the database. For example, you can use an ORM like <a target="_blank" href="https://mongoosejs.com/">Mongoose</a> which comes with great features and methods to use in the schema itself</li>
<li><strong>routes:</strong> Define your app routes, with HTTP methods. For example, you can define everything related to the user.</li>
</ul>
<pre><code class="lang-js">router.post(<span class="hljs-string">'/users/create'</span>, controller.create)
router.put(<span class="hljs-string">'/users/:userId'</span>, controller.update)
router.get(<span class="hljs-string">'/users'</span>, controller.getAll)
</code></pre>
<ul>
<li><strong>public:</strong> Store static images in<code>/img</code>, custom JavaScript files, and CSS <code>/css</code></li>
<li><strong>views:</strong> Contains templates to be rendered by the server.</li>
<li><strong>tests:</strong> Here you can write all the unit tests or acceptance tests for the API server.</li>
<li><strong>app.js:</strong> Acts as the main file of the project where you initialize the app and other elements of the project.</li>
<li><strong>package.json:</strong> Takes care of the dependencies, the scripts to run with the <code>npm</code> command, and the version of your project.</li>
</ul>
<h3 id="heading-exceptions-and-error-handling"><strong>Exceptions and Error Handling</strong></h3>
<p>This is one of the most important aspects to think about when creating any project with any language. Let’s see how to handle errors and exceptions gracefully in an Express app.</p>
<h4 id="heading-using-promises"><strong>Using promises</strong></h4>
<p>One of the advantages of using promises over callbacks is they can handle implicit or explicit exceptions/errors in asynchronous code blocks as well as for synchronous code defined in <code>.then()</code>, a promise callback</p>
<p>Just add <code>.catch(next)</code> at the end of the promise chain. For example:</p>
<pre><code class="lang-js">router.post(<span class="hljs-string">'/create'</span>, <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {

   User.create(req.body)    <span class="hljs-comment">// function to store user data in db</span>
   .then(<span class="hljs-function"><span class="hljs-params">result</span> =&gt;</span> {

     <span class="hljs-comment">// do something with result</span>

     <span class="hljs-keyword">return</span> result 
   })
   .then(<span class="hljs-function"><span class="hljs-params">user</span> =&gt;</span> res.json(user))
   .catch(next)
})
</code></pre>
<h4 id="heading-using-try-catch"><strong>Using try-catch</strong></h4>
<p>Try-catch is a traditional way of catching exceptions in asynchronous code.</p>
<p>Let’s take a look at an example with a possibility of getting an exception:</p>
<pre><code class="lang-js">router.get(<span class="hljs-string">'/search'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {

  setImmediate(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> jsonStr = req.query.params
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> jsonObj = <span class="hljs-built_in">JSON</span>.parse(jsonStr)

      res.send(<span class="hljs-string">'Success'</span>)
    } <span class="hljs-keyword">catch</span> (e) {
      res.status(<span class="hljs-number">400</span>).send(<span class="hljs-string">'Invalid JSON string'</span>)
    }
  })
})
</code></pre>
<h4 id="heading-avoid-using-synchronous-code"><strong>Avoid using synchronous code</strong></h4>
<p>Synchronous code also known as blocking code, because it blocks the execution until they are executed.</p>
<p>So avoid using synchronous functions or methods that might take milliseconds or microseconds. For a high traffic website it will compound and may lead to high latency or response time of the API requests.</p>
<p>Don’t use them in production especially :)</p>
<p>Many Node.js modules come with both <code>.sync</code> and <code>.async</code> methods, so use async in production.</p>
<p>But, if you still want to use a synchronous API use <code>--trace-sync-io</code> command-line flag. It will print a warning and a stack trace whenever your application uses a synchronous API.</p>
<p>For more on the fundamentals of error handling, see:</p>
<ul>
<li><a target="_blank" href="https://www.joyent.com/developers/node/design/errors">Error Handling in Node.js</a></li>
<li><a target="_blank" href="https://strongloop.com/strongblog/robust-node-applications-error-handling/">Building Robust Node Applications: Error Handling</a> (StrongLoop blog)</li>
</ul>
<blockquote>
<p>_What you should <strong>not</strong> do is to listen for the <code>uncaughtException</code> event, emitted when an exception bubbles all the way back to the event loop. Using it is generally <a target="_blank" href="https://nodejs.org/api/process.html#process_event_uncaughtexception">not preferred</a>._</p>
</blockquote>
<h3 id="heading-logging-properly"><strong>Logging properly</strong></h3>
<p>Logging is essential for debugging and app activity. It is used mainly for development purposes. We use <code>console.log</code> and <code>console.error</code> but these are <a target="_blank" href="https://nodejs.org/api/console.html#console_console_1">synchronous functions</a>.</p>
<h4 id="heading-for-debugging-purposes"><strong>For Debugging purposes</strong></h4>
<p>You can use a module like <a target="_blank" href="https://www.npmjs.com/package/debug">debug</a>. This module enables you to use the DEBUG environment variable to control what debug messages are sent to <code>console.err()</code>, if any.</p>
<h4 id="heading-for-app-activity"><strong>For app activity</strong></h4>
<p>One way is to write them to the database.</p>
<p>Check out <a target="_blank" href="https://medium.freecodecamp.org/how-to-log-a-node-js-api-in-an-express-js-app-with-mongoose-plugins-efe32717b59">How I used mongoose plugins to do auditing of my application</a> .</p>
<p>Another way is to write to a file <strong>OR</strong> use a logging library like <a target="_blank" href="https://www.npmjs.com/package/winston">Winston</a> or <a target="_blank" href="https://www.npmjs.com/package/bunyan">Bunyan</a>. For a detailed comparison of these two libraries, see the StrongLoop blog post <a target="_blank" href="https://strongloop.com/strongblog/compare-node-js-logging-winston-bunyan/">Comparing Winston and Bunyan Node.js Logging</a>.</p>
<h3 id="heading-require-mess">require(“./../../../../../../”) mess</h3>
<p>There are different workarounds for this problem.</p>
<p>If you find any module getting popular and if it has logical independence from the application, you can convert it to private npm module and use it like any other module in package.json.</p>
<p>OR</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> path  = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);
<span class="hljs-keyword">const</span> HOMEDIR  = path.join(__dirname,<span class="hljs-string">'..'</span>,<span class="hljs-string">'..'</span>);
</code></pre>
<p>where <code>__dirname</code> is the built-in variable that names the directory that contains the current file, and <code>..</code> ,<code>..</code>is the requisite number of steps up the directory tree to reach the root of the project.</p>
<p>From there it is simply:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> foo = <span class="hljs-built_in">require</span>(path.join(HOMEDIR,<span class="hljs-string">'lib'</span>,<span class="hljs-string">'foo'</span>));
<span class="hljs-keyword">const</span> bar = <span class="hljs-built_in">require</span>(path.join(HOMEDIR,<span class="hljs-string">'lib'</span>,<span class="hljs-string">'foo'</span>,<span class="hljs-string">'bar'</span>));
</code></pre>
<p>to load an arbitrary file within the project.</p>
<p>Let me know in the comment below if you have better ideas :)</p>
<h3 id="heading-set-nodeenv-to-production">Set NODE_ENV to “production”</h3>
<p>The <strong>NODE_ENV</strong> environment variable specifies the environment in which an application is running (usually, development or production). One of the simplest things you can do to improve performance is to set <code>**NODE_ENV**</code>to “production.”</p>
<p>Setting <strong>NODE_ENV</strong> to “<strong>production</strong>” makes Express:</p>
<ul>
<li>Cache view templates.</li>
<li>Cache CSS files generated from CSS extensions.</li>
<li>Generate less verbose error messages.</li>
</ul>
<p><a target="_blank" href="http://apmblog.dynatrace.com/2015/07/22/the-drastic-effects-of-omitting-node_env-in-your-express-js-applications/">Tests indicate</a> that just doing this can improve app performance by a factor of three!</p>
<h3 id="heading-using-process-manager"><strong>Using Process Manager</strong></h3>
<p>For production, you should not simply use <code>node app.j</code> — if your app crashes, it will be offline until you restart it.</p>
<p>The most popular process managers for Node are:</p>
<ul>
<li><a target="_blank" href="http://strong-pm.io/">StrongLoop Process Manager</a></li>
<li><a target="_blank" href="https://github.com/Unitech/pm2">PM2</a></li>
<li><a target="_blank" href="https://www.npmjs.com/package/forever">Forever</a></li>
</ul>
<p>I personally use <strong>PM2.</strong></p>
<p>For a feature-by-feature comparison of the three process managers, see <a target="_blank" href="http://strong-pm.io/compare/">http://strong-pm.io/compare/</a>. For a more detailed introduction to all three, see <a target="_blank" href="https://expressjs.com/en/advanced/pm.html">Process managers for Express apps</a>.</p>
<h3 id="heading-run-your-app-in-a-cluster">Run your app in a cluster</h3>
<p>In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes.</p>
<p>A cluster runs multiple instances of the app, ideally one instance on each CPU core. This distributes the load and tasks among the instances.</p>
<h4 id="heading-using-nodes-cluster-module">Using Node’s cluster module</h4>
<p>Clustering is made possible with Node’s <a target="_blank" href="https://nodejs.org/dist/latest-v4.x/docs/api/cluster.html">cluster module</a>. This enables a master process to spawn worker processes. It distributes incoming connections among the workers.</p>
<p>However, rather than using this module directly, it’s far better to use one of the many tools out there that do it for you automatically. For example <a target="_blank" href="https://www.npmjs.com/package/node-pm">node-pm</a> or <a target="_blank" href="https://www.npmjs.com/package/cluster-service">cluster-service</a>.</p>
<h4 id="heading-using-pm2">Using PM2</h4>
<p>For pm2 you can use cluster directly through a command. For example,</p>
<pre><code class="lang-js"># Start <span class="hljs-number">4</span> worker processes
pm2 start app.js -i <span class="hljs-number">4</span>

# Auto-detect number <span class="hljs-keyword">of</span> available CPUs and start that many worker processes
pm2 start app.js -i max
</code></pre>
<p>If you encounter any problems, feel free to <em>get in <a target="_blank" href="https://101node.io">touch</a> or comment below.</em><br>I would be happy to help :)</p>
<p><em>Don’t hesitate to clap if you considered this a worthwhile read!</em></p>
<p>References: <a target="_blank" href="https://expressjs.com/en/advanced/best-practice-performance.html">https://expressjs.com/en/advanced/best-practice-performance.html</a></p>
<p><em>Originally published at <a target="_blank" href="https://101node.io/blog/how-to-write-production-ready-node-express-app/">101node.io</a> on September 30, 2018.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to make input validation simple and clean in your Express.js app ]]>
                </title>
                <description>
                    <![CDATA[ By Shailesh Shekhawat This tutorial requires prior knowledge of using the expressjs framework Why do we need server-side validation? Your client side validation is not enough and it may be subverted More prone to Man in middle attacks, and the ser... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-make-input-validation-simple-and-clean-in-your-express-js-app-ea9b5ff5a8a7/</link>
                <guid isPermaLink="false">66d46152246e57ac83a2c7e1</guid>
                
                    <category>
                        <![CDATA[ Express.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 18 Sep 2018 22:08:42 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*e0mCbx2PuNysG54g0B1gRg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Shailesh Shekhawat</p>
<blockquote>
<p>This tutorial requires prior knowledge of using the <a target="_blank" href="http://expressjs.com">expressjs</a> framework</p>
</blockquote>
<h4 id="heading-why-do-we-need-server-side-validation">Why do we need server-side validation?</h4>
<ul>
<li>Your client side validation is not enough and it may be subverted</li>
<li>More prone to <a target="_blank" href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack">Man in middle attacks</a>, and the server should never trust the client-side</li>
<li>A user can turn off client-side JavaScript validation and manipulate the data</li>
</ul>
<p>If you have been building web applications using an Express framework or any other Node.js framework, validation plays a crucial role in any web app which requires you to validate the request <code>body</code> <code>param</code> <code>query</code>.</p>
<p>Writing your own middleware function can be cumbersome if</p>
<ul>
<li>you want to move fast while maintaining the quality of code or</li>
<li>you want to avoid using <code>**if** (**req**.body.head)</code> or <code>**if** (**req**.params.isCool)</code> in your main controller function where you define business logic</li>
</ul>
<p>In this tutorial, you’ll learn how to validate input in an Express.js app using an open source and popular module called <a target="_blank" href="https://github.com/ctavan/express-validator">express-validator</a>.</p>
<h3 id="heading-introduction-to-express-validator">Introduction to express-validator</h3>
<p>The definition on Github says:</p>
<blockquote>
<p>express-validator is a set of <a target="_blank" href="http://expressjs.com/">express.js</a> middlewares that wraps <a target="_blank" href="https://github.com/chriso/validator.js">validator.js</a> validator and sanitizer functions.</p>
</blockquote>
<p>The module implements five important API’s:</p>
<ul>
<li>Check API</li>
<li>Filter API</li>
<li>Sanitization chain API</li>
<li>Validation chain API</li>
<li>Validation Result API</li>
</ul>
<p>Let's take a look at a basic user <code>route</code> without any validation module to create a user: <code>/route/user.js</code></p>
<pre><code class="lang-js"><span class="hljs-comment">/**
* <span class="hljs-doctag">@api <span class="hljs-type">{post}</span> </span>/api/user Create user
* <span class="hljs-doctag">@apiName </span>Create new user
* <span class="hljs-doctag">@apiPermission <span class="hljs-variable">admin</span></span>
* <span class="hljs-doctag">@apiGroup <span class="hljs-variable">User</span></span>
*
* <span class="hljs-doctag">@apiParam  <span class="hljs-type">{String}</span> </span>[userName] username
* <span class="hljs-doctag">@apiParam  <span class="hljs-type">{String}</span> </span>[email] Email
* <span class="hljs-doctag">@apiParam  <span class="hljs-type">{String}</span> </span>[phone] Phone number
* <span class="hljs-doctag">@apiParam  <span class="hljs-type">{String}</span> </span>[status] Status
*
* <span class="hljs-doctag">@apiSuccess </span>(200) {Object} mixed `User` object
*/</span>

router.post(<span class="hljs-string">'/'</span>, userController.createUser)
</code></pre>
<p>Now in user controller <code>/controllers/user.js</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./models/user'</span>)

<span class="hljs-built_in">exports</span>.createUser = <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {
  <span class="hljs-comment">/** Here you need to validate user input. 
   Let's say only Name and email are required field
 */</span>

  <span class="hljs-keyword">const</span> { userName, email, phone, status } = req.body
  <span class="hljs-keyword">if</span> (userName &amp;&amp; email &amp;&amp;  isValidEmail(email)) { 

    <span class="hljs-comment">// isValidEmail is some custom email function to validate email which you might need write on your own or use npm module</span>
    User.create({
      userName,
      email,
      phone,
      status,   
    })
    .then(<span class="hljs-function"><span class="hljs-params">user</span> =&gt;</span> res.json(user))
    .catch(next)
  }
}
</code></pre>
<p>The above code is just a basic example of validating fields on your own.</p>
<p>You can handle some validations in your user model using Mongoose. For best practices, we want to make sure validation happens before business logic.</p>
<p><a target="_blank" href="https://github.com/ctavan/express-validator">express-validator</a> will take care of all these validations and the <a target="_blank" href="https://www.quora.com/What-does-it-mean-to-sanitize-a-field-How-is-that-related-to-escaping-as-in-entering-in-malicious-input-that-escapes-or-something">sanitization</a> of inputs as well.</p>
<h4 id="heading-installation"><strong>Installation</strong></h4>
<pre><code class="lang-bash">npm install --save express-validator
</code></pre>
<p>Include <strong>module</strong> in your main <code>server.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>)
<span class="hljs-keyword">const</span> bodyParser = <span class="hljs-built_in">require</span>(<span class="hljs-string">'body-parser'</span>)
<span class="hljs-keyword">const</span> expressValidator = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-validator'</span>)
<span class="hljs-keyword">const</span> app = express()
<span class="hljs-keyword">const</span> router = express.Router()

app.use(bodyParser.json())

app.use(expressValidator())

app.use(<span class="hljs-string">'/api'</span>, router)
</code></pre>
<p>Now using <a target="_blank" href="https://github.com/ctavan/express-validator">express-validator</a>, your <code>/routes/user.js</code> will be like this:</p>
<pre><code class="lang-js">router.post(
  <span class="hljs-string">'/'</span>, 
  userController.validate(<span class="hljs-string">'createUser'</span>), 
  userController.createUser,
)
</code></pre>
<p>Here <code>userController.validate</code> is a middleware function which is explained below. It accepts the <code>method</code> name for which the validation will be used.</p>
<p>Let’s create a middleware function <code>validate()</code>in our<code>/controllers/user.js</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { body } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-validator/check'</span>)

<span class="hljs-built_in">exports</span>.validate = <span class="hljs-function">(<span class="hljs-params">method</span>) =&gt;</span> {
  <span class="hljs-keyword">switch</span> (method) {
    <span class="hljs-keyword">case</span> <span class="hljs-string">'createUser'</span>: {
     <span class="hljs-keyword">return</span> [ 
        body(<span class="hljs-string">'userName'</span>, <span class="hljs-string">'userName doesn'</span>t exists<span class="hljs-string">').exists(),
        body('</span>email<span class="hljs-string">', '</span>Invalid email<span class="hljs-string">').exists().isEmail(),
        body('</span>phone<span class="hljs-string">').optional().isInt(),
        body('</span>status<span class="hljs-string">').optional().isIn(['</span>enabled<span class="hljs-string">', '</span>disabled<span class="hljs-string">'])
       ]   
    }
  }
}</span>
</code></pre>
<p>Please refer to <a target="_blank" href="https://express-validator.github.io/docs/check-api.html">this article</a> to know more about function definition and its use.</p>
<p>The <code>body</code> function will only validate <code>req.body</code> and takes two arguments. First is the <code>property name</code>. Second is your custom <code>message</code> that will be shown if validation fails. If you don’t provide a custom message, then the default message will be used.</p>
<p>As you can see, for a <code>required</code> field we are using the <code>.exists()</code> method. We are using <code>.optional()</code>for an <code>optional</code> field. Similarly <code>isEmail()</code> <code>isInt()</code> is used to validate <code>email</code> and <code>integer</code>.</p>
<p>If you want an input field to include only certain values, then you can use <code>.isIn([])</code>. This takes an <code>array</code> of values, and if you receive values other than the above, then an error will be thrown.</p>
<p>For example, the status field in the above code snippet can only have an <code>enabled</code> or <code>disabled</code> value. If you provide any value other than that, an error will be thrown.</p>
<p>In <code>/controllers/user.js</code> let’s write a<code>**createUser**</code> function where you can write business logic. It will be called after <code>**validate()**</code> with the result of the validations.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { validationResult } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-validator/check'</span>);

<span class="hljs-built_in">exports</span>.createUser = <span class="hljs-keyword">async</span> (req, res, next) =&gt; {
   <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> errors = validationResult(req); <span class="hljs-comment">// Finds the validation errors in this request and wraps them in an object with handy functions</span>

      <span class="hljs-keyword">if</span> (!errors.isEmpty()) {
        res.status(<span class="hljs-number">422</span>).json({ <span class="hljs-attr">errors</span>: errors.array() });
        <span class="hljs-keyword">return</span>;
      }

      <span class="hljs-keyword">const</span> { userName, email, phone, status } = req.body

      <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.create({

        userName,

        email,

        phone,

        status,   
      })

      res.json(user)
   } <span class="hljs-keyword">catch</span>(err) {
     <span class="hljs-keyword">return</span> next(err)
   }
}
</code></pre>
<h4 id="heading-if-you-are-wondering-what-is-validationresultreq">If you are wondering what is validationResult(req)?</h4>
<p><strong>This function</strong> <strong>finds the validation errors in this request and wraps them in an object with handy functions</strong></p>
<p>Now whenever request includes invalid body params or <code>userName</code> field is missing in <code>req.body</code>, your server will respond like this:</p>
<pre><code class="lang-js">{
  <span class="hljs-string">"errors"</span>: [{
    <span class="hljs-string">"location"</span>: <span class="hljs-string">"body"</span>,
    <span class="hljs-string">"msg"</span>: <span class="hljs-string">"userName is required"</span>,
    <span class="hljs-string">"param"</span>: <span class="hljs-string">"userName"</span>
  }]
}
</code></pre>
<p>So if <code>userName</code> or <code>email</code> failed to satisfy the validation then each error returned by <code>.array()</code>method has the following format by default:</p>
<pre><code class="lang-js">{   
  <span class="hljs-string">"msg"</span>: <span class="hljs-string">"The error message"</span>,

  <span class="hljs-string">"param"</span>: <span class="hljs-string">"param name"</span>, 

  <span class="hljs-string">"value"</span>: <span class="hljs-string">"param value"</span>,   
  <span class="hljs-comment">// Location of the param that generated this error.   </span>
  <span class="hljs-comment">// It's either body, query, params, cookies or headers.   </span>
  <span class="hljs-string">"location"</span>: <span class="hljs-string">"body"</span>,    

  <span class="hljs-comment">// nestedErrors only exist when using the oneOf function</span>
  <span class="hljs-string">"nestedErrors"</span>: [{ ... }] 
}
</code></pre>
<p>As you can see, this module really helps us take care of most of the validations on its own. It maintains code quality as well, and focuses mainly on business logic.</p>
<p>This was the introduction to input validation using the <strong>express-validator</strong> module and check out how to validate an array of the item and make your own custom validation in <a target="_blank" href="https://www.freecodecamp.org/news/how-to-perform-custom-validation-in-your-express-js-app-432eb423510f/">Part 2</a> of this series.</p>
<p>I have tried my best and hope I covered enough to explain it in detail so that you can get started.</p>
<p>If you encounter any problems, feel free to <em>get in <a target="_blank" href="https://101node.io">touch</a> or comment below.</em><br>I would be happy to help :)</p>
<p>Follow <a target="_blank" href="https://www.freecodecamp.org/news/author/thatshailesh/">Shailesh Shekhawat</a> to get notified whenever I publish a new post.</p>
<p><em>Don’t hesitate to clap if you considered this a worthwhile read!</em></p>
<p><em>Originally published at <a target="_blank" href="https://101node.io/blog/how-to-validate-inputs-in-express-js-app/">101node.io</a> on September 2, 2018.</em></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
