Upcoming Course: Code Your Own Business w/ React + GraphQL!
We're live-coding on Twitch! Join us!
Easily Deploy a Serverless Node App with ZEIT Now

Easily Deploy a Serverless Node App with ZEIT Now

Demo Project

I wanted to deploy a simple demo node app the other day using Now, and I got into a lot of difficulties and gotchas, with little help from the official docs. If you are in my shoes, this is for you, otherwise, read on to find out how to deploy a node app easily using the Now CLI tool.

NodeJS is a JavaScript runtime environment that runs outside a browser. Applications and APIs can be built using NodeJS. APIs are ways by which applications share data. These apps or APIs, however, need to be hosted on the internet to be accessible by other applications on the internet.

In this post, we shall deploy a simple Node app using the Now CLI service.

TL:DR

Deploy a Node app in the following steps:

  • Create a now.json file in your node project.
  • Specify the build file and the required builder ( @now/node-server for node apps).
  • Create the route for each API endpoint, in now.json.
  • Ensure the entry filename of your server is index.js else specify home route in now.json.
  • Use the now command to publish.

ZEIT Now is a cloud deployment and severless solution offering a seamless way to deploy both static and dynamic applications.

Installation

As this is a Nodejs project, check that you have node and its accompanying package manager, npm, installed with:

node -v && npm -v

This would print the current version numbers if installed. If you don't have it installed, go on the nodejs page to download and install it.

Next, install the Now CLI tool globally from npm with:

Essential Reading: Learn React from Scratch! (2019 Edition)
npm install -g now

Create a new now-express project directory using:

mkdir now-express

In the project directory, create a bare node project with this command:

npm init -y

This creates a node project having a default configuration with an accompanying package.json file.

Install express in the project using:

npm install --save express

Express is a Node.js framework for building web servers efficiently.

Create a Web Server

Create a new folder in the root directory called index.js, this can have any title, and it serves as the entry point of the application. In index.js import express, use the built-in body parser in express and create a listener on port 5000. Do this with:

const express = require("express");
const app = express();

const port = 5000;

// Body parser
app.use(express.urlencoded({ extended: false }));

// Listen on port 5000
app.listen(port, () => {
  console.log(`Server is booming on port 5000
Visit http://localhost:5000`);
});

In index.js Create the home route and two simple mock API endpoints with:

// Import Dependencies

//Specify port

// Body parser

// Home route
app.get("/", (req, res) => {
  res.send("Welcome to a basic express App");
});

// Mock APIs
app.get("/users", (req, res) => {
  res.json([
    { name: "William", location: "Abu Dhabi" },
    { name: "Chris", location: "Vegas" }
  ]);
});

app.post("/user", (req, res) => {
  const { name, location } = req.body;

  res.send({ status: "User created", name, location });
});

Here, we created two API endpoints to get user and to send a user through. The endpoint which posts a user to the server returns this user in its response.

In the package.json file include a script to start the server. Update package.json to:

{
  "name": "now-express",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
  },
  "keywords": [],
  "author": "William Imoh",
  "license": "MIT",
  "dependencies": {
    "express": "^4.17.1",
    "nodemon": "^1.19.1"
  }
}

To launch the server, run the command:

npm run start

Navigate to http://localhost:5000 on the browser to see the simple page.

You can check out the /users route in the browser and make an API call to /user with data using Postman.

Deploy Application using Now

Now requires a configuration file now.json with which it builds a node application and creates a lambda. In the absence of the configuration file, the files are served statically. Create a file named now.json in the root folder of the application.

In the configuration file, key parameters required to build the app are specified with the more important ones being the build and the builders. Create a build for the index.js file in now.json with:

{
  "version": 2,
  "builds": [{ "src": "index.js", "use": "@now/node-server" }],
}

Here, we first specified the version of the Now platform (version 2), then we specified the source file for the node app. The @now/node-server builder is used and recommended for node apps.

Using the @now/node builder throws an error when you access the application after deployment. @now/node is recommended for single node serverless functions.

You can read more about builds and builders.

While this setup will ship our application and provide a valid URL, we must specify the API routes else they will not be available when the app is deployed. Here's a sample error page from navigating to any route or route group when it's not specified in now.json.

In now.json create a key for routes, edit now.json to:

{
  "version": 2,
  "builds": [{ "src": "index.js", "use": "@now/node-server" }],
  "routes": [
    {
      "src": "/users",
      "dest": "/index.js",
      "methods": ["GET"]
    },
    {
      "src": "/user",
      "dest": "/index.js",
      "methods": ["POST"]
    }
  ]
}

This points the two available endpoints to destination pathnames as well as specifying the HTTP verbs available on each endpoint. Failure to state the applicable methods leaves the endpoint open to any kind of HTTP request.

The routes also take keys specifying applicable headers and status codes for each route. You can find more about handling routes in deployment here.

In the command line, deploy your application using:

now

This deploys your application and provides a valid URL, in my case, I have:

You can find the app on https://now-express.williamimoh.now.sh Navigate to /users to see an object with data from the server.

Gotcha

One key thing to note, while you may have a different name for your server file other than index.js, Now requires that the entry file name is index to be recognised, as well as the correct file extension. Failure to adhere to this naming convention will have your app being rendered using Now's directory listing.

Now requires the entry node file to be named index.js.

A workaround to this is to specify the home route in the now.json and point the destination to the server file. Even at this, the build source file specified in now.json will direct to the server file.

Assuming we rename the entry file of this project from index.js to server.js, now.json becomes:

{
  "version": 2,
  "builds": [{ "src": "server.js", "use": "@now/node-server" }],
  "routes": [
    {
      "src": "/",
      "dest": "/server.js",
      "methods": ["GET"]
    },
    {
      "src": "/users",
      "dest": "/server.js",
      "methods": ["GET"]
    },
    {
      "src": "/user",
      "dest": "/server.js",
      "methods": ["POST"]
    }
  ]
}

You can find the completed project on Github: https://github.com/Chuloo/now-express

Conclusion

In this post, we deployed a simple node app using Now and obtained a live URL. We also saw some gotchas with deploying an app using Now.

Feel free to comment on this post if you have any questions or suggestions. Happy keyboard slapping.

Like this article? Follow @iChuloo on Twitter