How To Build A URL Shortener With Node.js, Express, and MongoDB

How To Build A URL Shortener With Node.js, Express, and MongoDB

22.Jun.2021

that's right after a long long wait
we're finally gonna be building another
back-end project and this one is a ton
of fun we're gonna build a URL shortener
which is going to have all the works
we're gonna have a UI a back-end a
database absolutely everything you need
to get this project 100% done so let's
get started now after you're done
building this project you're gonna need
some place to host it and atlanticnet
today's video sponsor is giving you an
entire free year of hosting on their
servers and these are some powerful
servers that can definitely handle this
application and even much more complex
applications all you need to do is use
the link in the description below and
use the code Kyle when you sign up and
you're getting an additional $50 on top
of the year of free server usage so make
sure you check out that link down in the
description below to not miss out on
this entire year of free hosting welcome
back to web dev simplified my name is
Kyle and my job is to simplify the web
for you so you can start building your
dream project sooner so if that sounds
interesting make sure you subscribe to
the channel for more videos just like
this one and now to get started I'm in a
completely blank project so I can show
you exactly what you need to do step by
step and the first thing we need to do
to get started is open up the terminal
and actually initialize this folder as
an NPM project so let's just drag this
up so it's easy to see and we'll type
NPM an it and this is going to
initialize the folder for us we're just
going to do all the default values hit
enter a bunch of times and if this
throws you an error
make sure you have node installed I have
a video on that I'll link in the cards
and description down below and now our
next step is to install all the packages
we're going to need for this project I'm
just gonna get started with the very
basic packages and as we run into needs
for other packages I'll introduce them
then so since we're gonna be running an
Express server which is going to have a
MongoDB database we're gonna need to
install packages related to express and
MongoDB so if we use type in NPM I this
will allow us to install any packages we
list afterwards and we're gonna need
Express we're also gonna need Mongoose
which is for our database
mongodb and then we're gonna need ejs
this essentially allows us to create our
views our templating language so we can
make our HTML and our back-end
work together to send useful data down
to the browser and there we go all of
those were installed and the last thing
we need is our dev dependencies so we
should type in NPM hi - - save - dev and
we want to install node Mon and what
node Mon is going to allow us to do is
to make our server automatically refresh
every single time we make changes
because otherwise you have to manually
shut the server down and restart it
yourself so with all that done we can
open up our package JSON you can see all
of our dependencies here and let's just
create a simple start script so we're
just gonna call this dev start and this
is going to run node Mon server dot J
yes and this is going to start up a file
called server J s using node montt which
means it will Auto refresh for us so
let's save that and create our server
dot J s file and in here we can actually
put all of the code for our application
so to get our server setup let's just
make the most basic server possible the
first thing we're gonna need is that
Express library which we installed just
a little bit ago so let's make sure that
we've required that library and if we
run the Express function we're gonna get
out a variable which we can use to set
up our entire application so we're just
gonna put that inside of app then with
that variable we can call app dot listen
and we just need to pass in the port
number we want to listen to so we're
gonna use process D and V dot port this
way when you deploy your site you can
set the port environment variable and
use that but in development we're not
gonna have that variable set so it's
just default it to port 5,000 instead
and now we can save that and if we run
NPM
run dead start you can see that our
server is going to start up and it's
gonna open up on port 5,000 let me just
drag in a browser that has port 5,000
open and as you can see we have our
application open and it's saying it
cannot get / essentially we have no
route defined for our index so let's
just define a simple route and call it
apt-get and this is going to be for our
index this is going to take a function
here with requests and response
variables that are being passed into it
and in here we want to actually return
some
index file that we're going to create
inside of a folder called views now in
that folder we'll just create index
EGS and the reason we're using ejs is
because that's the templating language
we're going to use and we downloaded
that package for handling ejs so once we
have that created let's just put some
placeholder text in here that says hello
world so we can see if this works and in
our server we actually need to set up
our views to use the ejs view engine so
what we can do is say app dot set and we
want to pass in here view engine because
we're gonna be setting our view engine
and we need to set this to EJ yes that's
the view engine that we imported and the
one that we're going to use and then in
our app we can just say here res which
is our response we want to render our
index file so we can just say index like
this and if we save and refresh over
here you can see we're getting that text
hello world being printed out so we are
now rendering everything in our index
tjs out to our browser here now the next
thing to do is actually to create what
we're going to use inside of our index
ejs file and this index file is going to
contain both a form for creating new
short urls and it's also going to create
a list of all of our current short URLs
that we have so let's get started by
creating boilerplate HTML with this
exclamation point and we hit enter and
in order to get proper syntax
highlighting in this ejs file when we
start going forward and using actual ejs
syntax you're going to want to download
an extension here which is called ejs
language support as you can see at the
top make sure you have this installed
and that way you properly get these
syntax highlighting the inside of your
ejs file let's just shrink that back
down so inside of our ejs file what we
can do is actually put all of the code
inside of here for rendering out first
that form as well as the table which is
going to contain all of our different
results for the short URLs we've already
generated so first I want to just have a
title for our page we're gonna use an h1
and we're just gonna call this URL
shrinker then we're gonna have our form
which is going to have an action which
we're going to handle later and a method
which in our case is going to be a post
method and inside this form we need to
have an input which is going to handle
our full URL and then a submit button so
let's create a label which is going to
be for our full
URL and we're going to someone here say
full URL and then we're also let's just
make that URL instead and then we're
going to have an input and this is going
to be a type of URL and we're going to
give it a name here of full URL and
we're also going to give it an ID which
is full URL this is just our label is
links to our input now lastly we're
gonna create a button we're gonna make
this a submit button whoops
submit and this button is just going to
have the text of shrink now if we save
refresh our page over here you can see
we have the title label input and then
our button for shrink and right now our
form doesn't work but that's because we
haven't set up the backend for it now
before we get on to the backend let's
actually create the shell for our table
which is going to contain all of our
different URLs when we create them so
let's create a table and inside of here
we want to have a header and inside of
that header we're gonna have a row which
is just going to have three different
th's or tee headings inside of it and
the first one is going to be far full
URL and then we're gonna have another
one which is going to be for our short
URL that we generate and lastly we're
gonna actually track how many times
everything was clicked so we're just
gonna have another column which is going
to be for our clicks then we're gonna
have a body and inside that body we're
just gonna put a placeholder row for now
so let's just have a single value here
which is just going to be for example my
own website so we'll just put an anchor
tag here which it has an href to HTTP
colon backslash backslash courses dot
web dead of simplified comm and then
we're also just gonna put that exact
same URL as the text for our anchor tag
and if we save that refresh our page
over here you can see that's showing up
instead of our column as our full URL
now let's do a similar thing which is
going to be another TD which is going to
be for a short URL and we want an anchor
tag in here and this one instead is
going to have an href which is our
shortened version so it's going to just
say for example slash 1 2 3 4 5 6
whatever this shortened URL is it
doesn't really matter right now
we're going to use that same exact text
inside of the anchor tag and if we
refresh we now have that URL and then
we're gonna have a final row in our TV
we'll just
going to be the number and clicks will
say this one has ten clicks and as you
can see this is what our table is going
to look like let's just zoom that out a
little bit so it's not quite so
scrunched up in the guy that looks a
little bit better and now in order to
style everything inside of this view
instead of writing our own CSS I'm
actually just going to use bootstrap for
this so make sure you go to bootstraps
website get bootstrap comm go to the
download page and we're just gonna use
the CDN for importing this into our app
instead of downloading it locally so
just copy this first value here for this
link tag that's all we need and we're
just gonna paste that into the head Save
and now we have access to all of the
bootstrap information which we can use
to style our page over here you can see
it's already applied some basic styling
so the first thing I want to do is work
on styling out our form but actually
before we can get to styling the form
let's wrap everything inside of a class
called container and in this container
is just a bootstrap class which allows
us to have nice padding and margins and
everything between the edge of our page
so we have that container put everything
inside of it and if we save refresh you
see that just gives us a little bit of
margin and padding which looks pretty
good now we can move on to style in our
form so let's add a class here we're
gonna use my dash 4 this is gonna add
margin on the top and the bottom so if
we save refresh you can see it just
based our form out from our title and
our table and we're also going to use a
form in line so that we can have our
form inline like this when we start
applying all of the rest of our
bootstrap classes now the very first
thing we're gonna do which seems a
little weird is we're actually going to
hide this label and only allow it to be
read by screen readers so if we apply a
class here which is equal to s are only
this means this will be screenreader
only and if we refresh you can see it's
disappeared from our page so it'll only
be read by people using screen readers
and people that aren't using screen
readers just will not see it and that
means that for our input we want to make
sure we have a placeholder here which
says the URL and if we refresh that way
people know that this text box is for
entering in a URL also we're going to
make this required since we always want
to make sure that they enter a URL and
now we can apply some classes to this
input here and let's just shrink down
our side page so we have more room to
work with our HTML in the classes I want
to apply our form control and I want to
apply a little bit of margin on the
right of - let's save that and refresh
and
last thing to do is to style this button
we're just gonna put button and button
success that'll give us a green colored
button could we refresh you can see we
have that green button there and if our
screen size becomes large enough then
we're gonna have our farm side by side
like this let's actually just zoom out
so we can see that when we have more
room with our HTML and in order to make
it so our URL text box fills the entire
width we just want to apply a class of
column to it so we're just gonna say
call here and if we refresh that now
forces this URL to take up the full
width no matter what now with that out
of the way our form is taken care of and
we don't have to worry about it wrapping
on to a new line it'll always be on the
same line and now we can work on styling
out our table which in bootstrap is very
straightforward we just want to apply a
class of table and tables striped and if
we save refresh over here you can see we
have a nice-looking table we can even
apply the class of table responsive and
if we refresh that's just going to allow
us to scroll across our table on small
screen sizes like this as you can see
that's working pretty well and we can
expand this if we want to make it easier
to read everything inside of our HTML
and that's all the styling we're gonna
do for this it's just really basic
styling I just wanted to throw it in
here so it didn't look completely ugly
now the next thing to work on is
actually going to be our post request
for our forum which is going to allow us
to actually create new short URLs so the
action we're gonna use for that is just
slash short URLs so we're gonna post to
this short URLs endpoint and then let's
actually create that endpoint here we
can just do an app dot post and if you
remember right that is short URLs make
sure we start that with a slash like
that and this is again going to take a
request and a response and in here we
actually want to connect to our database
and save a new short URL so we need to
set up our database connection and if
you remember we used a library which we
imported earlier which is called
Mongoose so we're just going to make
sure we require that library now we can
just do that by requiring Mongoose and
in here we can actually connect to our
database so to do that we need to call
the function which is called Mongoose
dot connect and we need to pass it in
the URL for this database so for our
local database we can use MongoDB
: localhost slash and then we just put
whatever we want to call this database
call it URL shortener oops shortener
just like that and then we can pass it
some setup options by default we're
gonna want to pass it the options of use
new URL parser set that to true and also
use unified topology and we're going to
set that to true as well
this just allows us to not have to worry
about any deprecation warnings because
as you'll see if I remove this and I
save you can see that I get these
deprecation warnings down here and
that's because we are using a certain
version of MongoDB and Mongoose so it
expects us to have this use unified
topology true and if I save you see
those warnings are still appearing so
let's see what they say is wrong we
scroll all the way up you can see it
says parse error invalid
connection string it looks like I forgot
to add the slashes here for a MongoDB
connection now if I save you can see we
no longer have errors if we refresh our
page everything is working fine no
errors so we know that this connection
is working as we want it to so now we
need to create a model that is going to
store all of our short URL information
so just create a folder called models
and inside this folder we're gonna
create a file called short URL J s
whoops make sure I spell that correctly
J s there we go
and in here we want to again require
Mongoose so we're gonna do Mongoose
equals require Mongoose just like that
and then what we can do is actually
create a schema so we can set a variable
which is called our short URL oops
kima and we're gonna set that equal to
Mongoose dot schema we want to create a
new one of these
so we'll say new mungus schema and this
actually takes just an object which is
going to be all of our different columns
for our database and inside of here
we're gonna have a full URL a short URL
and then the number of times we've
clicked so our first property is going
to be full and then we're going to set
some options for this for example this
is going to be a type of string so we
can use type equal to string and it's
going to be required true so make sure
we say required true and essentially
this full is the name of the column in
our database and then this is just the
type of that column and whether or not
that column is required let's do the
same thing for the short version of our
URL the type is going to be string and
the required is going to be true
but we need some way to generate a short
version of the URL because our form only
has one URL to enter but we need to
actually generate a short URL to use so
to do that we're gonna use a library
called short ID so let's close out of
here and we're just gonna NPM I short ID
and this is a library that it's very
simple all it does is to create a unique
short identifier so let's import that we
say a short ID is equal to require of a
short ID and this has a single function
inside of it that we're worried about
which is short ID jot and generate and
this function just generates a short ID
for us so in order they use that with
our short column here we can actually
specify a default and we pass it a
function and this function is going to
run as the default value for our short
column and we can just say short ID dot
generate and since this dot generate is
a function this is essentially the same
thing as passing it a value like this
it's just going to automatically run our
generate function for us so we don't
need to worry about wrapping it in its
own function so now every time we create
a new short URL it'll generate this
short ID here and save it in our short
column the last thing we need to do is
our clicks so what we can do is just our
type here set to number we obviously
want to make sure that this is required
so we'll say required true and our
default for this one is just going to be
a value of 0 always we want to start
with 0 clicks on our short URL that just
obviously makes sense and lastly we
actually need to export this so we'll
say module exports is equal to Mongoose
dot model which is a function that takes
the name of our model which in our case
is short URL and it takes the schema
which is our short URL schema so this is
actually what kind of hooks up our
database and our actual model that you
can see that we created here so now we
can affect our database from within our
model let's just save that and now go
into our server we can get our short URL
oops
short URL and we can just require that
file if we start with that slash that's
going to be all of our local files we
can go models and short URL so now we
have our short URL being imported and in
our post we can actually create a new
one
so what we can say is short URL create
and all we want to do is pass in that
full value which is full and we know we
can get our body values by saying
request body and this is going to give
us access to our form and if we check in
our ejs file we have a name set on this
of full URL so we want to just access
the full URL property of our body and in
order to get this to properly work with
express we actually need to tell our app
that we're using URL parameters so we're
going to say app dot use express dot URL
encoded and this takes a single object
and all we want to do is set the
extended property to false it's required
that we pass in either true or false
here either one it doesn't matter for
our use case and now if we save we're
able to actually create a new short URL
here one thing to note though is this is
a synchronous action it actually happens
in the background and we want to make
sure we wait until this is finished
executing so we can just create an async
function we'll make this a synchronous
and then we'll just use the await
keyword here to say we want to wait for
this to finish creating before we move
on and if you're not familiar with async
await I have an entire video covering it
in the cards and the description now the
last thing we want to do is just
redirect our user back to our home page
this index page here so what we're doing
essentially is we're just creating a new
short URL and then redirecting us back
to the home page so now let's try that
out let's just refresh our page to make
sure everything works and you can see
we're getting an error we just need to
make sure we rerun our site so NPM run
dev start once that gets started up we
can now refresh as you can see and let's
try a new URL we'll see HTTP colon
backslash backslash courses dot webbed
of simplified com and if we typed in
shrink you can see everything executed
what our URLs aren't showing up yet so
inside of our get here we actually want
to make our URLs show up so we can call
short URL dot find and this is going to
get all of the URLs inside of our short
URL table so we can just say short URLs
is going to be equal to awaiting that
function we'll just make sure that this
is an async function so that we can use
a weight then we can pass those short
URLs
down into our view by just passing like
this an object with short urls like this
and then in our index file we can
actually loop through every single short
URL so what we want to do is take our
short URLs we want to loop through each
one of them so for each short URL whoops
URL we want to run this function here
and let's just make sure we end off
these brackets and create brackets
around these clothing is closing ones as
well and then we're just going to copy
this code because we're going to
essentially use this exact Rose syntax
but we're going to replace these a trips
that we manually set by using the hrs
from our short URL so we can say short
URL dot full because this first column
is for our full information and we're
also going to set the text of our anchor
same exact thing and then this one is
going to be for our in here short URL
dot short let's make sure we close that
off and again we're just going to copy
this and paste this into this section
here and then lastly for our clicks
we're gonna do the same exact thing
short URL dot clicks and we're gonna
close that off and let's just make sure
all of our syntax looks correct
we have opening and closing brackets for
all of these this one's opening closing
opening and closing opening and closing
opening this closing one is backwards
though so let's make sure we have here
and now all of our syntax should be good
so now if we save and refresh you can
see that this is actually updated to
have our normal courses URL and this has
the auto-generated short URL that we
created and then our clicks but
obviously when we click our short URL
this isn't gonna work it says cannot get
this weird short URL so in order to fix
this issue we need to create yet another
route and the important thing to do is
make sure this route comes at the very
bottom of all of our other routes so
we're gonna say apt-get and what we want
to do is get anything that has a value
here so we're just going to call this
short URL so essentially what this is
saying is give me any route that has
information directly after the first
slash so here directly after the first
slash we have this text and this is
going to be saved in a parameter called
short URL and then we can do the same
thing request response
and while we're at it we're just going
to make this an async function as well
and inside of here we can use request
per am - or URL and this is actually
going to be whatever we pass here this
short URL inside of our URL up here so
we can just actually use short URL our
model we can call the dot find one and
all we want to do is we want to find one
based on that short property
so whenever the short property equals
short URL we want to actually find that
model so we can say our short URL is
going to be equal to awaiting this
function and if we take a quick look at
this what's happening is we're just
calling to find one method on our
database passing it in our search query
which is just saying we want to find
which everyone has this short ID which
is passed in from our URL and then we're
gonna save it to this variable now
sometimes people are gonna pass a URL
that doesn't exist so we want to check
for that we can just say if short URL is
equal to whoops null then we just want
to return whoops return res dot send
status of 404 essentially saying we
cannot find what you're looking for
otherwise if we do have what they're
looking for we have a short URL here and
we can take the clicks on it and add one
essentially they've clicked on this so
we want to update that click counter by
adding one and then we want to make sure
we call the save function to update our
short URL with this new clicks value
then lastly we can call res dot
redirect and we're actually gonna pass
it in our short URL dot full so
essentially we passed in the short URL
we appended one to the clicks and then
what we're doing is getting the full URL
and redirecting our user to wherever
that happens to be so now let's save and
if we refresh our browser on this we
should get redirected to my course page
and of course that didn't quite work as
intended so let's take another look over
here and I notice immediately that I
spelled this parameter quest dot params
instead because we want to search
through all of our params and now if i
save and i refresh this we should get
redirected to my course page and as you
can see it redirected us to my course
page now let's go back here obviously we
want to be on our localhost 5,000 just
like this and let's create another one
we'll go to my blog for example say HTTP
s blog dot web dev simplified calm and
if we click shrink you can see that
shows up down here we have our short URL
and you even notice our clicks on this
short URL that we've already used has
been incremented by one and now let's
just open this in a new tab and you can
see it's redirected me to my blog by
using that short URL instead of having
to use the entire long URL now the very
last thing to do is we want to create a
file over here called dot get ignored
oops
ignore just like that and we want to
make sure we ignore our node modules and
the reason we're doing this is if you
ever deploy this site using git or
github or something like that you don't
want to send all of these node modules
up to your server for git and github you
just want to send up this package JSON
which handles downloading all of those
files for you so with this git ignore
we're just ignoring that folder so we
don't have to worry about saving it to
our github repository or whatever
repository you use and that's all there
is to creating this amazing URL
shortener if you enjoyed this video you
can check out some of my other
project-based videos linked over here
and subscribe to the channel for more
videos just like this one thank you very
much for watching and have a good day

We are social