Node.js, ZEIT Now, and Deploying
Tags: node, react, serverless, fullstack
Published: 2019-09-11 21:56:03

Have a cool app idea, but have no idea where to start in learning all the things one needs to know to create a modern, connected app for the web or smartphone?

I was in the same place two years ago, attending Computer Science classes for the first time at university. I felt lost as my friends and classmates seemed to be making all sorts of cool, game-changing apps while I was stuck in class turning in fancy for loops that I spent all night on. 

This tutorial is intended for everyone wanting to get an introduction to all the moving pieces of what makes up a modern app. We will walk through designing the architecture of the application, what exactly the back- and the front-ends are, how to write them, and how to deploy them. 

## Prerequisites

You should have a working understanding of Javascript or a similar-looking language like Java or C++. I won't explain syntax and everything, but will try to provide useful links and some explanation where I think it's important. 

Other than that, there isn't much else you need to know beforehand. If you don't know something mentioned here, Google is your friend. 

> Aside: I think being able to Google efficiently is one of the most important skills a software engineer can have. Every time something goes wrong while you're working through this tutorial, copy the error message and google it! No error message? Google what is going wrong in plain english! More often than not, typing out what's going wrong will let you distill the problem in your head and arrive at the solution. (If this happens a lot, it's time to invest in a rubber duck). 

# The tech you'll learn

In this series, we are going to learn how to write a front-end using [React](https://reactjs.org), a front-end javascript framework, how to write a back-end service with [Node.js](https://nodejs.org/en/) using a framework called [Express](http://expressjs.com/), and how to deploy it to [ZEIT Now](https://zeit.co/), a serverless deployment platform. To finish, we will explore how writing this project can be used to pick up new languages for the backend easily. We'll walk through a re-write of the backend using [Go](https://golang.org/) to demonstrate. By the end, you'll have the basic knowledge and skills to architect and write a web service to support your app or website. Along the way, we will pick up some useful bash skills as well. 


# Enough talk, let's go!

To start, let's install Node and the Zeit CLI, and deploy a small hello world! 

### Installing Node

If you have a preferred version of Node already installed, you can skip this section.

Head over to the [node.js website](https://nodejs.org/en/) and download the LTS version, which at the time of this writing is 10.16.3. Once downloaded and installed, run the following command in the Terminal (or the command line on windows: 

```bash
$ node -v
```

> Note: Throughout this tutorial, `$` is used to identify the Terminal prompt, and not a part of the command. 

You should see your version number printed to the screen, confirming a successful install. If it fails, google the error, debug, and fix the installation. 

After that works, run ```bash 
$ npm -v 
``` 

to confirm the version of npm. If it prompts you to update, do what it says and run 

```bash
$ npm install -g npm
``` 

to update to the latest version. 

#### Node? Who dis?

Node.js is a "javascript runtime environment" for the desktop. Let's break that down. 

Javascript is a language created mainly for the browser, and runs entirely in the browser. It's used to add interactivity and usefulness to HTML sites, and can do a lot of cool things. 

Go ahead and hit the F12 key to open up the browser's console. This is a useful debug tool that allows developers to run javascript commands in the browser. Try typing in any Javascript you know, or just some math like `1 + 2` and you should see it tell you the answer.

To make this happen, Google wrote a Javascript engine that is built into Chrome called "V8." This engine is responsible for taking Javascript input, parsing it, and running it. (This is all very high level so I'd recommend reading better articles about it if you are interested.)

This engine is open-source, and is available to read about at [v8.dev](https://v8.dev/). In 2009, a guy named Ryan Dahl took this open source Javascript engine, and built it into an application called Node.js, which is able to take in Javascript files and run it on computers outside the browser. If you've used python, this isn't too different from how python run files with something like `$ python file.py`. The only difference is that you're using the Javascript language instead of python. 

#### npm

npm is a package manager for node. It doesn't stand for "Node Package Manager," apparently, and doesn't have a meaning, but you can go to [the npm website](https://www.npmjs.com) to see all the things "npm" could stand for. 

Anyway, npm allows us to install "packages" which can contain libraries, utilities, and apps that we can take advantage of to extend the functionality of our application. A lot of packages are more or less industry standards, and we can use those to avoid wasting time reinventing the wheel.


### Installing the ZEIT CLI

One of the applications we will install through npm is the ZEIT Now CLI. 

> Aside: A CLI is a "Command Line Interface" which, as you can probably guess, is a way to use an application or service through the command line. This is kind of like how a GUI (Graphical User Interface) is a way to use an application through "Graphics" i.e. your screen. 

This is an open source application, so you can look at its code and usage details on its [Github repo](https://github.com/zeit/now). This application allows us to login to and deploy to the ZEIT serverless service through the command line. This is a common thing for many utilities and apps that are used in the industry, so it's good to get used to it now. Plus, using the terminal will make you look cool and you will become the pride of your family. (Not really, but maybe)

We will install Now from npm, by running the `npm install` command. You can look in the Now README on Github to see what the package is called in the npm registry, which surprisingly is just "now." Use 

```bash
$ npm install -g now
```

to install it. Before we use it, let's head over to [zeit.co](https://zeit.co) and create an account. In my opinion, their free tier is amazingly useful, so you'll be able to keep using this account after this tutorial. 

Once the account setup is finished, head back to the terminal and run 
```bash
$ now login
```
which will let you login to the CLI and use your account to do things. 

### No magic: breaking down the npm install command

Before we continue, let's take a minute to look at the `npm install` command we just ran. Right now, it seems a bit magical that the command was typed in and then stuff happened and now there's a new app on your computer. Generally speaking, whenever we come across things with a bit of "magic" about them, we should look into exactly what's going on so that we have an understanding of the internals. When something breaks, this knowledge is really helpful in fixing problems quickly. Then, we can go back to the magic. 

To take out the magic from all these command we ran and will run in the future, let's break down what that command is doing to learn the basics of using the terminal. If you're good with the terminal and how it works, skip this section. 

The `npm` is the name of the program you want to run, and runs the npm executable that came with the node.js install. 

The second thing we type in is `install`, a command that is available in the program. In this case, `install` tells npm that we want to install something and that we are going to pass in the name of the package we want to install. 

The next thing we pass in isn't the name though, it's `-g`. This is called a "switch" - it is something that either exists or doesn't in the command, and are usually optional. This one stands for "global" and you can use the corresponding long-form version of the switch by replacing it with `--global`. 

> Aside: Notice that long-form starts with two dashes instead of one and starts with the same letter as the short-form. This is a common practice across 99% of all unix/linux command line applications. It's easier to type `-g` in the terminal, and you definitely should, but in scripts and other situations where you only write the command once, you use the long-form `--global` to increase readability. 

> Switches in the commands allow users to specify options and turn on/off features in programs, and are what allow the command line to be an "interface" 

The `-g` switch tells npm to install the package globally on your computer. This allows you to use the installed package from anywhere in your file system, which makes sense for this situation, since you might want to use Now to deploy applications that are stored in various places on your computer. 

The last part of the command is `now` which is the name of the ZEIT Now package on the npm registry. Sometimes these are not so obvious and you should look at the docs or npm page of whichever package you want to install to get the right command. (Look on the top right part of the npm page for a copy-paste-able command.) 


## Deploy a thing!

Now, you should have the basic necessities installed in order to write and deploy a node.js service to Now. So to close out this section, let's do just that. 

Open up your favorite code editor (if it isn't [VS Code](https://code.visualstudio.com/) you're wrong). 

Using the file explorer (if you have time, look into doing it with the command line to be cool and learn to do things quicker), create a folder to hold your files for this tutorial somewhere on your computer. For example, mine is in `Documents/GreatestTutorial`. Create another folder inside that called `hello-world`. 

> Make sure your folder names do not contain any spaces, all the way through the path. This makes it easier to work with the command line.

> Organizing your code into folders is important, since that separates apps' configurations, libraries, and code and prevents overlap. It's possible to write three different python apps, a Go utility, and a Node.js web-app all in the same folder, but that sounds like a nightmare to work with. 

Now, open that folder in VS Code (or your lesser editor of choice) so that we can get started writing files. 

Create a file called `now.json`. Then, create another folder beside that called `api/` and create a new file inside the `api/` folder called `index.js`.

Your folder structure should look like this 
```
tutorial/
  |- hello-world/
     |- now.json
     |- api/
        |- index.js
```

In the `index.js`, type in the following code: (Type, don't copy/paste)

```js
module.exports = (req, res) => {
  res.status(200).send("hello there!");
}
```

We will go over what this code is doing below in the next section, but for now, let's continue. 

Open up `now.json` and type in the following: 

```json
{
  "version": 2
}
```

This simply defines a version number, which ZEIT uses to know which version of its platform we want to use. (We will always use v2, the latest and greatest from ZEIT). 

Now, go back to the terminal, change the working directory to be in the `hello-world` folder, and run

```bash
$ now
```

You should see it run and output something similar to this:

```
> Deploying ~/Documents/tutorial/hello-world under almadireddy
> Using project hello-world
> https://hello-world-3bonj1wv9.now.sh [v2] [951ms]
> Ready! Deployed to https://hello-world.almadireddy.now.sh [in clipboard] [3s]
```

The last line which says `Ready!` is important. Copy that URL (mine is live, go ahead and try if you aren't running this on your computer), and open it in your favorite browser with `/api` appended. So for example, I would open [https://hello-world.almadireddy.now.sh/api](https://hello-world.almadireddy.now.sh/api). You should see something like this:

![Screenshot of hello world app](https://i.imgur.com/4P7uJoz.png)

Congrats! You've just written and deployed a service using Node.js! 


### Breaking down the code

Let's break down what our code is actually doing. The first line begins with `module.exports =`. This is a node.js feature that allows programmers to define the parts of your code to "export." Exported objects, functions, and variables can be used in other files by importing the file that has the `module.exports` defined. We set our module.exports to be equal to the next part:


```js 
(req, res) => {
  res.status(200).send("hello there!");
}
``` 

This is a Javascript function definition with the arrow syntax. To explain, the following two function definitions are equivalent: 

```js
function add(x, y) {
  return x+y;
}

add(1, 3); // returns 4
```

and 

```js
let add = (x, y) => {
  return x+y;
}

add(1, 3); // returns 4
```

In the first example, the function definition names the function `add`, in the second, we give the function a name by assigning it to a variable. In our app, we have no explicit name, we just set it to the module.exports variable. This way, the function is exported so ZEIT's system can import and run it for us. 

Here is a great read on the differences, cosmetic and otherwise (and there are significant differences that go beyond cosmetics). [ES5 functions vs. ES6 ‘fat arrow’ functions](https://medium.com/@thejasonfile/es5-functions-vs-es6-fat-arrow-functions-864033baa1a) 

Our function takes in two parameters, `req` and `res`. When we call `now` and deploy it, ZEIT will listen for requests at the auto-generated URL, and call our function and pass in the two parameters whenever there is a request to that url. We made this request by going to the url in the browser, causing ZEIT to fill in the params, and run the code. Because you are defining the function, you can call `req` and `res` whatever you want. I sometimes use `request` and `response` since I have auto complete in VS Code, and that makes the code more readable. It also follows with the information we get access to in those parameters. 

Zeit will pass in information about the request - such as the parameters in the URL that were specified - to the first parameter of the function. This is why we name it `req` or `request`. We can add information about the response to the second parameter by calling functions such as `send` or `status` functions on that parameter, which is why we name it `res` or `response`. 

In our function, we are calling the `status()` function, and passing in `200`, which signifies a success. This is a HTTP Response Code, and we will go over those briefly in one of the next sections. This functionality is useful since if something goes wrong in our function, we can let the caller know with a status code that something went wrong. As the server, we control what response is sent, so it's our responsibility to send useful information. Sending a 200 allows our browser to treat it as a successful response. 

An example of a different status code is 401 which is "Unauthorized." This can be used in situations where the user is trying to access something but they aren't signed in. It's up to the developer to choose the proper codes and there are conventions you can look up to find out about them. 

Then, we chain a call to `send()` which is a function that sends whatever you pass into the function back to the requestor (our browser in this example). In our case, we are passing in the string `"hello there!"`. Our response could be anything: an HTML file, an image, a JSON file, or just a string. Using these conventions, we are mapping a request to a response, and that's the basis of all web servers. 


## Coming up

In the next part of this tutorial, we will go over designing and architecting our project. This is an important step in making modern software, and can inform a lot of programming down the line. We will get a high level view of all the moving pieces and the considerations we need to make. We will go over what it means to be "serverless," as I've used that term many times to describe ZEIT already without explaining it, and also download and install [Postman](https://www.getpostman.com) which you can get a head start on right now.