{"id":73165,"date":"2019-11-23T04:17:55","date_gmt":"2019-11-23T11:17:55","guid":{"rendered":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/"},"modified":"2019-11-23T04:17:55","modified_gmt":"2019-11-23T11:17:55","slug":"getting-started-with-an-express-and-es6-javascript-stack","status":"publish","type":"post","link":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/","title":{"rendered":"Getting Started With An Express And ES6+ JavaScript Stack"},"content":{"rendered":"<link rel=\"canonical\" href=\"https:\/\/www.smashingmagazine.com\/2019\/11\/express-es6-javascript-stack-mongodb-mongoose-servers\/\"><title>Getting Started With An Express And ES6+ JavaScript Stack<\/title><\/p>\n<article>\n<header>\n<h1>Getting Started With An Express And ES6+ JavaScript Stack<\/h1>\n<address>Jamie Corkhill<\/address>\n<p>                  <time datetime=\"2019-11-22T12:00:00+00:00\">2019-11-22T12:00:00+00:00<\/time><time datetime=\"2019-11-22T12:00:00+00:00\">2019-11-23T11:08:10+00:00<\/time><\/header>\n<p>This article is the second part in a series, with part one located <a href=\"https:\/\/www.smashingmagazine.com\/2019\/02\/node-api-http-es6-javascript\/\">here<\/a>, which provided basic and (hopefully) intuitive insight into Node.js, ES6+ JavaScript, Callback Functions, Arrow Functions, APIs, the HTTP Protocol, JSON, MongoDB, and more.<\/p>\n<p>In this article, we\u2019ll build upon the skills we attained in the previous one, learning how to implement and deploy a MongoDB Database for storing user booklist information, build an API with Node.js and the Express Web Application framework to expose that database and perform CRUD Operations upon it, and more. Along the way, we\u2019ll discuss ES6 Object Destructuring, ES6 Object Shorthand, the Async\/Await syntax, the Spread Operator, and we\u2019ll take a brief look at CORS, the Same Origin Policy, and more.<\/p>\n<p>In a later article, we\u2019ll refactor our codebase as to separate concerns by utilizing three-layer architecture and achieving Inversion of Control via Dependency Injection, we\u2019ll perform JSON Web Token and Firebase Authentication based security and access control, learn how to securely store passwords, and employ AWS Simple Storage Service to store user avatars with Node.js Buffers and Streams \u2014 all the while utilizing PostgreSQL for data persistence. Along the way, we will re-write our codebase from the ground up in TypeScript as to examine Classical OOP concepts (such as Polymorphism, Inheritance, Composition, and so on) and even design patterns like Factories and Adapters.<\/p>\n<div data-component=\"FeaturePanel\" data-audience=\"non-subscriber\" data-remove=\"true\"><\/div>\n<h3>A Word Of Warning<\/h3>\n<p>There is a problem with the majority of articles discussing Node.js out there today. Most of them, not all of them, go no further than depicting how to setup Express Routing, integrate Mongoose, and perhaps utilize JSON Web Token Authentication. The problem is that they don\u2019t talk about architecture, or security best practices, or about clean coding principles, or ACID Compliance, Relational Databases, Fifth Normal Form, the CAP Theorem or Transactions. It\u2019s either assumed that you know about all of that coming in, or that you won\u2019t be building projects large or popular enough to warrant that aforementioned knowledge.<\/p>\n<p>There appear to be a few different types of Node developers \u2014 among others, some are new to programming in general, and others come from a long history of enterprise development with C# and the .NET Framework or the Java Spring Framework. The majority of articles cater to the former group.<\/p>\n<p>In this article, I\u2019m going to do exactly what I just stated that too many articles are doing, but in a follow up article, we are going to refactor our codebase entirely, permitting me to explain principles such as Dependency Injection, Three-Layer Architecture (Controller\/Service\/Repository), Data Mapping and Active Record, design patterns, unit, integration, and mutation testing, SOLID Principles,  Unit of Work, coding against interfaces, security best practices like HSTS, CSRF, NoSQL and SQL Injection Prevention, and so on. We will also migrate from MongoDB to PostgreSQL, using the simple query builder Knex instead of an ORM \u2014 permitting us to build our own data access infrastructure and to get close up and personal with the Structured Query Language, the different types of relations (One-to-One, Many-to-Many, etc.), and more. This article, then, should appeal to beginners, but the next few should cater to more intermediate developers looking to improve their architecture.<\/p>\n<p>In this one, we are only going to worry about persisting book data. We won\u2019t handle user authentication, password hashing, architecture, or anything complex like that. All of that will come in the next and future articles. For now, and very basically, we\u2019ll just build a method by which to permit a client to communicate with our web server via the HTTP Protocol as to save book information in a database.<\/p>\n<p><strong>Note<\/strong>: <em>I\u2019ve intentionally kept it extremely simple and perhaps not all that practical here because this article, in and of itself, is extremely long, for I have taken the liberty of deviating to discuss supplemental topics. Thus, we will progressively improve the quality and complexity of the API over this series, but again, because I\u2019m considering this as one of your first introductions to Express, I\u2019m intentionally keeping things extremely simple.<\/em><\/p>\n<ol>\n<li><a href=\"https:\/\/www.smashingmagazine.com\/articles\/#es6-object-destructuring\">ES6 Object Destructuring<\/a><\/li>\n<li><a href=\"https:\/\/www.smashingmagazine.com\/articles\/#es6-object-shorthand\">ES6 Object Shorthand<\/a><\/li>\n<li><a href=\"https:\/\/www.smashingmagazine.com\/articles\/#es6-spread-operator\">ES6 Spread Operator (&#8230;)<\/a><\/li>\n<li>Coming up&#8230;<\/li>\n<\/ol>\n<h3>ES6 Object Destructuring<\/h3>\n<p>ES6 Object Destructuring, or Destructuring Assignment Syntax, is a method by which to extract or unpack values from arrays or objects into their own variables. We\u2019ll start with object properties and then discuss array elements.<\/p>\n<pre><code>const person = {\n    name: 'Richard P. Feynman',\n    occupation: 'Theoretical Physicist' \n};\n\n\/\/ Log properties:\nconsole.log('Name:', person.name); \nconsole.log('Occupation:', person.occupation);<\/code><\/pre>\n<p>Such an operation is quite primitive, but it can be somewhat of a hassle considering we have to keep referencing <code>person.something<\/code> everywhere. Suppose there were 10 other places throughout our code where we had to do that \u2014 it would get quite arduous quite fast. A method of brevity would be to assign these values to their own variables.<\/p>\n<pre><code>const person = {\n    name: 'Richard P. Feynman',\n    occupation: 'Theoretical Physicist' \n};\n\nconst personName = person.name;\nconst personOccupation = person.occupation;\n\n\/\/ Log properties:\nconsole.log('Name:', personName); \nconsole.log('Occupation:', personOccupation);<\/code><\/pre>\n<p>Perhaps this looks reasonable, but what if we had 10 other properties nested on the <code>person<\/code> object as well? That would be many needless lines just to assign values to variables \u2014 at which point we\u2019re in danger because if object properties are mutated, our variables won\u2019t reflect that change (remember, only references to the object are immutable with <code>const<\/code> assignment, not the object\u2019s properties), so basically, we can no longer keep \u201cstate\u201d (and I\u2019m using that word loosely) in sync. Pass by reference vs pass by value might come into play here, but I don\u2019t want to stray too far from the scope of this section.<\/p>\n<p>ES6 Object Destructing basically lets us do this:<\/p>\n<pre><code>const person = {\n    name: 'Richard P. Feynman',\n    occupation: 'Theoretical Physicist' \n};\n\n\/\/ This is new. It\u2019s called Object Destructuring.\nconst { name, occupation } = person;\n\n\/\/ Log properties:\nconsole.log('Name:', name); \nconsole.log('Occupation:', occupation);<\/code><\/pre>\n<p>We are <strong>not<\/strong> creating a new object\/object literal, we are unpacking the <code>name<\/code> and <code>occupation<\/code> properties from the original object and putting them into their own variables of the same name. The names we use have to match the property names that we wish to extract.<\/p>\n<p>Again, the syntax <code>const { a, b } = someObject;<\/code>  is specifically saying that we expect some property <code>a<\/code> and some property <code>b<\/code> to exist within <code>someObject<\/code> (i.e, <code>someObject<\/code> could be <code>{ a: 'dataA', b: 'dataB' }<\/code>, for example) and that we want to place whatever the values are of those keys\/properties within <code>const<\/code> variables of the same name. That\u2019s why the syntax above would provide us with two variables <code>const a = someObject.a<\/code> and <code>const b = someObject.b<\/code> .<\/p>\n<p>What that means is that there are two sides to Object Destructuring. The \u201cTemplate\u201d side and the \u201cSource\u201d side, where the <code>const { a, b }<\/code> side (the left-hand side) is the <em>template<\/em> and the <code>someObject<\/code> side (the right-hand side) is the <em>source<\/em> side \u2014 which  makes sense \u2014 we are defining a structure or \u201ctemplate\u201d on the left that mirrors the data on \u201csource\u201d side.<\/p>\n<p>Again, just to make this clear, here are a few examples:<\/p>\n<div>\n<pre><code>\/\/ ----- Destructure from Object Variable with const ----- \/\/\nconst objOne = {\n    a: 'dataA', \n    b: 'dataB'\n};\n\n\/\/ Destructure\nconst { a, b } = objOne;\n\nconsole.log(a); \/\/ dataA\nconsole.log(b); \/\/ dataB\n\n\/\/ ----- Destructure from Object Variable with let ----- \/\/\nlet objTwo = {\n    c: 'dataC', \n    d: 'dataD'\n};\n\n\/\/ Destructure\nlet { c, d } = objTwo;\n\nconsole.log(c); \/\/ dataC\nconsole.log(d); \/\/ dataD\n\n\/\/ Destructure from Object Literal with const ----- \/\/\nconst { e, f } = { e: 'dataE', f: 'dataF' }; \/\/ <\/code><\/pre>\n<\/div>\n<p>In the case of nested properties, mirror the same structure in your destructing assignment:<\/p>\n<div>\n<pre><code>const person = {\n    name:  'Richard P. Feynman',\n    occupation: {\n        type:  'Theoretical Physicist',\n        location: {\n            lat:  1,\n            lng:  2\n        }\n    }\n};\n\n\/\/ Attempt one:\nconst { name, occupation } = person;\n\nconsole.log(name); \/\/ Richard P. Feynman\nconsole.log(occupation); \/\/ The entire `occupation` object.\n\n\/\/ Attempt two:\nconst { occupation: { type, location } } = person;\n\nconsole.log(type); \/\/ Theoretical Physicist\nconsole.log(location) \/\/ The entire `location` object.\n\n\/\/ Attempt three:\nconst { occupation: {  location: { lat, lng } } } = person;\n\nconsole.log(lat); \/\/ 1\nconsole.log(lng); \/\/ 2<\/code><\/pre>\n<\/div>\n<p>As you can see, the properties you decide to pull off are optional, and to unpack nested properties, simply mirror the structure of the original object (the source) in the template side of your destructuring syntax. If you attempt to destructure a property that does not exist on the original object, that value will be undefined.<\/p>\n<p>We can additionally destructure a variable without first declaring it \u2014 assignment without declaration \u2014 using the following syntax:<\/p>\n<pre><code>let name, occupation;\n\nconst person = {\n    name: 'Richard P. Feynman',\n    occupation: 'Theoretical Physicist' \n};\n\n;({ name, occupation } = person);\n\nconsole.log(name); \/\/ Richard P. Feynman\nconsole.log(occupation); \/\/ Theoretical Physicist<\/code><\/pre>\n<p>We precede the expression with a semicolon as to ensure we don\u2019t accidentally create an IIFE (Immediately Invoked Function Expression) with a function on a previous line (if one such function exists), and the parentheses around the assignment statement are required as to stop JavaScript from treating your left-hand (template) side as a block.<\/p>\n<p>A very common use case of destructuring exists within function arguments:<\/p>\n<pre><code>const config = {\n    baseUrl: '<baseURL>',\n    awsBucket: '<bucket>',\n    secret: '<secret-key>' \/\/ <- Make this an env var.\n};\n\n\/\/ Destructures `baseUrl` and `awsBucket` off `config`.\nconst performOperation = ({ baseUrl, awsBucket }) => {\n    fetch(baseUrl).then(() => console.log('Done'));\n    console.log(awsBucket); \/\/ <bucket>\n};\n\nperformOperation(config);<\/code><\/pre>\n<p>As you can see, we could have just used the normal destructuring syntax we are now used to inside of the function, like this:<\/p>\n<pre><code>const config = {\n    baseUrl: '<baseURL>',\n    awsBucket: '<bucket>',\n    secret: '<secret-key>' \/\/ <- Make this an env var.\n};\n\nconst performOperation = someConfig => {\n    const { baseUrl, awsBucket } = someConfig;\n    fetch(baseUrl).then(() => console.log('Done'));\n    console.log(awsBucket); \/\/ <bucket>\n};\n\nperformOperation(config);<\/code><\/pre>\n<p>But placing said syntax inside the function signature performs destructuring automatically and saves us a line.<\/p>\n<p>A real-world use case of this is in React Functional Components for <code>props<\/code>:<\/p>\n<pre><code>import React from 'react';\n\n\/\/ Destructure `titleText` and `secondaryText` from `props`.\nexport default ({ titleText, secondaryText }) => (\n    <div>\n        <h1>{titleText}<\/h1>\n        <h3>{secondaryText}<\/h3>\n    <\/div>\n);<\/code><\/pre>\n<p>As opposed to:<\/p>\n<pre><code>import React from 'react';\n\nexport default props => (\n    <div>\n        <h1>{props.titleText}<\/h1>\n        <h3>{props.secondaryText}<\/h3>\n    <\/div>\n);<\/code><\/pre>\n<p>In both cases, we can set default values to the properties as well:<\/p>\n<div>\n<pre><code>const personOne = {\n    name:  'User One',\n    password:  'BCrypt Hash'\n};\n\nconst personTwo = {\n    password:  'BCrypt Hash'\n};\n\nconst createUser = ({ name = 'Anonymous', password }) => {\n    if (!password) throw  new  Error('InvalidArgumentException');\n    \n    console.log(name);\n    console.log(password);\n    \n    return {\n        id: Math.random().toString(36) \/\/ <\/code><\/pre>\n<\/div>\n<p>As you can see, in the event that <code>name<\/code> is not present when destructured, we provide it a default value. We can do this with the previous syntax as well:<\/p>\n<pre><code>const { a, b, c = 'Default' } = { a: 'dataA', b: 'dataB' };\nconsole.log(a); \/\/ dataA\nconsole.log(b); \/\/ dataB\nconsole.log(c); \/\/ Default<\/code><\/pre>\n<p>Arrays can be destructured too:<\/p>\n<pre><code>const myArr = [4, 3];\n\n\/\/ Destructuring happens here.\nconst [valOne, valTwo] = myArr;\n\nconsole.log(valOne); \/\/ 4\nconsole.log(valTwo); \/\/ 3\n\n\/\/ ----- Destructuring without assignment: ----- \/\/\nlet a, b;\n\n\/\/ Destructuring happens here.\n;([a, b] = [10, 2]);\n\nconsole.log(a + b); \/\/ 12<\/code><\/pre>\n<p>A practical reason for array destructuring occurs with React Hooks. (And there are many other reasons, I\u2019m just using React as an example).<\/p>\n<pre><code>import React, { useState } from \"react\";\n\nexport default () => {\n  const [buttonText, setButtonText] = useState(\"Default\");\n\n  return (\n    <button onClick={() => setButtonText(\"Toggled\")}>\n      {buttonText}\n    <\/button>\n  );\n}<\/code><\/pre>\n<p>Notice <code>useState<\/code> is being destructured off the export, and the array functions\/values are being destructured off the <code>useState<\/code> hook. Again, don\u2019t worry if the above doesn\u2019t make sense \u2014 you\u2019d have to understand React \u2014 and I\u2019m merely using it as an example.<\/p>\n<p>While there is more to ES6 Object Destructuring, I\u2019ll cover one more topic here: Destructuring Renaming, which is useful to prevent scope collisions or variable shadows, etc. Suppose we want to destructure a property called <code>name<\/code> from an object called <code>person<\/code>, but there is already a variable by the name of <code>name<\/code> in scope. We can rename on the fly with a colon:<\/p>\n<div>\n<pre><code>\/\/ JS Destructuring Naming Collision Example:\nconst name = 'Jamie Corkhill';\n\nconst person = {\n    name: 'Alan Touring'\n};\n\n\/\/ Rename `name` from `person` to `personName` after destructuring.\nconst { name: personName } = person;\n\nconsole.log(name); \/\/ Jamie Corkhill <\/code><\/pre>\n<\/div>\n<p>Finally, we can set default values with renaming too:<\/p>\n<pre><code>const name = 'Jamie Corkhill';\n\nconst person = {\n    location: 'New York City, United States'\n};\n\nconst { name: personName = 'Anonymous', location } = person;\n\nconsole.log(name); \/\/ Jamie Corkhill\nconsole.log(personName); \/\/ Anonymous\nconsole.log(location); \/\/ New York City, United States<\/code><\/pre>\n<p>As you can see, in this case, <code>name<\/code> from <code>person<\/code> (<code>person.name<\/code>) will be renamed to <code>personName<\/code> and set to the default value of <code>Anonymous<\/code> if non-existent.<\/p>\n<p>And of course, the same can be performed in function signatures:<\/p>\n<div>\n<pre><code>const personOne = {\n    name:  'User One',\n    password:  'BCrypt Hash'\n};\n\nconst personTwo = {\n    password:  'BCrypt Hash'\n};\n\nconst  createUser  = ({  name: personName =  'Anonymous', password }) => {\n    if (!password) throw  new  Error('InvalidArgumentException');\n    console.log(personName);\n    console.log(password);\n\n    return {\n        id: Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15),\n        name: personName,\n        password: password \/\/ <\/code><\/pre>\n<\/div>\n<div><\/div>\n<h3>ES6 Object Shorthand<\/h3>\n<p>Suppose you have the following factory: (we\u2019ll cover factories later)<\/p>\n<pre><code>const createPersonFactory = (name, location, position) => ({\n    name: name,\n    location: location,\n    position: position\n});<\/code><\/pre>\n<p>One might use this factory to create a <code>person<\/code> object, as follows. Also, note that the factory is implicitly returning an object, evident by the parentheses around the brackets of the Arrow Function.<\/p>\n<div>\n<pre><code>const person = createPersonFactory('Jamie', 'Texas', 'Developer');\nconsole.log(person); \/\/ { ... }<\/code><\/pre>\n<\/div>\n<p>That\u2019s what we already know from the ES5 Object Literal Syntax. Notice, however, in the factory function, that the <em>value of each property is the same name as the property identifier (key) itself.<\/em> That is \u2014 <code>location: location<\/code> or <code>name: name<\/code>. It turned out that that was a pretty common occurrence with JS developers.<\/p>\n<p>With the shorthand syntax from ES6, we may achieve the same result by rewriting the factory as follows:<\/p>\n<pre><code>const createPersonFactory = (name, location, position) => ({\n    name,\n    location,\n    position\n});\n\nconst person = createPersonFactory('Jamie', 'Texas', 'Developer');\nconsole.log(person);<\/code><\/pre>\n<p>Producing the output:<\/p>\n<pre><code>{ name: 'Jamie', location: 'Texas', position: 'Developer' }<\/code><\/pre>\n<p>It\u2019s important to realize that we can only use this shorthand when the object we wish to create is being dynamically created based on variables, <em>where the variable names are the same as the names of the properties to which we want the variables assigned.<\/em><\/p>\n<p>This same syntax works with object values:<\/p>\n<div>\n<pre><code>const createPersonFactory = (name, location, position, extra) => ({\n    name,\n    location,\n    position,\n    extra        \/\/ <\/code><\/pre>\n<\/div>\n<p>Producing the output:<\/p>\n<pre><code>{ \n    name: 'Jamie',\n    location: 'Texas',\n    position: 'Developer',\n    extra: { \n        interests: [ \n            'Mathematics',\n            'Quantum Mechanics',\n            'Spacecraft Launch Systems' \n        ],\n        favoriteLanguages: [ 'JavaScript', 'C#' ]\n     } \n}<\/code><\/pre>\n<p>As a final example, this works with object literals as well:<\/p>\n<pre><code>const id = '314159265358979';\nconst name = 'Archimedes of Syracuse';\nconst location = 'Syracuse';\n\nconst greatMathematician = {\n    id,\n    name,\n    location\n};<\/code><\/pre>\n<h3>ES6 Spread Operator (&#8230;)<\/h3>\n<p>The Spread Operator permits us to do a variety of things, some of which we\u2019ll discuss here.<\/p>\n<p>Firstly, we can spread out properties from one object on to another object:<\/p>\n<pre><code>const myObjOne = { a: 'a', b: 'b' };\nconst myObjTwo = { ...myObjOne }:<\/code><\/pre>\n<p>This has the effect of placing all properties on <code>myObjOne<\/code> onto <code>myObjTwo<\/code>, such that <code>myObjTwo<\/code> is now <code>{ a: 'a', b: 'b' }<\/code>. We can use this method to override previous properties. Suppose a user wants to update their account:<\/p>\n<pre><code>const user = {\n    name: 'John Doe', \n    email: 'john@domain.com',\n    password: '<hash>',\n    bio: 'Lorem ipsum'\n};\n\nconst updates = {\n    password: '<new-hash>',\n    bio: 'Ipsum lorem',\n    email: 'j@domain.com'\n};\n\nconst updatedUser = {\n    ...user,    \/\/ ',   \/\/ Updated\n     bio: 'Ipsum lorem'\n }\n *\/<\/new-hash><\/hash><\/code><\/pre>\n<p>The same can be performed with arrays:<\/p>\n<div>\n<pre><code>const apollo13Astronauts = ['Jim', 'Jack', 'Fred'];\nconst apollo11Astronauts = ['Neil', 'Buz', 'Michael'];\n\nconst unionOfAstronauts = [...apollo13Astronauts, ...apollo11Astronauts];\n\nconsole.log(unionOfAstronauts);\n\/\/ ['Jim', 'Jack', 'Fred', 'Neil', 'Buz, 'Michael'];<\/code><\/pre>\n<\/div>\n<p>Notice here that we created a union of both sets (arrays) by spreading the arrays out into a new array.<\/p>\n<p>There is a lot more to the Rest\/Spread Operator, but it is out of scope for this article. It can be used to attain multiple arguments to a function, for example. If you want to learn more, view the MDN Documentation <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/Spread_syntax\">here<\/a>.<\/p>\n<h3>ES6 Async\/Await<\/h3>\n<p>Async\/Await is a syntax to ease the pain of promise chaining.<\/p>\n<p>The <code>await<\/code> reserved keyword permits you to \u201cawait\u201d the settling of a promise, but it may only be used in functions marked with the <code>async<\/code> keyword. Suppose I have a function that returns a promise. In a new <code>async<\/code> function, I can <code>await<\/code> the result of that promise instead of using <code>.then<\/code> and <code>.catch<\/code>.<\/p>\n<div>\n<pre><code>\/\/ Returns a promise.\nconst myFunctionThatReturnsAPromise = () => {\n    return new Promise((resolve, reject) => {\n        setTimeout(() => resolve('Hello'), 3000);\n    });\n}\n\nconst myAsyncFunction = async () => {\n    const promiseResolutionResult = await myFunctionThatReturnsAPromise();\n    console.log(promiseResolutionResult);\n};\n\n\/\/ Writes the log statement after three seconds.\nmyAsyncFunction();<\/code><\/pre>\n<\/div>\n<p>There are a few things to note here. When we use <code>await<\/code> in an <code>async<\/code> function, only the resolved value goes into the variable on the left-hand side. If the function rejects, that\u2019s an error that we have to catch, as we\u2019ll see in a moment. Additionally, any function marked <code>async<\/code> will, by default, return a promise.<\/p>\n<p>Let\u2019s suppose I needed to make two API calls, one with the response from the former. Using promises and promise chaining, you might do it this way:<\/p>\n<div>\n<pre><code>const makeAPICall = route => new  Promise((resolve, reject) => {\n    console.log(route)\n    resolve(route);\n});\n\nconst main = () => {\n    makeAPICall('\/whatever')\n        .then(response => makeAPICall(response + ' second call'))\n        .then(response => console.log(response + ' logged'))\n        .catch(err => console.error(err))\n};\n\nmain();\n\n\/\/ Result:\n\/* \n\/whatever \n\/whatever second call \n\/whatever second call logged\n*\/<\/code><\/pre>\n<\/div>\n<p>What\u2019s happening here is that we first call <code>makeAPICall<\/code> passing to it <code>\/whatever<\/code>, which gets logged the first time. The promise resolves with that value. Then we call <code>makeAPICall<\/code> again, passing to it <code>\/whatever second call<\/code>, which gets logged, and again, the promise resolves with that new value. Finally, we take that new value <code>\/whatever second call<\/code> which the promise just resolved with, and log it ourselves in the final log, appending on <code>logged<\/code> at the end. If this doesn\u2019t make sense, you should look into promise chaining.<\/p>\n<p>Using <code>async<\/code>\/<code>await<\/code>, we can refactor to the following:<\/p>\n<div>\n<pre><code>const main = async () => {\n    const resultOne = await makeAPICall('\/whatever');\n    const resultTwo = await makeAPICall(resultOne + ' second call');\n    console.log(resultTwo + ' logged');\n};<\/code><\/pre>\n<\/div>\n<p>Here is what will happen. The entire function will stop executing at the very first <code>await<\/code> statement until the promise from the first call to <code>makeAPICall<\/code> resolves, upon resolution, the resolved value will be placed in <code>resultOne<\/code>. When that happens, the function will move to the second <code>await<\/code> statement, again pausing right there for the duration of the promise settling. When the promise resolves, the resolution result will be placed in <code>resultTwo<\/code>. If the idea about function execution sounds blocking, fear not, it\u2019s still asynchronous, and I\u2019ll discuss why in a minute.<\/p>\n<p>This only depicts the \u201chappy\u201d path. In the event that one of the promises reject, we can catch that with try\/catch, for if the promise rejects, an error will be thrown \u2014 which will be whatever error the promise rejected with.<\/p>\n<div>\n<pre><code>const main = async () => {\n    try {\n        const resultOne = await makeAPICall('\/whatever');\n        const resultTwo = await makeAPICall(resultOne + ' second call');\n        console.log(resultTwo + ' logged');\n    } catch (e) {\n        console.log(e)\n    }\n};<\/code><\/pre>\n<\/div>\n<p>As I said earlier, any function declared <code>async<\/code> will return a promise. So, if you want to call an async function from another function, you can use normal promises, or <code>await<\/code> if you declare the calling function <code>async<\/code>. However, if you want to call an <code>async<\/code> function from top-level code and await its result, then you\u2019d have to use <code>.then<\/code> and <code>.catch<\/code>.<\/p>\n<p>For example:<\/p>\n<div>\n<pre><code>const returnNumberOne = async () => 1;\n\nreturnNumberOne().then(value => console.log(value)); \/\/ 1<\/code><\/pre>\n<\/div>\n<p>Or, you could use an Immedieately Invoked Function Expression (IIFE):<\/p>\n<pre><code>(async () => {\n    const value = await returnNumberOne();\n    console.log(value); \/\/ 1\n})();<\/code><\/pre>\n<p>When you use <code>await<\/code> in an <code>async<\/code> function, the execution of the function will stop at that await statement until the promise settles. However, all other functions are free to proceed with execution, thus no extra CPU resources are allocated nor is the thread ever blocked. I\u2019ll say that again \u2014 operations in that specific function at that specific time will stop until the promise settles, but all other functions are free to fire. Consider an HTTP Web Server \u2014 on a per-request basis, all functions are free to fire for all users concurrently as requests are made, it\u2019s just that the async\/await syntax will provide the <em>illusion<\/em> that an operation is <em>synchronous<\/em> and <em>blocking<\/em> as to make promises easier to work with, but again, everything will remain nice and async.<\/p>\n<p>This isn\u2019t all there is to <code>async<\/code>\/<code>await<\/code>, but it should help you to grasp the basic principles.<\/p>\n<h3>Classical OOP Factories<\/h3>\n<p>We are now going to leave the <strong>JavaScript<\/strong> world and enter the <strong>Java<\/strong> world. There can come a time when the creation process of an object (in this case, an instance of a class \u2014 again, Java) is fairly complex or when we want to have different objects produced based upon a series of parameters. An example might be a function that creates different error objects. A factory is a common design pattern in Object-Oriented Programming and is basically a function that creates objects. To explore this, let us move away from JavaScript into the world of Java. This will make sense to developers who come from a Classical OOP (i.e, not prototypal), statically typed language background. <em>If you are not one such developer, feel free to skip this section.<\/em> This is a small deviation, and so if following along here interrupts your flow of JavaScript, then again, please skip this section.<\/p>\n<p>A common creational pattern, the Factory Pattern permits us to create objects without exposing the required business logic to perform said creation.<\/p>\n<p>Suppose we are writing a program that permits us to visualize primitive shapes in n-dimensions. If we provide a cube, for example, we\u2019d see a 2D cube (a square), a 3D cube (a cube), and a 4D cube (a Tesseract, or Hypercube). Here is how this might be done, trivially, and barring the actual drawing part, in Java.<\/p>\n<div>\n<pre><code>\/\/ Main.java\n\n\/\/ Defining an interface for the shape (can be used as a base type)\ninterface IShape {\n    void draw();\n}\n\n\/\/ Implementing the interface for 2-dimensions:\nclass TwoDimensions implements IShape {\n    @Override\n    public void draw() {\n        System.out.println(\"Drawing a shape in 2D.\");\n    }\n}\n\n\/\/ Implementing the interface for 3-dimensions:\nclass ThreeDimensions implements IShape {\n    @Override\n    public void draw() {\n        System.out.println(\"Drawing a shape in 3D.\");\n    }\n}\n\n\/\/ Implementing the interface for 4-dimensions:\nclass FourDimensions implements IShape {\n    @Override\n    public void draw() {\n        System.out.println(\"Drawing a shape in 4D.\");\n    }\n}\n\n\/\/ Handles object creation\nclass ShapeFactory {\n    \/\/ Factory method (notice return type is the base interface)\n    public IShape createShape(int dimensions) {\n        switch(dimensions) {\n            case 2:\n                return new TwoDimensions();\n            case 3:\n                return new ThreeDimensions();\n            case 4:\n                return new FourDimensions();\n            default: \n                throw new IllegalArgumentException(\"Invalid dimension.\");\n        }\n    }\n}\n\n\/\/ Main class and entry point.\npublic class Main {\n    public static void main(String[] args) throws Exception {\n        ShapeFactory shapeFactory = new ShapeFactory();\n        IShape fourDimensions = shapeFactory.createShape(4);\n        fourDimensions.draw(); \/\/ Drawing a shape in 4D.\n    }\n}<\/code><\/pre>\n<\/div>\n<p>As you can see, we define an interface that specifies a method for drawing a shape.  By having the different classes implement the interface, we can guarantee that all shapes can be drawn (for they all must have an overridable <code>draw<\/code> method as per the interface definition). Considering this shape is drawn differently depending upon the dimensions within which it\u2019s viewed, we define helper classes that implement the interface as to perform the GPU intensive work of simulating n-dimensional rendering. <code>ShapeFactory<\/code> does the work of instantiating the correct class \u2014 the <code>createShape<\/code> method is a factory, and like the definition above, it is a method that returns an object of a class. The return type of <code>createShape<\/code> is the <code>IShape<\/code> interface because the <code>IShape<\/code> interface is the base type of all shapes (because they have a <code>draw<\/code> method).<\/p>\n<p>This Java example is fairly trivial, but you can easily see how useful it becomes in larger applications where the setup to create an object might not be so simple. An example of this would be a video game. Suppose the user has to survive different enemies. Abstract classes and interfaces might be used to define core functions available to all enemies (and methods that can be overridden), perhaps employing the delegation pattern (favor composition over inheritance as the Gang of Four suggested so you don\u2019t get locked into extending a single base class and to make testing\/mocking\/DI easier). For enemy objects instantiated in different ways, the interface would permit factory object creation while relying on the generic interface type. This would be very relevant if the enemy was created dynamically.<\/p>\n<p>Another example is a builder function. Suppose we utilize the Delegation Pattern to have a class delegate work to other classes that honor an interface. We could place a static <code>build<\/code> method on the class to have it construct its own instance (assuming you were not using a Dependency Injection Container\/Framework). Instead of having to call each setter, you can do this:<\/p>\n<div>\n<pre><code>public class User {\n    private IMessagingService msgService;\n    private String name;\n    private int age;\n    \n    public User(String name, int age, IMessagingService msgService) {\n        this.name = name;\n        this.age = age;\n        this.msgService = msgService;\n    }\n    \n    public static User build(String name, int age) {\n        return new User(name, age, new SomeMessageService());\n    }\n}<\/code><\/pre>\n<\/div>\n<p>I\u2019ll be explaining the Delegation Pattern in a later article if you\u2019re not familiar with it \u2014 basically, through Composition and in terms of object-modeling, it creates a \u201chas-a\u201d relationship instead of an \u201cis-a\u201d relationship as you\u2019d get with inheritance. If you have a <code>Mammal<\/code> class and a <code>Dog<\/code> class, and <code>Dog<\/code> extends <code>Mammal<\/code>, then a <code>Dog<\/code> <strong>is-a<\/strong> <code>Mammal<\/code>. Whereas, if you had a <code>Bark<\/code> class, and you just passed instances of <code>Bark<\/code> into the constructor of <code>Dog<\/code>, then <code>Dog<\/code> <strong>has-a<\/strong> <code>Bark<\/code>. As you might imagine, this especially makes unit testing easier, for you can inject mocks and assert facts about the mock as long as mock honors the interface contract in the testing environment.<\/p>\n<p>The <code>static<\/code> \u201cbuild\u201d factory method above simply creates a new object of <code>User<\/code> and passes a concrete <code>MessageService<\/code> in. Notice how this follows from the definition above \u2014 not exposing the business logic to create an object of a class, or, in this case, not exposing the creation of the messaging service to the caller of the factory.<\/p>\n<p>Again,  this is not necessarily how you would do things in the real world, but it presents the idea of a factory function\/method quite well. We might use a Dependency Injection container instead, for example. Now back to JavaScript.<\/p>\n<h3>Starting With Express<\/h3>\n<p>Express is a Web Application Framework for Node (available via an NPM Module) that permits one to create an HTTP Web Server. It\u2019s important to note that Express is not the only framework to do this (there exists Koa, Fastify, etc.), and that, as seen in the previous article, Node can function without Express as a stand-alone entity. (Express is merely a module that was designed for Node \u2014 Node can do many things without it, although Express is popular for Web Servers).<\/p>\n<p>Again, let me make a very important distinction. <strong>There is<\/strong> a dichotomy present between Node\/JavaScript and Express. Node, the runtime\/environment within which you run JavaScript, can do many things \u2014 such as permitting you to build React Native apps, desktop apps, command-line tools, etc. \u2014 Express is nothing but a lightweight framework that permits you to use Node\/JS to build web servers as opposed to dealing with Node\u2019s low-level network and HTTP APIs. You don\u2019t need Express to build a web server.<\/p>\n<p>Before starting this section, if you are not familiar with HTTP and HTTP Requests (GET, POST, etc.), then I encourage you to read the corresponding section of my former article, which is linked above.<\/p>\n<p>Using Express, we\u2019ll set up different routes to which HTTP Requests may be made, as well as the related endpoints (which are callback functions) that will fire when a request is made to that route. Don\u2019t worry if routes and endpoints are currently non-sensical \u2014 I\u2019ll be explaining them later.<\/p>\n<p>Unlike other articles, I\u2019ll take the approach of writing the source code as we go, line-by-line, rather than dumping the entire codebase into one snippet and then explaining later. Let\u2019s begin by opening a terminal (I\u2019m using Terminus on top of Git Bash on Windows \u2014 which is a nice option for Windows users who want a Bash Shell without setting up the Linux Subsystem), setting up our project\u2019s boilerplate, and opening it in Visual Studio Code.<\/p>\n<pre><code>mkdir server && cd server\ntouch server.js\nnpm init -y\nnpm install express\ncode .<\/code><\/pre>\n<p>Inside the <code>server.js<\/code> file, I\u2019ll begin by requiring <code>express<\/code> using the <code>require()<\/code> function.<\/p>\n<pre><code>const express = require('express');<\/code><\/pre>\n<p><code>require('express')<\/code> tells Node to go out and get the Express module we installed earlier, which is currently inside the <code>node_modules<\/code> folder (for that\u2019s what <code>npm install<\/code> does \u2014 create a <code>node_modules<\/code> folder and puts modules and their dependencies in there). By convention, and when dealing with Express, we call the variable that holds the return result from <code>require('express')<\/code> <code>express<\/code>, although it may be called anything.<\/p>\n<p>This returned result, which we have called <code>express<\/code>, is actually a function \u2014 a function we\u2019ll have to invoke to create our Express app and set up our routes. Again, by convention, we call this <code>app<\/code> \u2014 <code>app<\/code> being the return result of <code>express()<\/code> \u2014 that is, the return result of calling the function that has the name <code>express<\/code> as <code>express()<\/code>.<\/p>\n<div>\n<pre><code>const express = require('express'); \nconst app = express();\n\n\/\/ Note that the above variable names are the convention, but not required.\n\/\/ An example such as that below could also be used.\n\nconst foo = require('express');\nconst bar = foo();\n\n\/\/ Note also that the node module we installed is called express.<\/code><\/pre>\n<\/div>\n<p>The line <code>const app = express();<\/code> simply puts a new Express Application inside of the <code>app<\/code> variable. It calls a function named <code>express<\/code> (the return result of <code>require('express')<\/code>) and stores its return result in a constant named <code>app<\/code>. If you come from an object-oriented programming background, consider this equivalent to instantiating a new object of a class, where <code>app<\/code> would be the object and where <code>express()<\/code> would call the constructor function of the <code>express<\/code> class. Remember, JavaScript allows us to store functions in variables \u2014 functions are first-class citizens. The <code>express<\/code> variable, then, is nothing more than a mere function. It\u2019s provided to us by the developers of Express.<\/p>\n<p>I apologize in advance if I\u2019m taking a very long time to discuss what is actually very basic, but the above, although primitive, confused me quite a lot when I was first learning back-end development with Node.<\/p>\n<p>Inside the Express source code, which is open-source on GitHub, the variable we called <code>express<\/code> is a function entitled <code>createApplication<\/code>, which, when invoked, performs the work necessary to create an Express Application:<\/p>\n<p>A snippet of Express source code:<\/p>\n<div>\n<pre><code>exports  =  module.exports  = createApplication;\n\n\/*\n * Create an express application\n *\/\n\n\/\/ This is the function we are storing in the express variable. (- Jamie)\nfunction createApplication() {\n\n   \/\/ This is what I mean by \"Express App\" (- Jamie)\n   var app = function(req, res, next) {\n\n      app.handle(req, res, next);\n\n   };\n\n   mixin(app, EventEmitter.prototype, false);\n   mixin(app, proto, false);\n\n   \/\/ expose the prototype that will get set on requests\n\n   app.request = Object.create(req, {\n\n      app: { configurable: true, enumerable: true, writable: true, value: app      }\n\n   })\n\n   \/\/ expose the prototype that will get set on responses\n\n   app.response = Object.create(res, {\n\n      app: { configurable: true, enumerable: true, writable: true, value: app }\n\n   })\n\n   app.init();\n\n   \/\/ See - `app` gets returned. (- Jamie)\n   return app;\n}<\/code><\/pre>\n<\/div>\n<p>GitHub: <a href=\"https:\/\/github.com\/expressjs\/express\/blob\/master\/lib\/express.js\">https:\/\/github.com\/expressjs\/express\/blob\/master\/lib\/express.js<\/a><\/p>\n<p>With that short deviation complete, let\u2019s continue setting up Express. Thus far, we have required the module and set up our <code>app<\/code> variable.<\/p>\n<pre><code>const express = require('express');\nconst app = express();<\/code><\/pre>\n<p>From here, we have to tell Express to listen on a port. Any HTTP Requests made to the URL and Port upon which our application is listening will be handled by Express. We do that by calling <code>app.listen(...)<\/code>, passing to it the port and a callback function which gets called when the server starts running:<\/p>\n<div>\n<pre><code>const PORT = 3000;\n\napp.listen(PORT, () => console.log(`Server is up on port {PORT}.`));<\/code><\/pre>\n<\/div>\n<p>We notate the <code>PORT<\/code> variable in capital by convention, for it is a constant variable that will never change. You could do that with all variables that you declare <code>const<\/code>, but that would look messy. It\u2019s up to the developer or development team to decide on notation, so we\u2019ll use the above sparsely. I use <code>const<\/code> everywhere as a method of \u201cdefensive coding\u201d \u2014 that is, if I know that a variable is never going to change then I might as well just declare it <code>const<\/code>. Since I define everything <code>const<\/code>, I make the distinction between what variables should remain the same on a per-request basis and what variables are true actual global constants.<\/p>\n<p>Here is what we have thus far:<\/p>\n<pre><code>const express = require('express'); \nconst app = express(); \n\nconst PORT = 3000;\n\n\/\/ We will build our API here.\n\/\/ ...\n\n\/\/ Binding our application to port 3000.\napp.listen(PORT, () => {\n   console.log(`Server is up on port ${PORT}.`);\n});<\/code><\/pre>\n<p>Let\u2019s test this to see if the server starts running on port 3000.<\/p>\n<p>I\u2019ll open a terminal and navigate to our project\u2019s root directory. I\u2019ll then run <code>node server\/server.js<\/code>. Note that this assumes you have Node already installed on your system (You can check with <code>node -v<\/code>).<\/p>\n<p>If everything works, you should see the following in the terminal:<\/p>\n<p><code>Server is up on port 3000.<\/code><\/p>\n<p>Go ahead and hit <code>Ctrl + C<\/code> to bring the server back down.<\/p>\n<p>If this doesn\u2019t work for you, or if you see an error such as <code>EADDRINUSE<\/code>, then it means you may have a service already running on port 3000. Pick another port number, like 3001, 3002, 5000, 8000, etc. Be aware, lower number ports are reserved and there is an upper bound of 65535.<\/p>\n<p>At this point, it\u2019s worth taking another small deviation as to understand servers and ports in the context of computer networking. We\u2019ll return to Express in a moment. I take this approach, rather than introducing servers and ports first, for the purpose of relevance. That is, it is difficult to learn a concept if you fail to see its applicability. In this way, you are already aware of the use case for ports and servers with Express, so the learning experience will be more pleasurable.<\/p>\n<h3>A Brief Look At Servers And Ports<\/h3>\n<p>A server is simply a computer or computer program that provides some sort of \u201cfunctionality\u201d to the clients that talk to it. More generally, it\u2019s a device, usually connected to the Internet, that handles connections in a pre-defined manner. In our case, that \u201cpre-defined manner\u201d will be HTTP or the HyperText Transfer Protocol. Servers that use the HTTP Protocol are called Web Servers.<\/p>\n<p>When building an application, the server is a critical component of the \u201cclient-server model\u201d, for it permits the sharing and syncing of data (generally via databases or file systems) across devices. It\u2019s a cross-platform approach, in a way, for the SDKs of platforms against which you may want to code \u2014 be they web, mobile, or desktop \u2014 all provide methods (APIs) to interact with a server over HTTP or TCP\/UDP Sockets. It\u2019s important to make a distinction here \u2014 by APIs, I mean programming language constructs to talk to a server, like <code>XMLHttpRequest<\/code> or the <code>Fetch<\/code> API in JavaScript, or <code>HttpUrlConnection<\/code> in Java, or even <code>HttpClient<\/code> in C#\/.NET. This is different from the kind of REST API we\u2019ll be building in this article to perform CRUD Operations on a database.<\/p>\n<p>To talk about ports, it\u2019s important to understand how clients connect to a server. A client requires the IP Address of the server and the Port Number of our specific service on that server. An IP Address, or Internet Protocol Address, is just an address that uniquely identifies a device on a network. Public and private IPs exist, with private addresses commonly used behind a router or Network Address Translator on a local network. You might see private IP Addresses of the form <code>192.168.XXX.XXX<\/code> or <code>10.0.XXX.XXX<\/code>. When articulating an IP Address, decimals are called \u201cdots\u201d. So <code>192.168.0.1<\/code> (a common router IP Addr.) might be pronounced, \u201cone nine two dot one six eight dot zero dot one\u201d. (By the way, if you\u2019re ever in a hotel and your phone\/laptop won\u2019t direct you to the AP captive portal, try typing 192.168.0.1 or 192.168.1.1 or similar directly into Chrome).<\/p>\n<p>For simplicity, and since this is not an article about the complexities of computer networking, assume that an IP Address is equivalent to a house address, allowing you to uniquely identify a house (where a house is analogous to a server, client, or network device) in a neighborhood. One neighborhood is one network. Put together all of the neighborhoods in the United States, and you have the public Internet. (This is a basic view, and there are many more complexities \u2014 firewalls, NATs, ISP Tiers (Tier One, Tier Two, and Tier Three), fiber optics and fiber optic backbones, packet switches, hops, hubs, etc., subnet masks, etc., to name just a few \u2014 in the real networking world.) The <code>traceroute<\/code> Unix command can provide more insight into the above, displaying the path (and associated latency) that packets take through a network as a series of \u201chops\u201d.<\/p>\n<p>A Port Number identifies a specific service running on a server. SSH, or Secure Shell, which permits remote shell access to a device, commonly runs on port 22. FTP or File Transfer Protocol (which might, for example, be used with an FTP Client to transfer static assets to a server) commonly runs on Port 21. We might say, then, that ports are specific rooms inside each house in our analogy above, for rooms in houses are made for different things \u2014 a bedroom for sleeping, a kitchen for food preparation, a dining room for consumption of said food, etc., just like ports correspond to programs that perform specific services. For us, Web Servers commonly run on Port 80, although you are free to specify whichever Port Number you wish as long they are not in use by some other service (they can\u2019t collide).<\/p>\n<p>In order to access a website, you need the IP Address of the site. Despite that, we normally access websites via a URL. Behind the scenes, a DNS, or Domain Name Server, converts that URL into an IP Address, allowing the browser to make a GET Request to the server, <em>get<\/em> the HTML, and render it to the screen. <code>8.8.8.8<\/code> is the address of one of Google\u2019s Public DNS Servers. You might imagine that requiring the resolution of a hostname to an IP Address via a remote DNS Server will take time, and you\u2019d be right. To reduce latency, Operating Systems have a DNS Cache \u2014 a temporary database that stores DNS lookup information, thereby reducing the frequency of which said lookups must occur. The DNS Resolver Cache can be viewed on Windows with the <code>ipconfig \/displaydns<\/code> CMD command and purged via the <code>ipconfig \/flushdns<\/code> command.<\/p>\n<p>On a Unix Server, more common lower number ports, like 80, require <em>root<\/em> level (<em>escalated<\/em> if you come from a Windows background) privileges. For that reason, we\u2019ll be using port 3000 for our development work, but will allow the server to choose the port number (whatever is available) when we deploy to our production environment.<\/p>\n<p>Finally, note that we can type IP Addresses directly in Google Chrome\u2019s search bar, thus bypassing the DNS Resolution mechanism. Typing <code>216.58.194.36<\/code>, for example, will take you to Google.com. In our development environment, when using our own computer as our dev server, we\u2019ll be using <code>localhost<\/code> and port 3000. An address is formatted as <code>hostname:port<\/code>, so our server will be up on <code>localhost:3000<\/code>. Localhost, or <code>127.0.0.1<\/code>, is the loopback address, and means the address of \u201cthis computer\u201d. It is a hostname, and its IPv4 address resolves to <code>127.0.0.1<\/code>. Try pinging localhost on your machine right now. You might get <code>::1<\/code> back \u2014 which is the IPv6 loopback address, or <code>127.0.0.1<\/code> back \u2014 which is the IPv4 loopback address. IPv4 and IPv6 are two different IP Address formats associated with different standards \u2014 some IPv6 addresses can be converted to IPv4 but not all.<\/p>\n<h3>Returning To Express<\/h3>\n<p>I mentioned HTTP Requests, Verbs, and Status Codes in my previous article, <a href=\"https:\/\/www.smashingmagazine.com\/2019\/02\/node-api-http-es6-javascript\/\">Get Started With Node: An Introduction To APIs, HTTP And ES6+ JavaScript<\/a>. If you do not have a general understanding of the protocol, feel free to jump to the \u201cHTTP and HTTP Requests\u201d section of that piece.<\/p>\n<p>In order to get a feel for Express, we are simply going to set up our endpoints for the four fundamental operations we\u2019ll be performing on the database \u2014 Create, Read, Update, and Delete, known collectively as CRUD.<\/p>\n<p>Remember, we access endpoints by routes in the URL. That is, although the words \u201croute\u201d and \u201cendpoint\u201d are commonly used interchangeably, an <em>endpoint<\/em> is technically a programming language function (like ES6 Arrow Functions) that performs some server-side operation, while a <em>route<\/em> is what the endpoint is located <em>behind of<\/em>. We specify these endpoints as callback functions, which Express will fire when the appropriate request is made from the client to the <em>route<\/em> behind which the endpoint lives. You can remember the above by realizing that it is endpoints that perform a function and the route is the name that is used to access the endpoints. As we\u2019ll see, the same route can be associated with multiple endpoints by using different HTTP Verbs (similar to method overloading if you come from a classical OOP background with Polymorphism).<\/p>\n<p>Keep in mind, we are following REST (REpresentational State Transfer) Architecture by permitting clients to make requests to our server. This is, after all, a REST or RESTful API. Specific <strong>requests<\/strong> made to specific <strong>routes<\/strong> will fire specific <strong>endpoints<\/strong> which will do specific <strong>things<\/strong>. An example of such a \u201cthing\u201d that an endpoint might do is adding new data to a database, removing data, updating data, etc.<\/p>\n<p>Express knows what endpoint to fire because we tell it, explicitly, the request method (GET, POST, etc.) and the route \u2014 we define what functions to fire for specific combinations of the above, and the client makes the request, specifying a route and method. To put this more simply, with Node, we\u2019ll tell Express \u2014 \u201cHey, if someone makes a GET Request to this route, then go ahead and fire this function (use this endpoint)\u201d. Things can get more complicated: \u201cExpress, if someone makes a GET Request to <em>this<\/em> route, but they don\u2019t send up a valid Authorization Bearer Token in the header of their request, then please respond with an <code>HTTP 401 Unauthorized<\/code>. If they do possess a valid Bearer Token, then please send down whatever protected resource they were looking for by firing the endpoint. Thanks very much and have a nice day.\u201d Indeed, it\u2019d be nice if programming languages could be that high level without leaking ambiguity, but it nonetheless demonstrates the basic concepts.<\/p>\n<p>Remember, the endpoint, in a way, <em>lives behind<\/em> the route. So it\u2019s imperative that the client provides, in the header of the request, what method it wants to use so that Express can figure out what to do. The request will be made to a specific route, which the client will specify (along with the request type) when contacting the server, allowing Express to do what it needs to do and us to do what we need to do when Express fires our callbacks. That\u2019s what it all comes down to.<\/p>\n<p>In the code examples earlier, we called the <code>listen<\/code> function which was available on <code>app<\/code>, passing to it a port and callback. <code>app<\/code> itself, if you remember, is the return result from calling the <code>express<\/code> variable as a function (that is, <code>express()<\/code>), and the <code>express<\/code> variable is what we named the return result from requiring <code>'express'<\/code> from our <code>node_modules<\/code> folder. Just like <code>listen<\/code> is called on <code>app<\/code>, we specify HTTP Request Endpoints by calling them on <code>app<\/code>. Let\u2019s look at GET:<\/p>\n<pre><code>app.get('\/my-test-route', () => {\n   \/\/ ...\n});<\/code><\/pre>\n<p>The first parameter is a <code>string<\/code>, and it is the route behind which the endpoint will live. The callback function is the endpoint. I\u2019ll say that again: <em>the callback function \u2014 the second parameter \u2014 is the endpoint<\/em> that will fire when an HTTP GET Request is made to whatever route we specify as the first argument (<code>\/my-test-route<\/code> in this case).<\/p>\n<p>Now, before we do any more work with Express, we need to know how routes work. The route we specify as a string will be called by making the request to <code>www.domain.com\/the-route-we-chose-earlier-as-a-string<\/code>. In our case, the domain is <code>localhost:3000<\/code>, which means, in order to fire the callback function above, we have to make a GET Request to <code>localhost:3000\/my-test-route<\/code>. If we used a different string as the first argument above, the URL would have to be different to match what we specified in JavaScript.<\/p>\n<p>When talking about such things, you\u2019ll likely hear of Glob Patterns. We could say that all of our API\u2019s routes are located at the <code>localhost:3000\/**<\/code> Glob Pattern, where <code>**<\/code> is a wildcard meaning any directory or sub-directory (note that routes are <strong>not<\/strong> directories) to which root is a parent \u2014 that is, everything.<\/p>\n<p>Let\u2019s go ahead and add a log statement into that callback function so that altogether we have:<\/p>\n<div>\n<pre><code>\/\/ Getting the module from node_modules.\nconst express = require('express');\n\n\/\/ Creating our Express Application.\nconst app = express();\n\n\/\/ Defining the port we\u2019ll bind to.\nconst PORT = 3000;\n\n\/\/ Defining a new endpoint behind the \"\/my-test-route\" route.\napp.get('\/my-test-route', () => {\n   console.log('A GET Request was made to \/my-test-route.');\n});\n\n\/\/ Binding the server to port 3000.\napp.listen(PORT, () => {\n   console.log(`Server is up on port ${PORT}.`)\n});<\/code><\/pre>\n<\/div>\n<p>We\u2019ll get our server up and running by executing <code>node server\/server.js<\/code> (with Node installed on our system and accessible globally from system environment variables) in the project\u2019s root directory. Like earlier, you should see the message that the server is up in the console. Now that the server is running, open a browser, and visit <code>localhost:3000<\/code> in the URL bar.<\/p>\n<p>You should be greeted with an error message that states <code>Cannot GET \/<\/code>. Press Ctrl + Shift + I on Windows in Chrome to view the developer console. In there, you should see that we have a <code>404<\/code> (Resource not found). That makes sense \u2014 we have only told the server what to do when someone visits <code>localhost:3000\/my-test-route<\/code>. The browser has nothing to render at <code>localhost:3000<\/code> (which is equivalent to <code>localhost:3000\/<\/code> with a slash).<\/p>\n<p>If you look at the terminal window where the server is running, there should be no new data. Now, visit <code>localhost:3000\/my-test-route<\/code> in your browser\u2019s URL bar. You <em>might<\/em> see the same error in Chrome\u2019s Console (because the browser is caching the content and still has no HTML to render), but if you view your terminal where the server process is running, you\u2019ll see that the callback function did indeed fire and the log message was indeed logged.<\/p>\n<p>Shut down the server with Ctrl + C.<\/p>\n<p>Now, let\u2019s give the browser something to render when a GET Request is made to that route so we can lose the <code>Cannot GET \/<\/code> message. I\u2019m going to take our <code>app.get()<\/code> from earlier, and in the callback function, I\u2019m going to add two arguments. Remember, the callback function we are passing in is getting called by Express behind the scenes, and Express can add whatever arguments it wants. It actually adds two (well, technically three, but we\u2019ll see that later), and while they are both extremely important, we don\u2019t care about the first one for now. The second argument is called <code>res<\/code>, short for <code>response<\/code>, and I\u2019ll access it by setting <code>undefined<\/code> as the first parameter:<\/p>\n<div>\n<pre><code>app.get('\/my-test-route', (undefined, res) => {\n    console.log('A GET Request was made to \/my-test-route.');\n});<\/code><\/pre>\n<\/div>\n<p>Again, we can call the <code>res<\/code> argument whatever we want, but <code>res<\/code> is convention when dealing with Express. <code>res<\/code> is actually an object, and upon it exist different methods for sending data back to the client. In this case, I\u2019m going to access the <code>send(...)<\/code> function available on <code>res<\/code> to send back HTML which the browser will render. We are not limited to sending back HTML, however, and can choose to send back text, a JavaScript Object, a stream (streams are especially beautiful), or whatever.<\/p>\n<div>\n<pre><code>app.get('\/my-test-route', (undefined, res) => {\n    console.log('A GET Request was made to \/my-test-route.');\n    res.send('<h1>Hello, World!<\/h1>');\n});<\/code><\/pre>\n<\/div>\n<p>If you shut down the server and then bring it back up, and then refresh your browser at the <code>\/my-test-route<\/code> route, you\u2019ll see the HTML get rendered.<\/p>\n<p>The Network Tab of the Chrome Developer Tools will allow you to see this GET Request with more detail as it pertains to headers.<\/p>\n<p>At this point, it\u2019ll serve us well to start learning about Express Middleware \u2014 functions that can be fired globally after a client makes a request.<\/p>\n<h3>Express Middleware<\/h3>\n<p>Express provides methods by which to define custom middleware for your application. Indeed, the meaning of Express Middleware is best defined in the Express Docs, <a href=\"https:\/\/expressjs.com\/en\/guide\/using-middleware.html\">here<\/a>)<\/p>\n<blockquote>\n<p><em>Middleware<\/em> functions are functions that have access to the <a href=\"https:\/\/expressjs.com\/en\/4x\/api.html#req\">request object<\/a> (<code>req<\/code>), the <a href=\"https:\/\/expressjs.com\/en\/4x\/api.html#res\">response object<\/a> (<code>res<\/code>), and the next middleware function in the application\u2019s request-response cycle. The next middleware function is commonly denoted by a variable named <code>next<\/code>.<\/p>\n<\/blockquote>\n<p>Middleware functions can perform the following tasks:<\/p>\n<ul>\n<li>Execute any code.<\/li>\n<li>Make changes to the request and the response objects.<\/li>\n<li>End the request-response cycle.<\/li>\n<li>Call the next middleware function in the stack.<\/li>\n<\/ul>\n<p>In other words, a middleware function is a custom function that we (the developer) can define, and that will act as an intermediary between when Express receives the request and when our appropriate callback function fires. We might make a <code>log<\/code> function, for example, that will log every time a request is made. Note that we can also choose to make these middleware functions fire <em>after<\/em> our endpoint has fired, depending upon where you place it in the stack \u2014 something we\u2019ll see later.<\/p>\n<p>In order to specify custom middleware, we have to define it as a function and pass it into <code>app.use(...)<\/code>.<\/p>\n<div>\n<pre><code>const myMiddleware = (req, res, next) => {\n    console.log(`Middleware has fired at time ${Date().now}`);\n    next();\n}\n\napp.use(myMiddleware); \/\/ This is the app variable returned from express().<\/code><\/pre>\n<\/div>\n<p>All together, we now have:<\/p>\n<div>\n<pre><code>\/\/ Getting the module from node_modules.  \nconst express =  require('express');  \n\n\/\/ Creating our Express Application.  \nconst app =  express();  \n\n\/\/ Our middleware function.\nconst myMiddleware = (req, res, next) => {\n    console.log(`Middleware has fired at time ${Date().now}`);\n    next();\n}\n\n\/\/ Tell Express to use the middleware.\napp.use(myMiddleware);\n\n\/\/ Defining the port we\u2019ll bind to.  \nconst PORT =  3000;  \n\n\/\/ Defining a new endpoint behind the \"\/my-test-route\" route. \napp.get('\/my-test-route', () => { \n    console.log('A GET Request was made to \/my-test-route.');  \n});  \n\n\/\/ Binding the server to port 3000. \napp.listen(PORT, () => { \n    console.log(`Server is up on port ${PORT}.`)  \n});<\/code><\/pre>\n<\/div>\n<p>If you make the requests through the browser again, you should now see that your middleware function is firing and logging timestamps. To foster experimentation, try removing the call to the <code>next<\/code> function and see what happens.<\/p>\n<p>The middleware callback function gets called with three arguments, <code>req<\/code>, <code>res<\/code>, and <code>next<\/code>. <code>req<\/code> is the parameter we skipped over when building out the GET Handler earlier, and it is an object containing information regarding the request, such as headers, custom headers, parameters, and any body that might have been sent up from the client (such as you do with a POST Request). I know we are talking about middleware here, but both the endpoints and the middleware function get called with <code>req<\/code> and <code>res<\/code>. <code>req<\/code> and <code>res<\/code> will be the same (unless one or the other mutates it) in both the middleware and the endpoint within the scope of a single request from the client. That means, for example, you could use a middleware function to sanitize data by stripping any characters that might be aimed at performing SQL or NoSQL Injections, and then handing the safe <code>req<\/code> to the endpoint.<\/p>\n<p><code>res<\/code>, as seen earlier, permits you to send data back to the client in a handful of different ways.<\/p>\n<p><code>next<\/code> is a callback function that you have to execute when the middleware has finished doing its job in order to call the next middleware function in the stack or the endpoint. Be sure to take note that you will have to call this in the <code>then<\/code> block of any async functions you fire in the middleware. Depending on your async operation, you may or may not want to call it in the <code>catch<\/code> block. That is, the <code>myMiddleware<\/code> function fires <em>after<\/em> the request is made from the client but <em>before<\/em> the endpoint function of the request is fired. When we execute this code and make a request, you should see the <code>Middleware has fired...<\/code> message <em>before<\/em> the <code>A GET Request was made to...<\/code> message in the console. If you don\u2019t call <code>next()<\/code>, the latter part will never run \u2014 your endpoint function to the request will not fire.<\/p>\n<p>Note also that I could have defined this function anonymously, as such (a convention to which I\u2019ll be sticking):<\/p>\n<div>\n<pre><code>app.use((req, res, next) => {\n    console.log(`Middleware has fired at time ${Date().now}`);\n    next();\n});<\/code><\/pre>\n<\/div>\n<p>For anyone new to JavaScript and ES6, if the way in which the above works does not make immediate sense, the below example should help. We are simply defining a callback function (the anonymous function) which takes another callback function (<code>next<\/code>) as an argument. We call a function that takes a function argument a Higher Order Function. Look at it the below way \u2014 it depicts a basic example of how the Express Source Code might work behind the scenes:<\/p>\n<div>\n<pre><code>console.log('Suppose a request has just been made from the client.n');\n\n\/\/ This is what (it\u2019s not exactly) the code behind app.use() might look like.\nconst use = callback => { \n    \/\/ Simple log statement to see where we are.\n    console.log('Inside use() - the \"use\" function has been called.');\n\n    \/\/ This depicts the termination of the middleware.\n    const next = () => console.log('Terminating Middleware!n');\n\n    \/\/ Suppose req and res are defined above (Express provides them).\n    const req = res = null;\n\n    \/\/ \"callback\" is the \"middleware\" function that is passed into \"use\".\n    \/\/ \"next\" is the above function that pretends to stop the middleware.\n    callback(req, res, next);\n};\n\n\/\/ This is analogous to the middleware function we defined earlier.\n\/\/ It gets passed in as \"callback\" in the \"use\" function above.\nconst myMiddleware = (req, res, next) => {\n    console.log('Inside the myMiddleware function!');\n    next();\n}\n\n\/\/ Here, we are actually calling \"use()\" to see everything work. \nuse(myMiddleware);\n\nconsole.log('Moving on to actually handle the HTTP Request or the next middleware function.');<\/code><\/pre>\n<\/div>\n<p>We first call <code>use<\/code> which takes <code>myMiddleware<\/code> as an argument. <code>myMiddleware<\/code>, in and of itself, is a function which takes three arguments &#8211; <code>req<\/code>, <code>res<\/code>, and <code>next<\/code>. Inside <code>use<\/code>, <code>myMiddlware<\/code> is called, and those three arguments are passed in. <code>next<\/code> is a function defined in <code>use<\/code>. <code>myMiddleware<\/code> is defined as <code>callback<\/code> in the <code>use<\/code> method. If I\u2019d placed <code>use<\/code>, in this example, on an object called <code>app<\/code>, we could have mimicked Express\u2019s setup entirely, albeit without any sockets or network connectivity.<\/p>\n<p>In this case, both <code>myMiddleware<\/code> and <code>callback<\/code> are Higher Order Functions, because they both take functions as arguments.<\/p>\n<p>If you execute this code, you will see the following response:<\/p>\n<pre><code>Suppose a request has just been made from the client. \n\nInside use() - the \"use\" function has been called. \nInside the middleware function! \nTerminating Middleware! \n\nMoving on to actually handle the HTTP Request or the next middleware function.<\/code><\/pre>\n<p>Note that I could have also used anonymous functions to achieve the same result:<\/p>\n<div>\n<pre><code>console.log('Suppose a request has just been made from the client.');\n\n\/\/ This is what (it\u2019s not exactly) the code behind app.use() might look like.\nconst use = callback => {\n    \/\/ Simple log statement to see where we are.\n    console.log('Inside use() - the \"use\" function has been called.');\n\n    \/\/ This depicts the termination of the middlewear.  \n    const  next  =  ()  => console.log('Terminating Middlewear!');\n\n    \/\/ Suppose req and res are defined above (Express provides them).\n    const req = res = null;\n\n    \/\/ \"callback\" is the function which is passed into \"use\".\n    \/\/ \"next\" is the above function that pretends to stop the middlewear.\n    callback(req, res, () => {\n        console.log('Terminating Middlewear!');\n    });\n};\n\n\/\/ Here, we are actually calling \"use()\" to see everything work.\nuse((req, res, next) => {\n    console.log('Inside the middlewear function!');\n    next();\n});\n\nconsole.log('Moving on to actually handle the HTTP Request.');<\/code><\/pre>\n<\/div>\n<p>With that hopefully settled, we can now return to the actual task at hand \u2014 setting up our middleware.<\/p>\n<p>The fact of the matter is, you will commonly have to send data up through an HTTP Request. You have a few different options for doing so \u2014 sending up URL Query Parameters, sending up data that will be accessible on the <code>req<\/code> object that we learned about earlier, etc. That object is not only available in the callback to calling <code>app.use()<\/code>, but also to any endpoint. We used <code>undefined<\/code> as a filler earlier so we could focus on <code>res<\/code> to send HTML back to the client, but now, we need access to it.<\/p>\n<div>\n<pre><code>app.use('\/my-test-route', (req, res) => {\n    \/\/ The req object contains client-defined data that is sent up.\n    \/\/ The res object allows the server to send data back down.\n});<\/code><\/pre>\n<\/div>\n<p>HTTP POST Requests <em>might<\/em> require that we send a body object up to the server. If you have a form on the client, and you take the user\u2019s name and email, you will likely send that data to the server on the body of the request.<\/p>\n<p>Let\u2019s take a look at what that might look like on the client side:<\/p>\n<div>\n<pre><code><!DOCTYPE html> \n<html> \n    <body> \n        <form action=\"http:\/\/localhost:3000\/email-list\" method=\"POST\" > \n            <input type=\"text\" name=\"nameInput\">\n            <input type=\"email\" name=\"emailInput\"> \n            <input type=\"submit\">\n       <\/form> \n   <\/body> \n<\/html><\/code><\/pre>\n<\/div>\n<p>On the server side:<\/p>\n<div>\n<pre><code>app.post('\/email-list', (req, res) => {\n    \/\/ What do we now? \n    \/\/ How do we access the values for the user\u2019s name and email?\n});<\/code><\/pre>\n<\/div>\n<p>To access the user\u2019s name and email, we\u2019ll have to use a particular type of middleware. This will put the data on an object called <code>body<\/code> available on <code>req<\/code>. Body Parser was a popular method of doing this, available by the Express developers as a standalone NPM module. Now, Express comes pre-packaged with its own middleware to do this, and we\u2019ll call it as so:<\/p>\n<pre><code>app.use(express.urlencoded({ extended: true }));<\/code><\/pre>\n<p>Now we can do:<\/p>\n<pre><code>app.post('\/email-list', (req, res) => {\n    console.log('User Name: ', req.body.nameInput);\n    console.log('User Email: ', req.body.emailInput);\n});<\/code><\/pre>\n<p>All this does is take any user-defined input which is sent up from the client, and makes them available on the <code>body<\/code> object of <code>req<\/code>. Note that on <code>req.body<\/code>, we now have <code>nameInput<\/code> and <code>emailInput<\/code>, which are the names of the <code>input<\/code> tags in the HTML. Now, this client-defined data should be considered dangerous (never, never trust the client), and needs to be sanitized, but we\u2019ll cover that later.<\/p>\n<p>Another type of middleware provided by express is <code>express.json()<\/code>. <code>express.json<\/code> is used to package any JSON Payloads sent up in a request from the client onto <code>req.body<\/code>, while <code>express.urlencoded<\/code> will package any incoming requests with strings, arrays, or other URL Encoded data onto <code>req.body<\/code>. In short, both manipulate <code>req.body<\/code>, but <code>.json()<\/code> is for JSON Payloads and <code>.urlencoded()<\/code> is for, among others, POST Query Parameters.<\/p>\n<p>Another way of saying this is that incoming requests with a <code>Content-Type: application\/json<\/code> header (such as specifying a POST Body with the <code>fetch<\/code> API) will be handled by <code>express.json()<\/code>, while requests with header <code>Content-Type: application\/x-www-form-urlencoded<\/code> (such as HTML Forms) will be handled with <code>express.urlencoded()<\/code>. This hopefully now makes sense.<\/p>\n<div><\/div>\n<h3>Starting Our CRUD Routes For MongoDB<\/h3>\n<p><strong>Note<\/strong>: <em>When performing PATCH Requests in this article, we won\u2019t follow the JSONPatch RFC Spec \u2014 an issue we\u2019ll rectify in the next article of this series.<\/em><\/p>\n<p>Considering that we understand that we specify each endpoint by calling the relevant function on <code>app<\/code>, passing to it the route and a callback function containing the request and response objects, we can begin to define our CRUD Routes for the Bookshelf API. Indeed, and considering this is an introductory article, I won\u2019t be taking care to follow HTTP and REST specifications completely, nor will I attempt to use the cleanest possible architecture. That will come in a future article.<\/p>\n<p>I\u2019ll open up the <code>server.js<\/code> file that we have been using thus far and empty everything out as to start from the below clean slate:<\/p>\n<div>\n<pre><code>\/\/ Getting the module from node_modules.\nconst express = require('express'); \n\n\/\/ This creates our Express App.\nconst app = express(); \n\n\/\/ Define middleware.\napp.use(express.json());\napp.use(express.urlencoded({ extended: true ));\n\n\/\/ Listening on port 3000 (arbitrary).\n\/\/ Not a TCP or UDP well-known port. \n\/\/ Does not require superuser privileges.\nconst PORT = 3000;\n\n\/\/ We will build our API here.\n\/\/ ...\n\n\/\/ Binding our application to port 3000.\napp.listen(PORT, () => console.log(`Server is up on port ${PORT}.`));<\/code><\/pre>\n<\/div>\n<p>Consider all following code to take up the <code>\/\/ ...<\/code> portion of the file above.<\/p>\n<p>To define our endpoints, and because we are building a REST API, we should discuss the proper way to name routes. Again, you should take a look at the HTTP section of my former article for more information. We are dealing with books, so all routes will be located behind <code>\/books<\/code> (the plural naming convention is standard).<\/p>\n<table>\n<thead>\n<tr>\n<th>Request<\/th>\n<th align=\"left\">Route<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>POST<\/td>\n<td align=\"left\"><code>\/books<\/code><\/td>\n<\/tr>\n<tr>\n<td>GET<\/td>\n<td align=\"left\"><code>\/books\/id<\/code><\/td>\n<\/tr>\n<tr>\n<td>PATCH<\/td>\n<td align=\"left\"><code>\/books\/id<\/code><\/td>\n<\/tr>\n<tr>\n<td>DELETE<\/td>\n<td align=\"left\"><code>\/books\/id<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>As you can see, an ID does not need to be specified when POSTing a book because we\u2019ll (or rather, MongoDB), will be generating it for us, automatically, server-side. GETting, PATCHing, and DELETing books will all require that we do pass that ID to our endpoint, which we\u2019ll discuss later. For now, let\u2019s simply create the endpoints:<\/p>\n<div>\n<pre><code>\/\/ HTTP POST \/books\napp.post('\/books', (req, res) => {\n    \/\/ ...\n    console.log('A POST Request was made!');\n});\n\n\/\/ HTTP GET \/books\/:id\napp.get('\/books\/:id', (req, res) => {\n    \/\/ ...\n    console.log(`A GET Request was made! Getting book ${req.params.id}`);\n});\n\n\/\/ HTTP PATCH \/books\/:id\napp.patch('\/books\/:id', (req, res) => {\n    \/\/ ...\n    console.log(`A PATCH Request was made! Updating book ${req.params.id}`);\n});\n\n\/\/ HTTP DELETE \/books\/:id\napp.delete('\/books\/:id', (req, res) => {\n    \/\/ ...\n    console.log(`A DELETE Request was made! Deleting book ${req.params.id}`);\n});<\/code><\/pre>\n<\/div>\n<p>The <code>:id<\/code> syntax tells Express that <code>id<\/code> is a dynamic parameter that will be passed up in the URL. We have access to it on the <code>params<\/code> object which is available on <code>req<\/code>. I know \u201cwe have access to it on <code>req<\/code>\u201d sounds like magic and magic (which doesn\u2019t exist) is dangerous in programming, but you have to remember that Express is not a black box. It\u2019s an open-source project available on GitHub under an MIT LIcense. You can easily view it\u2019s source code if you want to see how dynamic query parameters are put onto the <code>req<\/code> object.<\/p>\n<p>All together, we now have the following in our <code>server.js<\/code> file:<\/p>\n<div>\n<pre><code>\/\/ Getting the module from node_modules.\nconst express = require('express'); \n\n\/\/ This creates our Express App.\nconst app = express(); \n\n\/\/ Define middleware.\napp.use(express.json());\napp.use(express.urlencoded({ extended: true }));\n\n\/\/ Listening on port 3000 (arbitrary).\n\/\/ Not a TCP or UDP well-known port. \n\/\/ Does not require superuser privileges.\nconst PORT = 3000;\n\n\/\/ We will build our API here.\n\/\/ HTTP POST \/books\napp.post('\/books', (req, res) => {\n    \/\/ ...\n    console.log('A POST Request was made!');\n});\n\n\/\/ HTTP GET \/books\/:id\napp.get('\/books\/:id', (req, res) => {\n    \/\/ ...\n    console.log(`A GET Request was made! Getting book ${req.params.id}`);\n});\n\n\/\/ HTTP PATCH \/books\/:id\napp.patch('\/books\/:id', (req, res) => {\n    \/\/ ...\n    console.log(`A PATCH Request was made! Updating book ${req.params.id}`);\n});\n\n\/\/ HTTP DELETE \/books\/:id\napp.delete('\/books\/:id', (req, res) => {\n    \/\/ ...\n    console.log(`A DELETE Request was made! Deleting book ${req.params.id}`);\n});\n\n\/\/ Binding our application to port 3000.\napp.listen(PORT, () => console.log(`Server is up on port ${PORT}.`));<\/code><\/pre>\n<\/div>\n<p>Go ahead and start the server, running <code>node server.js<\/code> from the terminal or command line, and visit your browser. Open the Chrome Development Console, and in the URL (Uniform Resource Locator) Bar, visit <code>localhost:3000\/books<\/code>. You should already see the indicator in your OS\u2019s terminal that the server is up as well as the log statement for GET.<\/p>\n<p>Thus far, we\u2019ve been using a web browser to perform GET Requests. That is good for just starting out, but we\u2019ll quickly find that better tools exist to test API routes. Indeed, we could paste <code>fetch<\/code> calls directly into the console or use some online service. In our case, and to save time, we\u2019ll use <code>cURL<\/code> and Postman. I use both in this article (although you could use either or) so that I can introduce them for if you haven\u2019t used them. <code>cURL<\/code> is a library (a very, very important library) and command-line tool designed to transfer data using various protocols. Postman is a GUI based tool for testing APIs. After following the relevant installation instructions for both tools on your operating system, ensure your server is still running, and then execute the following commands (one-by-one) in a new terminal. It\u2019s important that you type them and execute them individually, and then watch the log message in the separate terminal from your server. Also, note that the standard programming language comment symbol <code>\/\/<\/code> is not a valid symbol in Bash or MS-DOS. You\u2019ll have to omit those lines, and I only use them here to describe each block of <code>cURL<\/code> commands.<\/p>\n<pre><code>\/\/ HTTP POST Request (Localhost, IPv4, IPv6)\ncurl -X POST http:\/\/localhost:3000\/books\ncurl -X POST http:\/\/127.0.0.1:3000\/books\ncurl -X POST http:\/\/[::1]:3000\/books\n\n\/\/ HTTP GET Request (Localhost, IPv4, IPv6)\ncurl -X GET http:\/\/localhost:3000\/books\/123abc\ncurl -X GET http:\/\/127.0.0.1:3000\/books\/book-id-123\ncurl -X GET http:\/\/[::1]:3000\/books\/book-abc123\n\n\/\/ HTTP PATCH Request (Localhost, IPv4, IPv6)\ncurl -X PATCH http:\/\/localhost:3000\/books\/456\ncurl -X PATCH http:\/\/127.0.0.1:3000\/books\/218\ncurl -X PATCH http:\/\/[::1]:3000\/books\/some-id\n\n\/\/ HTTP DELETE Request (Localhost, IPv4, IPv6)\ncurl -X DELETE http:\/\/localhost:3000\/books\/abc\ncurl -X DELETE http:\/\/127.0.0.1:3000\/books\/314\ncurl -X DELETE http:\/\/[::1]:3000\/books\/217<\/code><\/pre>\n<p>As you can see, the ID that is passed in as a URL Parameter can be any value. The <code>-X<\/code> flag specifies the type of HTTP Request (it can be omitted for GET), and we provide the URL to which the request will be made thereafter. I\u2019ve duplicated each request three times, allowing you to see that everything still works whether you use the <code>localhost<\/code> hostname, the IPv4 Address (<code>127.0.0.1<\/code>) to which <code>localhost<\/code> resolves, or the IPv6 Address (<code>::1<\/code>) to which <code>localhost<\/code> resolves. Note that <code>cURL<\/code> requires wrapping IPv6 Addresses in square brackets.<\/p>\n<p>We are in a decent place now \u2014 we have the simple structure of our routes and endpoints set up. The server runs correctly and accepts HTTP Requests as we expect it to. Contrary to what you might expect, there is not long to go at this point \u2014 we just have to set up our database, host it (using a Database-as-a-Service \u2014 MongoDB Atlas), and persist data to it (and perform validation and create error responses).<\/p>\n<h3>Setting Up A Production MongoDB Database<\/h3>\n<p>To set up a production database, we\u2019ll head over to the <a href=\"https:\/\/www.mongodb.com\/cloud\/atlas\">MongoDB Atlas Home Page<\/a> and sign up for a free account. Thereafter, create a new cluster. You can maintain the default settings, picking a fee tier applicable region. Then hit the \u201cCreate Cluster\u201d button. The cluster will take some time to create, and then you\u2019ll be able to attain your database URL and password. Take note of these when you see them. We\u2019ll hardcode them for now, and then store them in environment variables later for security purposes. For help in creating and connecting to a cluster, I\u2019ll refer you to the MongoDB Documentation, particularly <a href=\"https:\/\/docs.atlas.mongodb.com\/create-new-cluster\/\">this page<\/a> and <a href=\"https:\/\/docs.atlas.mongodb.com\/connect-to-cluster\/\">this page<\/a>, or you can leave a comment below and I\u2019ll try to help.<\/p>\n<h3>Creating A Mongoose Model<\/h3>\n<p>It\u2019s recommended that you have an understanding of the meanings of Documents and Collections in the context of NoSQL (Not Only SQL \u2014 Structured Query Language). For reference, you might want to read both the <a href=\"https:\/\/mongoosejs.com\/docs\/index.html\">Mongoose Quick Start Guide<\/a> and the <a href=\"https:\/\/www.smashingmagazine.com\/2019\/02\/node-api-http-es6-javascript\/\">MongoDB<\/a> section of my former article.<\/p>\n<p>We now have a database that is ready to accept CRUD Operations. Mongoose is a Node module (or ODM \u2014 Object Document Mapper) that will allow us to perform those operations (abstracting away some of the complexities) as well as set up the schema, or structure, of the database collection.<\/p>\n<p>As an important disclaimer, there is a lot of controversy around ORMs and such patterns as Active Record or Data Mapper. Some developers swear by ORMs and others swear against them (believing they get in the way). It\u2019s also important to note that ORMs abstract a lot away like connection pooling, socket connections, and handling, etc. You could easily use the MongoDB Native Driver (another NPM Module), but it would talk a lot more work. While it\u2019s recommended that you play with the Native Driver before using ORMs, I omit the Native Driver here for brevity. For complex SQL operations on a Relational Database, not all ORMs will be optimized for query speed, and you may end up writing your own raw SQL. ORMs can come into play a lot with Domain-Driven Design and CQRS, among others. They are an established concept in the .NET world, and the Node.js community has not completely caught up yet \u2014 TypeORM is better, but it\u2019s not NHibernate or Entity Framework.<\/p>\n<p>To create our Model, I\u2019ll create a new folder in the <code>server<\/code> directory entitled <code>models<\/code>, within which I\u2019ll create a single file with the name <code>book.js<\/code>. Thus far, our project\u2019s directory structure is as follows:<\/p>\n<pre><code>- server\n  - node_modules\n  - models\n    - book.js\n  - package.json\n  - server.js<\/code><\/pre>\n<p>Indeed, this directory structure is not required, but I use it here because it\u2019s simple. Allow me to note that this is not at all the kind of architecture you want to use for larger applications (and you might not even want to use JavaScript \u2014 TypeScript could be a better option), which I discuss in this article\u2019s closing. The next step will be to install <code>mongoose<\/code>, which is performed via, as you might expect, <code>npm i mongoose<\/code>.<\/p>\n<p>The meaning of a Model is best ascertained from the Mongoose documentation:<\/p>\n<blockquote>\n<p><a href=\"https:\/\/mongoosejs.com\/docs\/api.html#model-js\">Models<\/a> are fancy constructors compiled from <code>Schema<\/code> definitions. An instance of a model is called a <a href=\"https:\/\/mongoosejs.com\/docs\/documents.html\">document<\/a>. Models are responsible for creating and reading documents from the underlying MongoDB database.<\/p>\n<\/blockquote>\n<p>Before creating the Model, we\u2019ll define its Schema. A Schema will, among others, make certain expectations about the value of the properties provided. MongoDB is schemaless, and thus this functionality is provided by the Mongoose ODM. Let\u2019s start with a simple example. Suppose I want my database to store a user\u2019s name, email address, and password. Traditionally, as a plain old JavaScript Object (POJO), such a structure might look like this:<\/p>\n<pre><code>const userDocument = {\n    name: 'Jamie Corkhill',\n    email: 'jamie@domain.com',\n    password: 'Bcrypt Hash'\n};<\/code><\/pre>\n<p>If that above object was how we expected our user\u2019s object to look, then we would need to define a schema for it, like this:<\/p>\n<pre><code>const schema = {\n    name: {\n        type: String,\n        trim: true,\n        required: true\n    },\n    email: {\n        type: String,\n        trim: true,\n        required: true\n    },\n    password: {\n        type: String,\n        required: true\n    }\n};<\/code><\/pre>\n<p>Notice that when creating our schema, we define what properties will be available on each document in the collection as an object in the schema. In our case, that\u2019s <code>name<\/code>, <code>email<\/code>, and <code>password<\/code>. The fields <code>type<\/code>, <code>trim<\/code>, <code>required<\/code> tell Mongoose what data to expect. If we try to set the <code>name<\/code> field to a number, for example, or if we don\u2019t provide a field, Mongoose will throw an error (because we are expecting a type of <code>String<\/code>), and we can send back a <code>400 Bad Request<\/code> to the client. This might not make sense right now because we have defined an arbitrary <code>schema<\/code> object. However, the fields of <code>type<\/code>, <code>trim<\/code>, and <code>required<\/code> (among others) are special validators that Mongoose understands. <code>trim<\/code>, for example, will remove any whitespace from the beginning and end of the string. We\u2019ll pass the above schema to <code>mongoose.Schema()<\/code> in the future and that function will know what to do with the validators.<\/p>\n<p>Understanding how Schemas work, we\u2019ll create the model for our Books Collection of the Bookshelf API. Let\u2019s define what data we require:<\/p>\n<ol>\n<li>\n<p>Title<\/p>\n<\/li>\n<li>\n<p>ISBN Number<\/p>\n<\/li>\n<li>\n<p>Author<\/p>\n<ol>\n<li>\n<p>First Name<\/p>\n<\/li>\n<li>\n<p>Last Name<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>Publishing Date<\/p>\n<\/li>\n<li>\n<p>Finished Reading (Boolean)<\/p>\n<\/li>\n<\/ol>\n<p>I\u2019m going to create this in the <code>book.js<\/code> file we created earlier in <code>\/models<\/code>. Like the example above, we\u2019ll be performing validation:<\/p>\n<pre><code>const mongoose = require('mongoose');\n\n\/\/ Define the schema:\nconst mySchema = {\n    title: {\n        type: String,\n        required: true,\n        trim: true,\n    },\n    isbn: {\n        type: String,\n        required: true,\n        trim: true,\n    },\n    author: {\n        firstName:{\n            type: String,\n            required: true,\n            trim: true\n        },\n        lastName: {\n            type: String,\n            required: true,\n            trim: true\n        }\n    },\n    publishingDate: {\n        type: String\n    },\n    finishedReading: {\n        type: Boolean,\n        required: true,\n        default: false\n    }\n}<\/code><\/pre>\n<p><code>default<\/code> will set a default value for the property if none is provided \u2014 <code>finishedReading<\/code> for example, although a required field, will be set automatically to <code>false<\/code> if the client does not send one up.<\/p>\n<p>Mongoose also provides the ability to perform custom validation on our fields, which is done by supplying the <code>validate()<\/code> method, which attains the value that was attempted to be set as its one and only parameter. In this function, we can throw an error if the validation fails. Here is an example:<\/p>\n<pre><code>\/\/ ...\nisbn: {\n    type: String,\n    required: true,\n    trim: true,\n    validate(value) {\n        if (!validator.isISBN(value)) {\n            throw new Error('ISBN is invalid.');\n        }\n    }\n}\n\/\/ ...<\/code><\/pre>\n<p>Now, if anyone supplies an invalid ISBN to our model, Mongoose will throw an error when trying to save that document to the collection. I\u2019ve already installed the NPM module <code>validator<\/code> via <code>npm i validator<\/code> and required it. <code>validator<\/code> contains a bunch of helper functions for common validation requirements, and I use it here instead of RegEx because ISBNs can\u2019t be validated with RegEx alone due to a tailing checksum. Remember, users will be sending a JSON body to one of our POST routes. That endpoint will catch any errors (such as an invalid ISBN) when attempting to save, and if one is thrown, it\u2019ll return a blank response with an <code>HTTP 400 Bad Request<\/code> status \u2014 we haven\u2019t yet added that functionality.<\/p>\n<p>Finally, we have to define our schema of earlier as the schema for our model, so I\u2019ll make a call to <code>mongoose.Schema()<\/code> passing in that schema:<\/p>\n<pre><code>const bookSchema = mongoose.Schema(mySchema);<\/code><\/pre>\n<p>To make things more precise and clean, I\u2019ll replace the <code>mySchema<\/code> variable with the actual object all on one line:<\/p>\n<pre><code>const bookSchema = mongoose.Schema({\n    title:{\n        type: String,\n        required: true,\n        trim: true,\n    },\n    isbn:{\n        type: String,\n        required: true,\n        trim: true,\n        validate(value) {\n           if (!validator.isISBN(value)) {\n                throw new Error('ISBN is invalid.');\n           }\n        }\n    },\n    author:{\n        firstName: {\n            type: String\n            required: true,\n            trim: true\n        },\n        lastName:{\n            type: String,\n            required: true,\n            trim: true\n        }\n    },\n    publishingDate:{\n        type: String\n    },\n    finishedReading:{\n        type: Boolean,\n        required: true,\n        default: false\n    }\n});<\/code><\/pre>\n<p>Let\u2019s take a final moment to discuss this schema. We are saying that each of our documents will consist of a title, an ISBN, an author with a first and last name, a publishing date, and a finishedReading boolean.<\/p>\n<ol>\n<li><code>title<\/code> will be of type <code>String<\/code>, it\u2019s a required field, and we\u2019ll trim any whitespace.<\/li>\n<li><code>isbn<\/code> will be of type <code>String<\/code>, it\u2019s a required field, it must match the validator, and we\u2019ll trim any whitespace.<\/li>\n<li><code>author<\/code> is of type <code>object<\/code> containing a required, trimmed, <code>string<\/code> firstName and a required, trimmed, <code>string<\/code> lastName.<\/li>\n<li><code>publishingDate<\/code> is of type String (although we could make it of type <code>Date<\/code> or <code>Number<\/code> for a Unix timestamp.<\/li>\n<li><code>finishedReading<\/code> is a required <code>boolean<\/code> that will default to <code>false<\/code> if not provided.<\/li>\n<\/ol>\n<p>With our <code>bookSchema<\/code> defined, Mongoose knows what data and what fields to expect within each document to the collection that stores books. However, how do we tell it what collection that specific schema defines? We could have hundreds of collections, so how do we correlate, or tie, <code>bookSchema<\/code> to the <code>Book<\/code> collection?<\/p>\n<p>The answer, as seen earlier, is with the use of models. We\u2019ll use <code>bookSchema<\/code> to create a model, and that model will model the data to be stored in the Book collection, which will be created by Mongoose automatically.<\/p>\n<p>Append the following lines to the end of the file:<\/p>\n<pre><code>const Book = mongoose.model('Book', bookSchema);\n\nmodule.exports = Book;<\/code><\/pre>\n<p>As you can see, we have created a model, the name of which is <code>Book<\/code> (\u2014 the first parameter to <code>mongoose.model()<\/code>), and also provided the ruleset, or schema, to which all data is saved in the Book collection will have to abide. We export this model as a default export, allowing us to <code>require<\/code> the file for our endpoints to access. <code>Book<\/code> is the object upon which we\u2019ll call all of the required functions to Create, Read, Update, and Delete data which are provided by Mongoose.<\/p>\n<p>Altogether, our <code>book.js<\/code> file should look as follows:<\/p>\n<div>\n<pre><code>const mongoose = require('mongoose');\nconst validator = require('validator');\n\n\/\/ Define the schema.\nconst bookSchema = mongoose.Schema({\n    title:{\n        type: String,\n        required: true,\n        trim: true,\n    },\n    isbn:{\n        type: String,\n        required: true,\n        trim: true,\n        validate(value) {\n            if (!validator.isISBN(value)) {\n                throw new Error('ISBN is invalid.');\n            }\n        }\n    },\n    author:{\n        firstName: {\n            type: String,\n            required: true,\n            trim: true\n        },\n        lastName:{\n            type: String,\n            required: true,\n            trim: true\n        }\n    },\n    publishingDate:{\n        type: String\n    },\n    finishedReading:{\n        type: Boolean,\n        required: true,\n        default: false\n    }\n});\n\n\/\/ Create the \"Book\" model of name Book with schema bookSchema.\nconst Book = mongoose.model('Book', bookSchema);\n\n\/\/ Provide the model as a default export.\nmodule.exports = Book;<\/code><\/pre>\n<\/div>\n<h3>Connecting To MongoDB (Basics)<\/h3>\n<p>Don\u2019t worry about copying down this code. I\u2019ll provide a better version in the next section. To connect to our database, we\u2019ll have to provide the database URL and password. We\u2019ll call the <code>connect<\/code> method available on <code>mongoose<\/code> to do so, passing to it the required data. For now, we are going hardcode the URL and password \u2014 an extremely frowned upon technique for many reasons: namely the accidental committing of sensitive data to a public (or private made public) GitHub Repository. Realize also that commit history is saved, and that if you accidentally commit a piece of sensitive data, removing it in a future commit will not prevent people from seeing it (or bots from harvesting it), because it\u2019s still available in the commit history. CLI tools exist to mitigate this issue and remove history.<\/p>\n<p>As stated, for now, we\u2019ll hard code the URL and password, and then save them to environment variables later. At this point, let\u2019s look at simply how to do this, and then I\u2019ll mention a way to optimize it.<\/p>\n<pre><code>const mongoose = require('mongoose');\n\nconst MONGODB_URL = 'Your MongoDB URL';\n\nmongoose.connect(MONGODB_URL, {\n    useNewUrlParser: true,\n    useCreateIndex: true,\n    useFindAndModify: false,\n    useUnifiedTopology: true\n});<\/code><\/pre>\n<p>This will connect to the database. We provide the URL that we attained from the MongoDB Atlas dashboard, and the object passed in as the second parameter specifies features to use as to, among others, prevent deprecation warnings.<\/p>\n<p>Mongoose, which uses the core MongoDB Native Driver behind the scenes, has to attempt to keep up with breaking changes made to the driver. In a new version of the driver, the mechanism used to parse connection URLs was changed, so we pass the <code>useNewUrlParser: true<\/code> flag to specify that we want to use the latest version available from the official driver.<\/p>\n<p>By default, if you set indexes (and they are called \u201cindexes\u201d not \u201cindices\u201d) (which we won\u2019t cover in this article) on data in your database, Mongoose uses the <code>ensureIndex()<\/code> function available from the Native Driver. MongoDB deprecated that function in favor of <code>createIndex()<\/code>, and so setting the flag <code>useCreateIndex<\/code> to true will tell Mongoose to use the <code>createIndex()<\/code> method from the driver, which is the non-deprecated function.<\/p>\n<p>Mongoose\u2019s original version of <code>findOneAndUpdate<\/code> (which is a method to find a document in a database and update it) pre-dates the Native Driver version. That is, <code>findOneAndUpdate()<\/code> was not originally a Native Driver function but rather one provided by Mongoose, so Mongoose had to use <code>findAndModify<\/code> provided behind the scenes by the driver to create <code>findOneAndUpdate<\/code> functionality. With the driver now updated, it contains its own such function, so we don\u2019t have to use <code>findAndModify<\/code>. This might not make sense, and that\u2019s okay \u2014 it\u2019s not an important piece of information on the scale of things.<\/p>\n<p>Finally, MongoDB deprecated its old server and engine monitoring system. We use the new method with <code>useUnifiedTopology: true<\/code>.<\/p>\n<p>What we have thus far is a way to connect to the database. But here\u2019s the thing \u2014 it\u2019s not scalable or efficient. When we write unit tests for this API, the unit tests are going to use their own test data (or fixtures) on their own test databases. So, we want a way to be able to create connections for different purposes \u2014 some for testing environments (that we can spin up and tear down at will), others for development environments, and others for production environments. To do that, we\u2019ll build a factory. (Remember that from earlier?)<\/p>\n<h3>Connecting To Mongo \u2014 Building An Implementation Of A JS Factory<\/h3>\n<p>Indeed, Java Objects are not analogous at all to JavaScript Objects, and so, subsequently, what we know above from the Factory Design Pattern won\u2019t apply. I merely provided that as an example to show the traditional pattern. To attain an object in Java, or C#, or C++, etc., we have to instantiate a class. This is done with the <code>new<\/code> keyword, which instructs the compiler to allocate memory for the object on the heap. In C++, this gives us a pointer to the object that we have to clean up ourselves so we don\u2019t have hanging pointers or memory leaks (C++ has no garbage collector, unlike Node\/V8 which is built on C++) In JavaScript, the above need not be done \u2014 we don\u2019t need to instantiate a class to attain an object \u2014 an object is just <code>{}<\/code>. Some people will say that everything in JavaScript is an object, although that is technically not true because primitive types are not objects.<\/p>\n<p>For the above reasons, our JS Factory will be simpler, sticking to the loose definition of a factory being a function that returns an object (a JS object). Since a function is an object (for <code>function<\/code> inherits from <code>object<\/code> via prototypal inheritance), our below example will meet this criterion. To implement the factory, I\u2019ll create a new folder inside of <code>server<\/code> called <code>db<\/code>. Within <code>db<\/code> I\u2019ll create a new file called <code>mongoose.js<\/code>. This file will make connections to the database. Inside of <code>mongoose.js<\/code>, I\u2019ll create a function called <code>connectionFactory<\/code> and export it by default:<\/p>\n<pre><code>\/\/ Directory - server\/db\/mongoose.js\n\nconst mongoose = require('mongoose');\n\nconst MONGODB_URL = 'Your MongoDB URL';\n\nconst connectionFactory = () => {\n    return mongoose.connect(MONGODB_URL, {\n        useNewUrlParser: true,\n        useCreateIndex: true,\n        useFindAndModify: false\n    });\n};\n\nmodule.exports = connectionFactory;<\/code><\/pre>\n<p>Using the shorthand provided by ES6 for Arrow Functions that return one statement on the same line as the method signature, I\u2019ll make this file simpler by getting rid of the <code>connectionFactory<\/code> definition and just exporting the factory by default:<\/p>\n<pre><code>\/\/ server\/db\/mongoose.js\nconst mongoose = require('mongoose');\n\nconst MONGODB_URL = 'Your MongoDB URL';\n\nmodule.exports = () => mongoose.connect(MONGODB_URL, {\n    useNewUrlParser: true,\n    useCreateIndex: true,\n    useFindAndModify: true\n});<\/code><\/pre>\n<p>Now, all one has to do is require the file and call the method that gets exported, like this:<\/p>\n<pre><code>const connectionFactory = require('.\/db\/mongoose');\nconnectionFactory();\n\n\/\/ OR\n\nrequire('.\/db\/mongoose')();<\/code><\/pre>\n<p>You could invert control by having your MongoDB URL be provided as a parameter to the factory function, but we are going to dynamically change the URL as an environment variable based on environment.<\/p>\n<p>The benefits of making our connection as a function are that we can call that function later in code to connect to the database from files aimed at production and those aimed at local and remote integration testing both on-device and with a remote CI\/CD pipeline\/build server.<\/p>\n<h3>Building Our Endpoints<\/h3>\n<p>We now begin to add very simple CRUD related logic to our endpoints. As previously stated, a short disclaimer is in order. The methods by which we go about implementing our business logic here are <strong>not<\/strong> ones that you should mirror for anything other than simple projects. Connecting to databases and performing logic directly within endpoints is (and should be) frowned upon, for you lose the ability to swap out services or DBMSs without having to perform an application wide refactor. Nonetheless, considering this is a beginner\u2019s article, I employ these bad practices here. A future article in this series will discuss how we can increase both the complexity and the quality of our architecture.<\/p>\n<p>For now, let\u2019s go back to our <code>server.js<\/code> file and ensure we both have the same starting point. Notice I added the <code>require<\/code> statement for our database connection factory and I imported the model we exported from <code>.\/models\/book.js<\/code>.<\/p>\n<div>\n<pre><code>const express = require('express'); \n\n\/\/ Database connection and model.\nrequire('.\/db\/mongoose.js');\nconst Book = require('.\/models\/book.js');\n\n\/\/ This creates our Express App.\nconst app = express(); \n\n\/\/ Define middleware.\napp.use(express.json());\napp.use(express.urlencoded({ extended: true }));\n\n\/\/ Listening on port 3000 (arbitrary).\n\/\/ Not a TCP or UDP well-known port. \n\/\/ Does not require superuser privileges.\nconst PORT = 3000;\n\n\/\/ We will build our API here.\n\/\/ HTTP POST \/books\napp.post('\/books', (req, res) => {\n    \/\/ ...\n    console.log('A POST Request was made!');\n});\n\n\/\/ HTTP GET \/books\/:id\napp.get('\/books\/:id', (req, res) => {\n    \/\/ ...\n    console.log(`A GET Request was made! Getting book ${req.params.id}`);\n});\n\n\/\/ HTTP PATCH \/books\/:id\napp.patch('\/books\/:id', (req, res) => {\n    \/\/ ...\n    console.log(`A PATCH Request was made! Updating book ${req.params.id}`);\n});\n\n\/\/ HTTP DELETE \/books\/:id\napp.delete('\/books\/:id', (req, res) => {\n    \/\/ ...\n    console.log(`A DELETE Request was made! Deleting book ${req.params.id}`);\n});\n\n\/\/ Binding our application to port 3000.\napp.listen(PORT, () => console.log(`Server is up on port ${PORT}.`));<\/code><\/pre>\n<\/div>\n<p>I\u2019m going to start with <code>app.post()<\/code>. We have access to the <code>Book<\/code> model because we exported it from the file within which we created it. As stated in the Mongoose docs, <code>Book<\/code> is constructable. To create a new book, we call the constructor and pass the book data in, as follows:<\/p>\n<pre><code>const book = new Book(bookData);<\/code><\/pre>\n<p>In our case, we\u2019ll have <code>bookData<\/code> as the object sent up in the request, which will be available on <code>req.body.book<\/code>. Remember, <code>express.json()<\/code> middleware will put any JSON data that we send up onto <code>req.body<\/code>. We are to send up JSON in the following format:<\/p>\n<div>\n<pre><code>{\n    \"book\": {\n        \"title\": \"The Art of Computer Programming\",\n        \"isbn\": \"ISBN-13: 978-0-201-89683-1\",\n        \"author\": { \n            \"firstName\": \"Donald\", \n            \"lastName\": \"Knuth\" \n        }, \n        \"publishingDate\": \"July 17, 1997\",\n        \"finishedReading\": true\n    }\n}<\/code><\/pre>\n<\/div>\n<p>What that means, then, is that the JSON we pass up will get parsed, and the entire JSON object (the first pair of braces) will be placed on <code>req.body<\/code> by the <code>express.json()<\/code> middleware. The one and only property on our JSON object is <code>book<\/code>, and thus the <code>book<\/code> object will be available on <code>req.body.book<\/code>.<\/p>\n<p>At this point, we can call the model constructor function and pass in our data:<\/p>\n<div>\n<pre><code>app.post('\/books', async (req, res) => {    \/\/ <\/code><\/pre>\n<\/div>\n<p>Notice a few things here. Calling the <code>save<\/code> method on the instance we get back from calling the constructor function will persist the <code>req.body.book<\/code> object to the database if and only if it complies with the schema we defined in the Mongoose model. The act of saving data to a database is an asynchronous operation, and this <code>save()<\/code> method returns a promise \u2014 the settling of which we much await. Rather than chain on a <code>.then()<\/code> call, I  use the ES6 Async\/Await syntax, which means I must make the callback function to <code>app.post<\/code> <code>async<\/code>.<\/p>\n<p><code>book.save()<\/code> will reject with a <code>ValidationError<\/code> if the object the client sent up does not comply with the schema we defined. Our current setup makes for some very flaky and badly written code, for we don\u2019t want our application to crash in the event of a failure regarding validation. To fix that, I\u2019ll surround the dangerous operation in a <code>try\/catch<\/code> clause. In the event of an error, I\u2019ll return an HTTP 400 Bad Request or an HTTP 422 Unprocessable Entity. There is some amount of debate over which to use, so I\u2019ll stick with a 400 for this article since it is more generic.<\/p>\n<div>\n<pre><code>app.post('\/books', async (req, res) => { \n    try {\n        const book = new Book(req.body.book);\n        await book.save();    \n        return res.status(201).send({ book });\n    } catch (e) {\n        return res.status(400).send({ error: 'ValidationError' });\n    }\n});<\/code><\/pre>\n<\/div>\n<p>Notice that I use the ES6 Object Shorthand to just return the <code>book<\/code> object right back to the client in the success case with <code>res.send({ book })<\/code> \u2014 that would be equivalent to <code>res.send({ book: book })<\/code>. I also return the expression just to make sure my function exits. In the <code>catch<\/code> block, I set the status to be 400 explicitly, and return the string \u2018ValidationError\u2019 on the <code>error<\/code> property of the object that gets sent back. A 201 is the success path status code meaning \u201cCREATED\u201d.<\/p>\n<p>Indeed, this isn\u2019t the best solution either because we can\u2019t really be sure the reason for failure was a Bad Request on the client\u2019s side. Maybe we lost connection (supposed a dropped socket connection, thus a transient exception) to the database, in which case we should probably return a 500 Internal Server error. A way to check this would be to read the <code>e<\/code> error object and selectively return a response.  Let\u2019s do that now, but as I\u2019ve said multiple times, a followup article will discuss proper architecture in terms of Routers, Controllers, Services, Repositories, custom error classes, custom error middleware, custom error responses, Database Model\/Domain Entity data mapping, and Command Query Separation (CQS).<\/p>\n<div>\n<pre><code>app.post('\/books', async (req, res) => {\n    try {\n        const book =  new  Book(req.body.book);\n        await book.save();\n        return res.send({ book });\n    } catch (e) {\n        if (e instanceof mongoose.Error.ValidationError) {\n            return res.status(400).send({  error:  'ValidationError' });\n        } else {\n            return res.status(500).send({  error:  'Internal Error' });\n        }\n    }\n});<\/code><\/pre>\n<\/div>\n<p>Go ahead and open Postman (assuming you have it, otherwise, download and install it) and create a new request. We\u2019ll be making a POST Request to <code>localhost:3000\/books<\/code>. Under the \u201cBody\u201d tab within the Postman Request section, I\u2019ll select the \u201craw\u201d radio button and select \u201cJSON\u201d in the dropdown button to the far right. This will go ahead and automatically add the <code>Content-Type: application\/json<\/code> header to the request. I\u2019ll then copy and paste the Book JSON Object from earlier into the Body text area. This is what we have:<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/3e18f752-56b9-4200-9ff0-90f608a5ffcc\/post-request-with-json-one.png?ssl=1\"><\/p>\n<p>    <img data-recalc-dims=\"1\" decoding=\"async\" srcset=\"https:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/11\/post-request-with-json-one.png 400w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_800\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/3e18f752-56b9-4200-9ff0-90f608a5ffcc\/post-request-with-json-one.png 800w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1200\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/3e18f752-56b9-4200-9ff0-90f608a5ffcc\/post-request-with-json-one.png 1200w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1600\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/3e18f752-56b9-4200-9ff0-90f608a5ffcc\/post-request-with-json-one.png 1600w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_2000\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/3e18f752-56b9-4200-9ff0-90f608a5ffcc\/post-request-with-json-one.png 2000w\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/11\/post-request-with-json-one.png?w=900&#038;ssl=1\" sizes=\"100vw\" alt=\"The Postman GUI populated with data for the POST Request.\"><\/a><figcaption>\n      Data to populate Postman fields with for our POST Request. (<a href=\"https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/3e18f752-56b9-4200-9ff0-90f608a5ffcc\/post-request-with-json-one.png\">Large preview<\/a>)<br \/>\n    <\/figcaption><\/figure>\n<p>Thereafter, I\u2019ll hit the send button, and you should see a 201 Created response in the \u201cResponse\u201d section of Postman (the bottom row). We see this because we specifically asked Express to respond with a 201 and the Book object \u2014 had we just done <code>res.send()<\/code> with no status code, <code>express<\/code>  would have automatically responded with a 200 OK. As you can see, the Book object is now saved to the database and has been returned to the client as the Response to the POST Request.<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/48e7794b-918a-47bd-a7b8-a4a596096a04\/postman-with-json.png?ssl=1\"><\/p>\n<p>    <img data-recalc-dims=\"1\" decoding=\"async\" srcset=\"https:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/11\/postman-with-json.png 400w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_800\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/48e7794b-918a-47bd-a7b8-a4a596096a04\/postman-with-json.png 800w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1200\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/48e7794b-918a-47bd-a7b8-a4a596096a04\/postman-with-json.png 1200w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1600\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/48e7794b-918a-47bd-a7b8-a4a596096a04\/postman-with-json.png 1600w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_2000\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/48e7794b-918a-47bd-a7b8-a4a596096a04\/postman-with-json.png 2000w\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/11\/postman-with-json.png?w=900&#038;ssl=1\" sizes=\"100vw\" alt=\"The Postman GUI populated with response data from the POST Request.\"><\/a><figcaption>\n      JSON Payload Response to our POST Request. (<a href=\"https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/48e7794b-918a-47bd-a7b8-a4a596096a04\/postman-with-json.png\">Large preview<\/a>)<br \/>\n    <\/figcaption><\/figure>\n<p>If you view the database Book collection through MongoDB Atlas, you\u2019ll see that the book was indeed saved.<\/p>\n<p>You can also tell that MongoDB has inserted the <code>__v<\/code> and <code>_id<\/code> fields. The former represents the version of the document, in this case, 0, and the latter is the document\u2019s ObjectID \u2014 which is automatically generated by MongoDB and is guaranteed to have a low collision probability.<\/p>\n<h3>A Summary Of What We Have Covered Thus Far<\/h3>\n<p>We have covered a lot thus far in the article. Let\u2019s take a short reprieve by going over a brief summary before returning to finish the Express API.<\/p>\n<p>We learned about ES6 Object Destructuring, the ES6 Object Shorthand Syntax, as well as the ES6 Rest\/Spread operator. All three of those let us do the following (and more, as discussed above):<\/p>\n<div>\n<pre><code>\/\/ Destructuring Object Properties:\nconst { a: newNameA = 'Default', b } = { a: 'someData', b: 'info' };\nconsole.log(`newNameA: ${newNameA}, b: ${b}`); \/\/ newNameA: someData, b: info\n\n\/\/ Destructuring Array Elements\nconst [elemOne, elemTwo] = [() => console.log('hi'), 'data'];\nconsole.log(`elemOne(): ${elemOne()}, elemTwo: ${elemTwo}`); \/\/ elemOne(): hi, elemTwo: data\n\n\/\/ Object Shorthand\nconst makeObj = (name) => ({ name });\nconsole.log(`makeObj('Tim'): ${JSON.stringify(makeObj('Tim'))}`); \/\/ makeObj('Tim'): { \"name\": \"Tim\" }\n\n\/\/ Rest, Spread\nconst [c, d, ...rest] = [0, 1, 2, 3, 4];\nconsole.log(`c: ${c}, d: ${d}, rest: ${rest}`) \/\/ c: 0, d: 1, rest: 2, 3, 4<\/code><\/pre>\n<\/div>\n<p>We also covered Express, Expess Middleware, Servers, Ports, IP Addressing, etc. Things got interesting when we learned that there exist methods availabile on the return result from <code>require('express')();<\/code> with the names of the HTTP Verbs, such as <code>app.get<\/code> and <code>app.post<\/code>.<\/p>\n<p>If that <code>require('express')()<\/code> part didn\u2019t make sense to you, this was the point I was making:<\/p>\n<pre><code>const express = require('express');\nconst app = express();\napp.someHTTPVerb<\/code><\/pre>\n<p>It should make sense in the same way that we fired off the connection factory before for Mongoose.<\/p>\n<p>Each route handler, which is the endpoint function (or callback function), gets passed in a <code>req<\/code> object and a <code>res<\/code> object from Express behind the scenes. (They technically also get <code>next<\/code>, as we\u2019ll see in a minute). <code>req<\/code> contains data specific to the incoming request from the client, such as headers or any JSON sent up. <code>res<\/code> is what permits us to return responses to the client. The <code>next<\/code> function is also passed into handlers.<\/p>\n<p>With Mongoose, we saw how we can connect to the database with two methods \u2014 a primitive way and a more advanced\/practical way that borrows from the Factory Pattern. We\u2019ll end up using this when we discuss Unit and Integration Testing with Jest (and mutation testing) because it\u2019ll permit us to spin up a test instance of the DB populated with seed data against which we can run assertions.<\/p>\n<p>After that, we created a Mongoose schema object and used it to create a model, and then learned how we can call the constructor of that model to create a new instance of it. Available on the instance is a <code>save<\/code> method (among others), which is asynchronous in nature, and which will check that the object structure we passed in complies with the schema, resolving the promise if it does, and rejecting the promise with a <code>ValidationError<\/code> if it does not. In the event of a resolution, the new document is saved to the database and we respond with an HTTP 200 OK\/201 CREATED, otherwise, we catch the thrown error in our endpoint, and return an HTTP 400 Bad Request to the client.<\/p>\n<p>As we continue you building out our endpoints, you\u2019ll learn more about some of the methods available on the model and the model instance.<\/p>\n<h3>Finishing Our Endpoints<\/h3>\n<p>Having completed the POST Endpoint, let\u2019s handle GET. As I mentioned earlier, the <code>:id<\/code> syntax inside the route lets Express know that <code>id<\/code> is a route parameter, accessible from <code>req.params<\/code>. You already saw that when you match some ID for the param \u201cwildcard\u201d in the route, it was printed to the screen in the early examples. For instance, if you made a GET Request to \u201c\/books\/test-id-123\u201d, then <code>req.params.id<\/code> would be the string <code>test-id-123<\/code> because the param name was <code>id<\/code> by having the route as <code>HTTP GET \/books\/:id<\/code>.<\/p>\n<p>So, all we need to do is retrieve that ID from the <code>req<\/code> object and check to see if any document in our database has the same ID \u2014 something made very easy by Mongoose (and the Native Driver).<\/p>\n<div>\n<pre><code>app.get('\/books\/:id', async (req, res) => {\n    const book = await Book.findById(req.params.id);\n    console.log(book);\n    res.send({ book });\n});<\/code><\/pre>\n<\/div>\n<p>You can see that accessible upon our model is a function we can call that will find a document by its ID. Behind the scenes, Mongoose will cast whatever ID we pass into <code>findById<\/code> to the type of the <code>_id<\/code> field on the document, or in this case, an <code>ObjectId<\/code>. If a matching ID is found (and only one will ever be found for <code>ObjectId<\/code> has an extremely low collision probability), that document will be placed in our <code>book<\/code> constant variable. If not, <code>book<\/code> will be null \u2014 a fact we\u2019ll use in the near future.<\/p>\n<p>For now, let\u2019s restart the server (you must restart the server unless you\u2019re using <code>nodemon<\/code>) and ensure that we still have the one book document from before inside the <code>Books<\/code> Collection. Go ahead and copy the ID of that document, the highlighted portion of the image below:<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/10690f96-71d8-4c5f-8e91-2cc407db88f7\/id-to-use.png?ssl=1\"><\/p>\n<p>    <img data-recalc-dims=\"1\" decoding=\"async\" srcset=\"https:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/11\/id-to-use.png 400w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_800\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/10690f96-71d8-4c5f-8e91-2cc407db88f7\/id-to-use.png 800w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1200\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/10690f96-71d8-4c5f-8e91-2cc407db88f7\/id-to-use.png 1200w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1600\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/10690f96-71d8-4c5f-8e91-2cc407db88f7\/id-to-use.png 1600w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_2000\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/10690f96-71d8-4c5f-8e91-2cc407db88f7\/id-to-use.png 2000w\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/11\/id-to-use.png?w=900&#038;ssl=1\" sizes=\"100vw\" alt=\"The Book Document ObjectID\"><\/a><figcaption>\n      An example of an ObjectID to use for the upcoming GET Request. (<a href=\"https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/10690f96-71d8-4c5f-8e91-2cc407db88f7\/id-to-use.png\">Large preview<\/a>)<br \/>\n    <\/figcaption><\/figure>\n<p>And use it to make a GET Request to <code>\/books\/:id<\/code> with Postman as follows (note that the body data is just left over from my earlier POST Request. It\u2019s not actually being used despite the fact that it\u2019s depicted in the image below):<\/p>\n<figure><a href=\"https:\/\/i0.wp.com\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/1f521c4d-a437-45a0-b7e9-691ac60c7a8f\/book-get-req.png?ssl=1\"><\/p>\n<p>    <img data-recalc-dims=\"1\" decoding=\"async\" srcset=\"https:\/\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/11\/book-get-req.png 400w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_800\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/1f521c4d-a437-45a0-b7e9-691ac60c7a8f\/book-get-req.png 800w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1200\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/1f521c4d-a437-45a0-b7e9-691ac60c7a8f\/book-get-req.png 1200w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_1600\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/1f521c4d-a437-45a0-b7e9-691ac60c7a8f\/book-get-req.png 1600w,\n\t\t\t        https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_auto\/w_2000\/https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/1f521c4d-a437-45a0-b7e9-691ac60c7a8f\/book-get-req.png 2000w\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/11\/book-get-req.png?w=900&#038;ssl=1\" sizes=\"100vw\" alt=\"The Postman GUI populated with data for the GET Request.\"><\/a><figcaption>\n      API URL and Postman data for GET Request. (<a href=\"https:\/\/cloud.netlifyusercontent.com\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/1f521c4d-a437-45a0-b7e9-691ac60c7a8f\/book-get-req.png\">Large preview<\/a>)<br \/>\n    <\/figcaption><\/figure>\n<p>Upon doing so, you should get the book document with the specified ID back inside the Postman response section. Notice that earlier, with the POST Route, which is designed to \u201cPOST\u201d or \u201cpush\u201d new resources to the server, we responded with a 201 Created \u2014 because a new resource (or document) was created. In the case of GET, nothing new was created \u2014 we just requested a resource with a specific ID, thus a 200 OK status code is what we got back, instead of 201 Created.<\/p>\n<p>As is common in the field of software development, edge cases must be accounted for \u2014 user input is inherently unsafe and erroneous, and it\u2019s our job, as developers, to be flexible to the types of input we can be given and to respond to them accordingly. What do we do if the user (or the API Caller) passes us some ID that can\u2019t be cast to a MongoDB ObjectID, or an ID that can be cast but that doesn\u2019t exist?<\/p>\n<p>For the former case, Mongoose is going to throw a <code>CastError<\/code> \u2014 which is understandable because if we provide an ID like <code>math-is-fun<\/code>, then that\u2019s obviously not something that can be cast to an ObjectID, and casting to an ObjectID is specifically what Mongoose is doing under the hood.<\/p>\n<p>For the latter case, we could easily rectify the issue via a Null Check or a Guard Clause. Either way, I\u2019m going to send back and HTTP 404 Not Found Response. I\u2019ll show you a few ways we can do this, a bad way and then a better way.<\/p>\n<p>Firstly, we could do the following:<\/p>\n<div>\n<pre><code>app.get('\/books\/:id', async (req, res) => {\n    try {\n        const book = await Book.findById(req.params.id);\n        \n        if (!book) throw new Error();\n    \n        return res.send({ book });\n    } catch (e) {\n        return res.status(404).send({ error: 'Not Found' });\n    }\n});<\/code><\/pre>\n<\/div>\n<p>This works and we can use it just fine. I expect that the statement <code>await Book.findById()<\/code> will throw a Mongoose <code>CastError<\/code> if the ID string can\u2019t be cast to an ObjectID, causing the <code>catch<\/code> block to execute. If it can be cast but the corresponding ObjectID does not exist, then <code>book<\/code> will be <code>null<\/code> and the Null Check will throw an error, again firing the <code>catch<\/code> block. Inside <code>catch<\/code>, we just return a 404. There are two problems here. First, even if the Book is found but some other unknown error occurs, we send back a 404 when we should probably give the client a generic catch-all 500. Second, we are not really differentiating between whether the ID sent up is valid but non-existent, or whether it\u2019s just a bad ID.<\/p>\n<p>So, here is another way:<\/p>\n<div>\n<pre><code>const mongoose = require('mongoose');\n\napp.get('\/books\/:id', async (req, res) => {\n    try {\n        const book = await Book.findById(req.params.id);\n        \n        if (!book) return res.status(404).send({ error: 'Not Found' });\n        \n        return res.send({ book });\n    } catch (e) {\n        if (e instanceof mongoose.Error.CastError) {\n            return res.status(400).send({ error: 'Not a valid ID' });\n        } else {\n            return res.status(500).send({ error: 'Internal Error' });\n        }\n    }\n});<\/code><\/pre>\n<\/div>\n<p>The nice thing about this is that we can handle all three cases of a 400, a 404 and a generic 500. Notice that after the Null Check on <code>book<\/code>, I use the <code>return<\/code> keyword on my response. This is very important because we want to make sure we exit the route handler there.<\/p>\n<p>Some other options might be for us to check if the <code>id<\/code> on <code>req.params<\/code> can be cast to an ObjectID explicitly as opposed to permitting Mongoose to cast implicitly with <code>mongoose.Types.ObjectId.isValid('id);<\/code>, but there is an edge case with 12-byte strings that causes this to sometimes work unexpectedly.<\/p>\n<p>We could make said repetition less painful with <code>Boom<\/code>, an HTTP Response library, for example, or we could employ Error Handling Middleware. We could also transform Mongoose Errors into something more readable with Mongoose Hooks\/Middleware as described <a href=\"https:\/\/mongoosejs.com\/docs\/middleware.html#error-handling-middleware\">here<\/a>. An additional option would be to define custom error objects and use global Express Error Handling Middleware, however, I\u2019ll save that for an upcoming article wherein we discuss better architectural methods.<\/p>\n<p>In the endpoint for <code>PATCH \/books\/:id<\/code>, we\u2019ll expect an update object to be passed up containing updates for the book in question. For this article, we\u2019ll allow all fields to be updated, but in the future, I\u2019ll show how we can disallow updates of particular fields. Additionally, you\u2019ll see that the error handling logic in our PATCH Endpoint will be the same as our GET Endpoint. That\u2019s an indication that we are violating DRY Principles, but again, we\u2019ll touch on that later.<\/p>\n<p>I\u2019m going to expect that all updates are available on the <code>updates<\/code> object of <code>req.body<\/code> (meaning the client will send up JSON containing an <code>updates<\/code> object) and will use the <code>Book.findByAndUpdate<\/code> function with a special flag to perform the update.<\/p>\n<div>\n<pre><code>app.patch('\/books\/:id', async (req, res) => {\n    const { id } = req.params;\n    const { updates } = req.body;\n    \n    try {\n        const updatedBook = await Book.findByIdAndUpdate(id, updates, { runValidators: true, new: true });\n        \n        if (!updatedBook) return res.status(404).send({ error: 'Not Found' });\n        \n        return res.send({ book: updatedBook });\n    } catch (e) {\n        if (e instanceof mongoose.Error.CastError) {\n            return res.status(400).send({ error: 'Not a valid ID' });\n        } else {\n            return res.status(500).send({ error: 'Internal Error' });\n        }\n    }\n});<\/code><\/pre>\n<\/div>\n<p>Notice a few things here. We first destructure <code>id<\/code> from <code>req.params<\/code> and <code>updates<\/code> from <code>req.body<\/code>.<\/p>\n<p>Available on the <code>Book<\/code> model is a function by the name of <code>findByIdAndUpdate<\/code> that takes the ID of the document in question, the updates to perform, and an optional options object. Normally, Mongoose won\u2019t re-perform validation for update operations, so the <code>runValidators: true<\/code> flag we pass in as the <code>options<\/code> object forces it to do so.  Furthermore, as of Mongoose 4, <code>Model.findByIdAndUpdate<\/code> no longer returns the modified document but returns the original document instead. The <code>new: true<\/code> flag (which is false by default) overrides that behavior.<\/p>\n<p>Finally, we can build out our DELETE endpoint, which is quite similar to all of the others:<\/p>\n<div>\n<pre><code>app.delete('\/books\/:id', async (req, res) => {\n    try {\n        const deletedBook = await Book.findByIdAndDelete(req.params.id);\n        \n        if (!deletedBook) return res.status(404).send({ error: 'Not Found' });\n        \n        return res.send({ book: deletedBook });\n    } catch (e) {\n        if (e instanceof mongoose.Error.CastError) {\n            return res.status(400).send({ error: 'Not a valid ID' });\n        } else {\n            return res.status(500).send({ error: 'Internal Error' });\n        }\n    }\n});<\/code><\/pre>\n<\/div>\n<p>With that, our primitive API is complete and you can test it by making HTTP Requests to all endpoints.<\/p>\n<h3>A Short Disclaimer About Architecture And How We\u2019ll Rectify It<\/h3>\n<p>From an architectural standpoint, the code we have here is quite bad, it\u2019s messy, it\u2019s not DRY, it\u2019s not SOLID, in fact, you might even call it abhorrent. These so-called \u201cRoute Handlers\u201d are doing a lot more than just \u201chanding routes\u201d \u2014 they are directly interfacing with our database. That means there is absolutely no abstraction.<\/p>\n<p>Let\u2019s face it, most applications will never be this small or you could probably get away with serverless architectures with the Firebase Database. Maybe, as we\u2019ll see later, users want the ability to upload avatars, quotes, and snippets from their books, etc. Maybe we want to add a live chat feature between users with WebSockets, and let\u2019s even go as far as saying we\u2019ll open up our application to let users borrow books with one another for a small charge \u2014 at which point we need to consider Payment Integration with the Stripe API and shipping logistics with the Shippo API.<\/p>\n<p>Suppose we proceed with our current architecture and add all of this functionality. These route handers, also known as Controller Actions, are going to end up being very, very large with a high <strong>cyclomatic complexity<\/strong>. Such a coding style might suit us fine in the early days, but what if we decide that our data is referential and thus PostgreSQL is a better database choice than MongoDB? We now have to refactor our entire application, stripping out Mongoose, altering our Controllers, etc., all of which could lead to potential bugs in the rest of the business logic. Another such example would be that of deciding that AWS S3 is too expensive and we wish to migrate to GCP. Again, this requires an application-wide refactor.<\/p>\n<p>Although there are many opinions around architecture, from Domain-Driven Design, Command Query Responsibility Segregation, and Event Sourcing, to Test-Driven Development, SOILD, Layered Architecture, Onion Architecture, and more, we\u2019ll focus on implementing simple Layered Architecture in future articles, consisting of Controllers, Services, and Repositories, and employing Design Patterns like Composition, Adapters\/Wrappers, and Inversion of Control via Dependency Injection. While, to an extent, this could be somewhat performed with JavaScript, we\u2019ll look into TypeScript options to achieve this architecture as well, permitting us to employ functional programming paradigms such as Either Monads in addition to OOP concepts like Generics.<\/p>\n<p>For now, there are two small changes we can make. Because our error handling logic is quite similar in the <code>catch<\/code> block of all endpoints, we can extract it to a custom Express Error Handling Middleware function at the very end of the stack.<\/p>\n<h3>Cleaning Up Our Architecture<\/h3>\n<p>At present, we are repeating a very large amount of error handling logic across all our endpoints. Instead, we can build an Express Error Handling Middleware function, which is an Express Middleware Function that gets called with an error, the req and res objects, and the next function.<\/p>\n<p>For now, let\u2019s build that middleware function. All I\u2019m going to do is repeat the same error handling logic we are used to:<\/p>\n<div>\n<pre><code>app.use((err, req, res, next) => {\n    if (err instanceof mongoose.Error.ValidationError) {\n        return res.status(400).send({  error:  'Validation Error' });\n    } else if (err instanceof mongoose.Error.CastError) {\n        return res.status(400).send({  error:  'Not a valid ID' });\n    } else {\n        console.log(err); \/\/ Unexpected, so worth logging.\n        return res.status(500).send({  error:  'Internal error' });\n    }\n});<\/code><\/pre>\n<\/div>\n<p>This doesn\u2019t appear to work with Mongoose Errors, but in general, rather than using <code>if\/else if\/else<\/code> to determine error instances, you can switch over the error\u2019s constructor. I\u2019ll leave what we have, however.<\/p>\n<p>In a <strong>synchronous<\/strong> endpoint\/route handler, if you throw an error, Express will catch it and process it with no extra work required on your part. Unfortunately, that\u2019s not the case for us. We are dealing with <strong>asynchronous<\/strong> code. In order to delegate error handling to Express with async route handlers, we much catch the error ourselves and pass it to <code>next()<\/code>.<\/p>\n<p>So, I\u2019ll just permit <code>next<\/code> to be the third argument into the endpoint, and I\u2019ll remove the error handling logic in the <code>catch<\/code> blocks in favor of just passing the error instance to <code>next<\/code>, as such:<\/p>\n<pre><code>app.post('\/books', async (req, res, next) => {\n    try {\n        const book =  new  Book(req.body.book);\n        await book.save();\n        return res.send({ book });\n    } catch (e) {\n        next(e)\n    }\n});<\/code><\/pre>\n<p>If you do this to all route handlers, you should end up with the following code:<\/p>\n<div>\n<pre><code>const express = require('express'); \nconst mongoose = require('mongoose');\n\n\/\/ Database connection and model.\nrequire('.\/db\/mongoose.js')();\nconst Book = require('.\/models\/book.js');\n\n\/\/ This creates our Express App.\nconst app = express(); \n\n\/\/ Define middleware.\napp.use(express.json());\napp.use(express.urlencoded({ extended: true }));\n\n\/\/ Listening on port 3000 (arbitrary).\n\/\/ Not a TCP or UDP well-known port. \n\/\/ Does not require superuser privileges.\nconst PORT = 3000;\n\n\/\/ We will build our API here.\n\/\/ HTTP POST \/books\napp.post('\/books', async (req, res, next) => {\n    try {\n        const book = new Book(req.body.book);\n        await book.save();    \n        return res.status(201).send({ book });\n    } catch (e) {\n        next(e)\n    }\n});\n\n\/\/ HTTP GET \/books\/:id\napp.get('\/books\/:id', async (req, res) => {\n    try {\n        const book = await Book.findById(req.params.id);\n        \n        if (!book) return res.status(404).send({ error: 'Not Found' });\n        \n        return res.send({ book });\n    } catch (e) {\n           next(e);\n    }\n});\n\n\/\/ HTTP PATCH \/books\/:id\napp.patch('\/books\/:id', async (req, res, next) => {\n    const { id } = req.params;\n    const { updates } = req.body;\n    \n    try {\n        const updatedBook = await Book.findByIdAndUpdate(id, updates, { runValidators: true, new: true });\n        \n        if (!updatedBook) return res.status(404).send({ error: 'Not Found' });\n        \n        return res.send({ book: updatedBook });\n    } catch (e) {\n        next(e);\n    }\n});\n\n\/\/ HTTP DELETE \/books\/:id\napp.delete('\/books\/:id', async (req, res, next) => {\n    try {\n        const deletedBook = await  Book.findByIdAndDelete(req.params.id);\n        \n        if (!deletedBook) return res.status(404).send({  error:  'Not Found' });\n        \n        return res.send({ book: deletedBook });\n    } catch (e) {\n        next(e);\n    }\n});\n\n\/\/ Notice - bottom of stack.\napp.use((err, req, res, next) => {\n    if (err instanceof mongoose.Error.ValidationError) {\n        return res.status(400).send({  error:  'Validation Error' });\n    } else if (err instanceof mongoose.Error.CastError) {\n        return res.status(400).send({  error:  'Not a valid ID' });\n    } else {\n        console.log(err); \/\/ Unexpected, so worth logging.\n        return res.status(500).send({  error:  'Internal error' });\n    }\n});\n\n\/\/ Binding our application to port 3000.\napp.listen(PORT, () => console.log(`Server is up on port ${PORT}.`));<\/code><\/pre>\n<\/div>\n<p>Moving further, it would be worth separating our error handling middleware into another file, but that\u2019s trivial, and we\u2019ll see it in future articles in this series. Additionally, we could use an NPM module named <code>express-async-errors<\/code> as to permit us to not have to call next in the catch block, but again, I\u2019m trying to show you how things are done officially.<\/p>\n<h3>A Word About CORS And The Same Origin Policy<\/h3>\n<p>Suppose your website is served from the domain <code>myWebsite.com<\/code> but your server is at <code>myOtherDomain.com\/api<\/code>. CORS stands for Cross-Origin Resource Sharing and is a mechanism by which cross-domain requests can be performed. In the case above, since the server and front-end JS code are at different domains, you\u2019d be making a request across two different origins, which is commonly restricted by the browser for security reasons, and mitigated by supplying specific HTTP headers.<\/p>\n<p>The Same Origin Policy is what performs those aforementioned restrictions \u2014 a web browser will only permit requires to be made across the same origin.<\/p>\n<p>We\u2019ll touch on CORS and SOP later when we build a Webpack bundled front-end for our Book API with React.<\/p>\n<h3>Conclusion And What\u2019s Next<\/h3>\n<p>We have discussed a lot in this article. Perhaps it wasn\u2019t all fully practical, but it hopefully got you more comfortable working with Express and ES6 JavaScript features. If you are new to programming and Node is the first path down which you are embarking, hopefully the references to statically types languages like Java, C++, and C# helped to highlight some of the differences between JavaScript and its static counterparts.<\/p>\n<p>Next time, we\u2019ll finish building out our Book API by making some fixes to our current setup with regards to the Book Routes, as well as adding in User Authentication so that users can own books. We\u2019ll do all of this with a similar architecture to what I described here and with MongoDB for data persistence. Finally, we\u2019ll permit users to upload avatar images to AWS S3 via Buffers.<\/p>\n<p>In the article thereafter, we\u2019ll be rebuilding our application from the ground up in TypeScript, still with Express. We\u2019ll also move to PostgreSQL with Knex instead of MongoDB with Mongoose as to depict better architectural practices. Finally, we\u2019ll update our avatar image uploading process to use Node Streams (we\u2019ll discuss Writable, Readable, Duplex, and Transform Streams). Along the way, we\u2019ll cover a great amount of design and architectural patterns and functional paradigms, including:<\/p>\n<ul>\n<li>Controllers\/Controller Actions<\/li>\n<li>Services<\/li>\n<li>Repositories<\/li>\n<li>Data Mapping<\/li>\n<li>The Adapter Pattern<\/li>\n<li>The Factory Pattern<\/li>\n<li>The Delegation Pattern<\/li>\n<li>OOP Principles and Composition vs Inheritance<\/li>\n<li>Inversion of Control via Dependency Injection<\/li>\n<li>SOLID Principles<\/li>\n<li>Coding against interfaces<\/li>\n<li>Data Transfer Objects<\/li>\n<li>Domain Models and Domain Entities<\/li>\n<li>Either Monads<\/li>\n<li>Validation<\/li>\n<li>Decorators<\/li>\n<li>Logging and Logging Levels<\/li>\n<li>Unit Tests, Integration Tests (E2E), and Mutation Tests<\/li>\n<li>The Structured Query Language<\/li>\n<li>Relations<\/li>\n<li>HTTP\/Express Security Best Practices<\/li>\n<li>Node Best Practices<\/li>\n<li>OWASP Security Best Practices<\/li>\n<li>And more.<\/li>\n<\/ul>\n<p>Using that new architecture, in the article after that, we\u2019ll write Unit, Integration, and Mutation tests, aiming for close to 100 percent testing coverage, and we\u2019ll finally discuss setting up a remote CI\/CD pipeline with CircleCI, as well as Message Busses, Job\/Task Scheduling, and load balancing\/reverse proxying.<\/p>\n<p>Hopefully, this article has been helpful, and if you have any queries or concerns, let me know in the comments below.<\/p>\n<div>\n  <img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/11\/logo-red-19.png?w=900&#038;ssl=1\" alt=\"Smashing Editorial\"><span>(dm, yk, il)<\/span>\n<\/div>\n<\/article>\n<p class=\"wpematico_credit\"><small>Powered by <a href=\"http:\/\/www.wpematico.com\" target=\"_blank\" rel=\"noopener noreferrer\">WPeMatico<\/a><\/small><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Getting Started With An Express And ES6+ JavaScript Stack Getting Started With An Express And ES6+ JavaScript Stack Jamie Corkhill 2019-11-22T12:00:00+00:002019-11-23T11:08:10+00:00 This article is the second part in a series, with part one located here, which provided basic and (hopefully) intuitive insight into Node.js, ES6+ JavaScript, Callback Functions, Arrow Functions, APIs, the HTTP Protocol, JSON,&#8230;<a class=\"moretag\" href=\"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/\"> Read the full article&#8230;<\/a><\/p>\n","protected":false},"author":4,"featured_media":73166,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[371],"tags":[],"class_list":["post-73165","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-user-experience"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"Getting Started With An Express And ES6+ JavaScript StackGetting Started With An Express And ES6+ JavaScript Stack Jamie Corkhill 2019-11-22T12:00:00+00:002019-11-23T11:08:10+00:00This article is the second part in a series, with part one located here, which provided basic and (hopefully) intuitive insight into Node.js, ES6+ JavaScript, Callback Functions, Arrow Functions, APIs, the HTTP Protocol, JSON, MongoDB, and\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Guest Contribution\"\/>\n\t<meta name=\"keywords\" content=\"user experience\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Design for Immersive Technologies | User Experience for Games, Virtual Reality (VR) and Augmented\/Mixed Reality (AR\/MR)\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Getting Started With An Express And ES6+ JavaScript Stack | Design for Immersive Technologies\" \/>\n\t\t<meta property=\"og:description\" content=\"Getting Started With An Express And ES6+ JavaScript StackGetting Started With An Express And ES6+ JavaScript Stack Jamie Corkhill 2019-11-22T12:00:00+00:002019-11-23T11:08:10+00:00This article is the second part in a series, with part one located here, which provided basic and (hopefully) intuitive insight into Node.js, ES6+ JavaScript, Callback Functions, Arrow Functions, APIs, the HTTP Protocol, JSON, MongoDB, and\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-11-23T11:17:55+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-11-23T11:17:55+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Getting Started With An Express And ES6+ JavaScript Stack | Design for Immersive Technologies\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Getting Started With An Express And ES6+ JavaScript StackGetting Started With An Express And ES6+ JavaScript Stack Jamie Corkhill 2019-11-22T12:00:00+00:002019-11-23T11:08:10+00:00This article is the second part in a series, with part one located here, which provided basic and (hopefully) intuitive insight into Node.js, ES6+ JavaScript, Callback Functions, Arrow Functions, APIs, the HTTP Protocol, JSON, MongoDB, and\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/11\\\/getting-started-with-an-express-and-es6-javascript-stack\\\/#article\",\"name\":\"Getting Started With An Express And ES6+ JavaScript Stack | Design for Immersive Technologies\",\"headline\":\"Getting Started With An Express And ES6+ JavaScript Stack\",\"author\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/author\\\/guestcontribution\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/www.taterboy.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/post-request-with-json-one.png?fit=400%2C215&ssl=1\",\"width\":400,\"height\":215},\"datePublished\":\"2019-11-23T04:17:55-07:00\",\"dateModified\":\"2019-11-23T04:17:55-07:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/11\\\/getting-started-with-an-express-and-es6-javascript-stack\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/11\\\/getting-started-with-an-express-and-es6-javascript-stack\\\/#webpage\"},\"articleSection\":\"User Experience\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/11\\\/getting-started-with-an-express-and-es6-javascript-stack\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.taterboy.com\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/category\\\/user-experience\\\/#listItem\",\"name\":\"User Experience\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/category\\\/user-experience\\\/#listItem\",\"position\":2,\"name\":\"User Experience\",\"item\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/category\\\/user-experience\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/11\\\/getting-started-with-an-express-and-es6-javascript-stack\\\/#listItem\",\"name\":\"Getting Started With An Express And ES6+ JavaScript Stack\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/11\\\/getting-started-with-an-express-and-es6-javascript-stack\\\/#listItem\",\"position\":3,\"name\":\"Getting Started With An Express And ES6+ JavaScript Stack\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/category\\\/user-experience\\\/#listItem\",\"name\":\"User Experience\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/#organization\",\"name\":\"Design for Immersive Technologies\",\"description\":\"User Experience for Games, Virtual Reality (VR) and Augmented\\\/Mixed Reality (AR\\\/MR)\",\"url\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/author\\\/guestcontribution\\\/#author\",\"url\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/author\\\/guestcontribution\\\/\",\"name\":\"Guest Contribution\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/11\\\/getting-started-with-an-express-and-es6-javascript-stack\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d2aad73eb0f48c67b141e9fc978a0e498969791ed623346e361d02d19775b0bb?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Guest Contribution\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/11\\\/getting-started-with-an-express-and-es6-javascript-stack\\\/#webpage\",\"url\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/11\\\/getting-started-with-an-express-and-es6-javascript-stack\\\/\",\"name\":\"Getting Started With An Express And ES6+ JavaScript Stack | Design for Immersive Technologies\",\"description\":\"Getting Started With An Express And ES6+ JavaScript StackGetting Started With An Express And ES6+ JavaScript Stack Jamie Corkhill 2019-11-22T12:00:00+00:002019-11-23T11:08:10+00:00This article is the second part in a series, with part one located here, which provided basic and (hopefully) intuitive insight into Node.js, ES6+ JavaScript, Callback Functions, Arrow Functions, APIs, the HTTP Protocol, JSON, MongoDB, and\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/11\\\/getting-started-with-an-express-and-es6-javascript-stack\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/author\\\/guestcontribution\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/author\\\/guestcontribution\\\/#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/www.taterboy.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/post-request-with-json-one.png?fit=400%2C215&ssl=1\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/11\\\/getting-started-with-an-express-and-es6-javascript-stack\\\/#mainImage\",\"width\":400,\"height\":215},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/2019\\\/11\\\/getting-started-with-an-express-and-es6-javascript-stack\\\/#mainImage\"},\"datePublished\":\"2019-11-23T04:17:55-07:00\",\"dateModified\":\"2019-11-23T04:17:55-07:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/\",\"name\":\"Design for Immersive Technologies\",\"description\":\"User Experience for Games, Virtual Reality (VR) and Augmented\\\/Mixed Reality (AR\\\/MR)\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.taterboy.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Getting Started With An Express And ES6+ JavaScript Stack | Design for Immersive Technologies","description":"Getting Started With An Express And ES6+ JavaScript StackGetting Started With An Express And ES6+ JavaScript Stack Jamie Corkhill 2019-11-22T12:00:00+00:002019-11-23T11:08:10+00:00This article is the second part in a series, with part one located here, which provided basic and (hopefully) intuitive insight into Node.js, ES6+ JavaScript, Callback Functions, Arrow Functions, APIs, the HTTP Protocol, JSON, MongoDB, and","canonical_url":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/","robots":"max-image-preview:large","keywords":"user experience","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/#article","name":"Getting Started With An Express And ES6+ JavaScript Stack | Design for Immersive Technologies","headline":"Getting Started With An Express And ES6+ JavaScript Stack","author":{"@id":"https:\/\/www.taterboy.com\/blog\/author\/guestcontribution\/#author"},"publisher":{"@id":"https:\/\/www.taterboy.com\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/11\/post-request-with-json-one.png?fit=400%2C215&ssl=1","width":400,"height":215},"datePublished":"2019-11-23T04:17:55-07:00","dateModified":"2019-11-23T04:17:55-07:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/#webpage"},"isPartOf":{"@id":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/#webpage"},"articleSection":"User Experience"},{"@type":"BreadcrumbList","@id":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog#listItem","position":1,"name":"Home","item":"https:\/\/www.taterboy.com\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog\/category\/user-experience\/#listItem","name":"User Experience"}},{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog\/category\/user-experience\/#listItem","position":2,"name":"User Experience","item":"https:\/\/www.taterboy.com\/blog\/category\/user-experience\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/#listItem","name":"Getting Started With An Express And ES6+ JavaScript Stack"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/#listItem","position":3,"name":"Getting Started With An Express And ES6+ JavaScript Stack","previousItem":{"@type":"ListItem","@id":"https:\/\/www.taterboy.com\/blog\/category\/user-experience\/#listItem","name":"User Experience"}}]},{"@type":"Organization","@id":"https:\/\/www.taterboy.com\/blog\/#organization","name":"Design for Immersive Technologies","description":"User Experience for Games, Virtual Reality (VR) and Augmented\/Mixed Reality (AR\/MR)","url":"https:\/\/www.taterboy.com\/blog\/"},{"@type":"Person","@id":"https:\/\/www.taterboy.com\/blog\/author\/guestcontribution\/#author","url":"https:\/\/www.taterboy.com\/blog\/author\/guestcontribution\/","name":"Guest Contribution","image":{"@type":"ImageObject","@id":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/d2aad73eb0f48c67b141e9fc978a0e498969791ed623346e361d02d19775b0bb?s=96&d=mm&r=g","width":96,"height":96,"caption":"Guest Contribution"}},{"@type":"WebPage","@id":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/#webpage","url":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/","name":"Getting Started With An Express And ES6+ JavaScript Stack | Design for Immersive Technologies","description":"Getting Started With An Express And ES6+ JavaScript StackGetting Started With An Express And ES6+ JavaScript Stack Jamie Corkhill 2019-11-22T12:00:00+00:002019-11-23T11:08:10+00:00This article is the second part in a series, with part one located here, which provided basic and (hopefully) intuitive insight into Node.js, ES6+ JavaScript, Callback Functions, Arrow Functions, APIs, the HTTP Protocol, JSON, MongoDB, and","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.taterboy.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/#breadcrumblist"},"author":{"@id":"https:\/\/www.taterboy.com\/blog\/author\/guestcontribution\/#author"},"creator":{"@id":"https:\/\/www.taterboy.com\/blog\/author\/guestcontribution\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/11\/post-request-with-json-one.png?fit=400%2C215&ssl=1","@id":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/#mainImage","width":400,"height":215},"primaryImageOfPage":{"@id":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/#mainImage"},"datePublished":"2019-11-23T04:17:55-07:00","dateModified":"2019-11-23T04:17:55-07:00"},{"@type":"WebSite","@id":"https:\/\/www.taterboy.com\/blog\/#website","url":"https:\/\/www.taterboy.com\/blog\/","name":"Design for Immersive Technologies","description":"User Experience for Games, Virtual Reality (VR) and Augmented\/Mixed Reality (AR\/MR)","inLanguage":"en-US","publisher":{"@id":"https:\/\/www.taterboy.com\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Design for Immersive Technologies | User Experience for Games, Virtual Reality (VR) and Augmented\/Mixed Reality (AR\/MR)","og:type":"article","og:title":"Getting Started With An Express And ES6+ JavaScript Stack | Design for Immersive Technologies","og:description":"Getting Started With An Express And ES6+ JavaScript StackGetting Started With An Express And ES6+ JavaScript Stack Jamie Corkhill 2019-11-22T12:00:00+00:002019-11-23T11:08:10+00:00This article is the second part in a series, with part one located here, which provided basic and (hopefully) intuitive insight into Node.js, ES6+ JavaScript, Callback Functions, Arrow Functions, APIs, the HTTP Protocol, JSON, MongoDB, and","og:url":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/","article:published_time":"2019-11-23T11:17:55+00:00","article:modified_time":"2019-11-23T11:17:55+00:00","twitter:card":"summary","twitter:title":"Getting Started With An Express And ES6+ JavaScript Stack | Design for Immersive Technologies","twitter:description":"Getting Started With An Express And ES6+ JavaScript StackGetting Started With An Express And ES6+ JavaScript Stack Jamie Corkhill 2019-11-22T12:00:00+00:002019-11-23T11:08:10+00:00This article is the second part in a series, with part one located here, which provided basic and (hopefully) intuitive insight into Node.js, ES6+ JavaScript, Callback Functions, Arrow Functions, APIs, the HTTP Protocol, JSON, MongoDB, and"},"aioseo_meta_data":{"post_id":"73165","title":null,"description":null,"keywords":null,"keyphrases":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_custom_url":null,"og_image_custom_fields":null,"og_custom_image_width":null,"og_custom_image_height":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"location":null,"local_seo":null,"created":"2021-02-07 16:41:18","updated":"2026-09-02 13:09:05","focus_keyword":null,"additional_keywords":null,"truseo_locale":null,"primary_term":null,"og_image_url":null,"og_image_width":null,"og_image_height":null,"twitter_image_url":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"limit_modified_date":false,"ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.taterboy.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.taterboy.com\/blog\/category\/user-experience\/\" title=\"User Experience\">User Experience<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tGetting Started With An Express And ES6+ JavaScript Stack\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.taterboy.com\/blog"},{"label":"User Experience","link":"https:\/\/www.taterboy.com\/blog\/category\/user-experience\/"},{"label":"Getting Started With An Express And ES6+ JavaScript Stack","link":"https:\/\/www.taterboy.com\/blog\/2019\/11\/getting-started-with-an-express-and-es6-javascript-stack\/"}],"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8wzr5-j25","jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.taterboy.com\/blog\/wp-content\/uploads\/2019\/11\/post-request-with-json-one.png?fit=400%2C215&ssl=1","_links":{"self":[{"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/posts\/73165","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/comments?post=73165"}],"version-history":[{"count":0,"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/posts\/73165\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/media\/73166"}],"wp:attachment":[{"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/media?parent=73165"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/categories?post=73165"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.taterboy.com\/blog\/wp-json\/wp\/v2\/tags?post=73165"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}