Introduction
There are numerous free hosting services available for getting your Node.js applications up and running publicly. One of these services is Heroku, that allows you to deploy, manage and scale your applications on the web.
In this article we'll be building a simple Node and Express.js application that shortens given links, and deploy it to Heroku.
Creating a Node.js URL Shortener
To make the development process easier we'll be using Express, which is a lightweight web framework that is flexible and easily customizable. Express comes with an application generator, but we'll start from scratch.
Creating the Project Directory
Let's cd
into the workspace and create a new directory for the project:
$ mkdir url-shortener
Initializing npm
Next let's initialize npm, and with it, start our project:
$ npm init
npm init
will ask a series of questions (package name, version, description, etc). For simplicity's sake, let's skip all of these by hitting RETURN for each prompt. Node will then generate a package.json
file and print it to the terminal:
{
"name": "url-shortener",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
}
The fields in package.json
(package name, description, author, etc) can be updated at any time so you don't need to worry about it too much.
What we've added here manually is the "start": "node app.js"
. This will be extremely important later, when we deploy the app to Heroku.
Heroku needs to know how to run our application, and this is typically done via a Procfile. Since our application is so simple, a Procfile would be overkill, and it's enough to simply define that our app should be run by simply executing the node app.js
command.
Installing Express
With that out of the way, we're ready to install Express:
$ npm install express --save
Building a Node Server
With Express installed I'll create a very simple application in a file called app.js
:
const express = require('express');
const app = express();
const path = require('path');
const port = 3000;
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.listen(port, () => console.log(`url-shortener listening on port ${port}!`));
The application at this point is really only the Express boilerplate required to set it up, with a single route handler that returns an HTML page on port 3000
.
Let's go ahead and define the page, which will accept a URL we want to shorten. It'll only consist of a header and a simple form that accepts the URL:
<h1>URL Shortener</h1>
<form method="POST" action="/url">
<input type="text" name="url" />
<input type="submit" />
</form>
We can test if the application is running fine by executing:
$ node app.js
Since we've added the "start" : "node app.js"
command to our package.json
file, we can also run it using an NPM command:
$ npm start
And navigating to http://localhost:3000
:
Handling Form Submission
While the page is rendering correctly, there's no logic to actually handle the POST request sent via the form at the /url
endpoint.
To snatch the URL from the request sent via the form, we'll be using the body-parser module and extract it from the request body, so let's go ahead and require
it as well and set it up for use:
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.urlencoded());
With that done, we can extract the body of the request via req.body
so let's go ahead and make another request handler that packs the URL from the body and sends it back via the response:
app.post('/url', function(req, res) {
const url = req.body.url;
res.send(url);
});
This still isn't what we want as we're getting the entire URL back and not the shortened version.
Shortening the URL
The only thing left to do for our Node app to be complete is to actually shorten the URL before sending it back. For this, we can use the node-url-shortener module. Let's install it via npm:
$ npm install node-url-shortener --save
Then require the package in the application:
const urlShortener = require('node-url-shortener');
And lastly, let's add another block of code that shortens the URL before sending it back:
app.post('/url', function(req, res) {
const url = req.body.url;
urlShortener.short(url, function(err, shortUrl){
res.send(shortUrl);
});
});
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
The urlShortner
has a short()
method that accepts two parameters: the original URL and a callback function. The shortened URL gets passed into the callback function and then into res.send()
.
Let's start up the application and test it out:
After inputting a URL, we're greeted with:
Deploying to Heroku
Signing up for Heroku and Installing the CLI
Now that the application has been built, it's time to think about Heroku. If you don't have an account, head over to signup.heroku.com and create one.
Once you have an account, the next thing to do is install Heroku's CLI tools, which are used for deployment. Heroku provides installation instructions at The Dev Center.
Pushing to Heroku
Deploying to Heroku works via Git. It's very simple once you understand how it works. In essence you can deploy to Heroku by pushing to a remote repo, just like pushing to GitHub.
Because this is a new project, Git needs to be initialized:
$ git init
Now, we're ready to add and commit all the project files. Though, before doing that, we'll add a .gitignore
file because we don't want the node_modules
directory to be committed. It should be generated by npm upon deployment rather than committed to source control.
In your .gitignore
file, simply add:
node_modules
With that out of the way, we can add and commit:
$ git add .
$ git commit -m 'initial commit'
Once the project is committed, we need to create a Heroku app that'll correspond to our Node app:
$ heroku create
Creating app... !
▸ Invalid credentials provided.
heroku: Press any key to open up the browser to login or q to exit:
Opening browser to https://cli-auth.heroku.com/auth/browser/abcd1234-b6a7-4df4-bb42-0eaf987d0637
Logging in... done
Logged in as [email protected]
Creating app... done, ⬢ nameful-wolf-12818
https://nameful-wolf-12818.herokuapp.com/ | https://git.heroku.com/nameful-wolf-12818.git
If this is your first time using the CLI, Heroku will ask you to login via the browser. The process is very simple, just follow the instructions.
Once complete, Heroku returns the newly created app name and URL (your app name will be different to mine). If you browse to the URL you'll see a Heroku welcome page.
This still isn't our URL shortener app, simply a public Heroku app to which we'll deploy our own.
Deploying the App
In the previous heroku create
command, a new remote will have been added to your Git repository, allowing you to deploy to Heroku with a simple command like this:
$ git push heroku master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 326 bytes | 326.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
...
...
...
remote: Verifying deploy... done.
To https://git.heroku.com/nameful-wolf-12818.git
5cb9118..dd0bacd master -> master
Since the application is successfully deployed, we can go ahead and start it up:
Though, we'll encounter an issue due to the mismatch in ports. In our app, we've hardcoded that it uses port 3000
, but Heroku works on a different port and this clash crashes our application.
In order to make the application work both locally and on Heroku, we'll change the port to be either 3000
or the process.env.PORT
, which is set by Heroku:
const port = process.env.PORT || 3000;
Deploying the application again and refreshing the page, everything works just fine!
Conclusion
There are numerous free hosting services available for getting your applications up and running publicly. One of these services is Heroku, that allows you to deploy, manage and scale your applications on the web.
We've built a simple Node and Express application that shortens provided URLs via the node-url-shortener
module. We've then prepared that app for deployment and finally got it up and running on Heroku.