Build a Custom URL Shortener Service

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] this video is sponsored by dev Mountain if you're interested in learning web development iOS or UX design dev Mountain is a 12-week design and development boot camp intended to get you a full-time position in the industry to learn more visit dev mountain comm or click the link in the description below hey what's going on guys so in this project we're gonna be building a URL shortener service so I'm sure that most of you have heard of bitly and some of these other URL shorteners where we can take a very long link such as this amazon link right here and if we put this in here and click shorten it gives us a much much shorter link that has this the domain part of it and then it has this code and if I click it it goes to that same page so what we're gonna do is build a service that does this we're not going to build the user interface or anything like that I'm actually saving that for a course possibly might view j/s course we'll have the UI we'll have users that can log in and create short links but in this video we're gonna build the the API basically so that we can get this functionality we can send a long URL and get back a short URL that will actually work and we're going to be using a database because we need to store the the long URL the short URL and the code which is basically this part here ok so I'm using MongoDB for that we're gonna use MongoDB Atlas which is the cloud version but if you want to use a local MongoDB instance you can do that as well so I'm just going to log into MongoDB right here I think that's it no it's not it okay so basically if you're new to MongoDB you can lock you can create an account for free you can log in and it allows you to create a cluster you need to add a user I already have a user you can see if I click connect and I click connect to your application I get this string right here that has my username and then I just need to put my password in so we can use this in our application to connect to our database all right so that's all set for now so I'm going to jump into a terminal and we're just I'm starting this from absolute scratch I just have an empty folder here and I'm gonna go ahead and just open up vs code okay so I just have a folder called URL shortener service and I'm going to I'm gonna use my my standard terminal here as opposed to my integrated terminal so let's do an NPM NIT and just add on - why and that's gonna create a package Jason and I know a lot of you guys know some of this stuff but I'm still gonna explain it for people that don't so package Jason is just manifest with some information here it also holds any dependencies or any packages that we install and there's quite a few we need to install so I'm gonna clear this up here and let's do a NPM install Express okay so expresses the web framework we'll be using to create our routes and stuff we're going to use node config or config which is just a package that allows us to have global variables we're gonna be using Mongoose which is an abstract basically like an abstraction for our database so that we can easily interact with MongoDB we're gonna use a package called short ID to generate the URL code and we're going to use valid - URL to validate the URLs that are sent that are sent to the API okay so those are the regular dependencies and now I'm just going to go ahead and npm install with a - uppercase D so I'm installing a dev dependency and I want to install node Mon which will constantly monitor our applications so that we don't have to keep reloading it every time we make a change all right so you can see all that stuff was added to the package dot Jason now as far as scripts I'm just gonna add a start script here so basically if we do NPM start I just want it to run node and then index which is gonna be our our entry point file and then we'll create a dev script that will run node mon-sol node montt index and we'll save that we should be all set for our package Jason so now let's create the entry point I'm gonna call it index J s and let's just set up a basic Express server so I'll say Express so we want to require Express and let's initialize our app with Express and we're gonna be accepting data from you know when we make the post request to create the URL or to create a short URL so we need to add a piece of middleware hair so we use app dot use and we can just do Express dot jason and pass in this extended value and set that to false so basically what this does is it allows us to accept JSON data into our API then we're going to create a port variable which I'm going to use 5,000 and then let's say app dot listen which will listen on a port so we'll put our variable in there and then we can have a callback and I'm just gonna do a console log and we'll just say server running on ports and then we'll put in our variable of port all right so just doing that the server should run if I go to my terminal and I run npm run dev there we go so node mon is now running and it's watching on port 5000 all right so now that we have that let's let's start to connect to our database so I'm going to create a folder called config and inside here I'm going to create a default dot JSON file so when we use that config package that I installed this right here basically it looks at this default dot JSON for any global variables and if you go into production if you deploy and you're in a production environment you want to create a production dot JSON for your variables so this takes in just a JSON object and we need our URI and I can grab that from Atlas so if I go to connect connect your application and just copy this string right here and paste that in and you just need to add your password so mine is Brad T one two three four and then we also want to put base URL here so this is basically going to be your domain and in this case it's just going to be localhost port 3000 but if you deploy this and you get a domain you can use that all right so let's save this close it up and now inside config we're gonna create another file called D bjs and this is where we want to connect to our database and if you took my myrn stat course we're doing pretty much the same thing as far as connecting so we're using Mongoose so require Mongoose and we also want to bring in that config package because we want to be able to want to be able to grab that URI I can't spell today okay so we'll create another variable called DB and said that's a config in the way that we grab those global variables is just with config get and I'm gonna grab URI okay so this is gonna grab this right here whatever this value is so underneath that let's create a function to connect to our database so I'll call this connect DB and we're gonna label this a sync because we're gonna use a sink of weight here because Mongoose when you use Mongoose methods it returns a promise so instead of using dot then I'm gonna I'm gonna use a sink away okay and we want to wrap this in a try-catch and inside the try we're gonna await Mongoose dot connect and this takes in the string the connection string which we put in DB variable and then some options and we're gonna add here use New york-new URL parser and set that to true otherwise we're gonna get some warnings okay and then once we connect I'm just gonna its console.log and we'll just say MongoDB connected okay and then down here if something goes wrong we'll do a console error of error dot message that should give us that should print out the message and then we'll exit will say process exit we want to exit with failure so we're gonna put in a one okay and then we're just going to module dot exports the connect DB function so that we can run that in the index file and connect so let's save this and let's go to index j s and let's see we want to bring in connect DB i want to bring in that function we just created so we're gonna require and we want to go into the config and then DB and then let's go right yeah I guess we'll go right here say connect to database and all you have to do is run connect dB all right so I'm gonna save that and if we go back to our terminal now now you see this DB connected okay if I were to mess this the string up somehow which I'll go to default Jason and if I mess up the password and we take a look you can see that the app has crashed and we get this bad authentication failed message so I'm just gonna fix that and we should be all set good so we can close that up we can close that up we're connected to our database so the next thing I'm gonna do is create our model so let's create a folder called models if you haven't used Mongoose before you basically create a schema for each resource we only have one resource which is our URL so I'm gonna create a model called URL dot Jas and let's see we're gonna bring in Mongoose and then we want to create a schema so we're gonna call this URL schema and we set this to a new Mongoose dot schema and then this takes in an object with all the fields we want so the first thing is a URL code and that's gonna be string we also want a long URL so that's you know the long version or the original URL and then a short URL which we're going to construct which will also be a string and then let's also have the date for the date I'm gonna set type string the reason I'm doing it this way is because I also want to do a default and let's make that date dot now that way that the current date and time will be inserted and then we just want a module dot exports so we want to export the model so we say Mongoose dot model and name of the model is URL and then we need to pass in the schema okay and that's it let's save that so that's our model now we need to start to deal with our routes so we're gonna have a folder called routes basically just gonna have two routes but I'm gonna have two separate files one is gonna be index dot JSON is gonna be whether that's use me URL dot J s so URL j s is basically where we're gonna have our post route to be able to create a URL and insert it into the database index J s is gonna have the basically all the short URLs recreate we need to have them work so basically we need to have them redirect to the long URLs that's what's going to go in here so before we do anything here let's go to our main index J s and we need to basically define our routes so let's go right here and say app dot use so we just want to set slash to require dot slash routes slash index I'll copy that down and then we also want slash API slash URL to pertain to that URL routes file alright so we'll save that what's this okay so it's just telling us we haven't used a router yet so we need to go to both of these and set up our Express router so the way we do that is we bring in Express and then to create a router will say const router equals express dots uppercase our router and then at the bottom we're gonna module dot exports equals router and we want to do the same thing in our URL j s and that should clear up that error yeah alright so we're gonna start off in the URL j s this is where we we actually create our short URL that's gonna have that route so we're gonna bring in a couple things here so we're gonna bring in our valid URL method that's comes from that valid URL package that I installed so it's valid - URL let's see let's also bring in our short ID so it's shorts ID like that short ID and then let's also bring in do we need config yeah because we need the base URL so let's bring in config and then we want to bring in our model our URL model so I'm gonna go right here and just say Const URL equals require dot dot slash so up one level into models and into URL alright so let's create our route so I'm just gonna give this kind of a signature here let's say route and this is gonna be a I'm sorry it's gonna be a post request not a poet a post request to slash API slash URL slash shorten okay that's going to be the endpoint to create a short URL and let's just give this a description I'll say create shorts URL okay so let's go ahead and take our router and let's a router dot post because this is a post request and then in here we just put shorten okay we don't have to put this API URL because we already connected that right here to this file alright so it'll be this route when we hit that and then we have request response and we're gonna get inside this request dot body we're gonna send some data and I'm gonna pull out that data using destructuring so we're just basically gonna send a long URL that's it that's all we're gonna send with the request and for our base URL let's set a variable of base URL and let's get that from our config file so config dot get and we want to get base URL which is gonna be in our case localhost oh wait a minute I put 3000 didn't I should be 5,000 because that's what I'm running it on whatever port you're running it on it's what you want to use alright so let's see let's make sure that URL is valid so to put an if statement here and we're going to use valid URL which has a method called is URI okay so basically it'll just make sure it's a valid URI or URL and we want to check the base URL first and wait a minute if it's valid no let's let's check to see if it's not valid and if it's not valid then we're going to return a res dot status of 401 and we'll add a jason message here and we'll just say invalid base URL okay so now we want to generate the code pi so if we look at the bitly website the link that was generated this right here is the code okay and we're gonna use that short ID package to do that so let's say create URL code so we'll say Const URL code and all we have to do is say shorts ID dot generates and that will create it for us now what we want to do is check the long URL that's sent in from the client and make sure that that's an actual URLs let's say check long URL actually put a comment here all right so same thing we're gonna do an if and let's say if valid URL dot is URI and we're gonna pass in our long URL which remember comes in from the client and if that's valid then we're gonna want to look in our database to see if that URL is already there so I'm gonna do a try-catch here and let's see I also want to mark this async this route callback he sink because I'm using a sink of wait for Mongoose so let's do I'm gonna use let here and create a variable called URL and set this to a wait and then we're gonna take our model so with Mongoose we have a bunch of different methods one of them is find one which will find one record from your database and we want to find it by long URL and this is the same as doing this okay now we want to see if there's a URL found so let's say if there's a URL then we want to just return that or you know respond with that so we can just do res dot jason which will give a 200 response and we'll send the URL which will have all the database fields the long the short the code and the date alright now if there's not a URL found then let's see we're gonna construct our short URL so let's say Const short URL and we'll set this to our base URL and then we want to just add on let's say slash and then we're gonna add on the URL code okay so the URL code was right here was constructed with that short ID package with the generate method so it'll be localhost 3000 slash and then some random code okay now down here let's take URL okay which we initialized here if it was found then you know it'll just return the response if not then we're gonna set that to a new URL to insert into the database and this takes in an object whoops what did I do here forgot the equals so in here we're gonna have the long URL we want that inserted we also want the short URL that we just created and we also want the URL code and then remember we also have the date so I'll just set that to whatever the didn't then date is okay and then we need to save it because just saying new URL doesn't actually save it it just creates the instance to save it we need to call URL dot save which returns a promise so we need to put a wait in front of it but we don't need to store it store it in a variable and then let's just do our res dot jason and then we'll return URL which will include all this stuff all right hopefully that makes sense now down here and the catch so if something goes wrong it's most likely some kind of server error so I'm going to first of all just console error whatever the error is and then as far as response from the server let's do a 500 status and we'll just say Jason and we'll do server error okay now this else is it pertains to this right here if long URL is not valid so if it's not valid then let's just do a res dot status 401 and Jason let's invalid long URL and I think that should be good so I'm gonna save that now just to kind of reiterate in case any of this doesn't make sense we brought in everything including our model we have a post request to this endpoint right here we are pulling the long URL out from the body which is sent from the client we're pulling the base URL from our default dot JSON file which is localhost 5,000 and then we're checking the base URL making sure that's valid then we're generating our URL code for the short URL we're checking the long URL to make sure that's valid this is what's sent in from the client then we're looking to see if that URL is in there like if there's a URL for google.com that's already in the database then we're just going to return whatever that is whatever's there else then we're gonna construct the new short URL we're going to instant our instantiate a new URL object with the long short the code and the date we're gonna save it to the database and then respond with it okay down here something goes wrong we'll send a server error 500 if the if the URL is invalid the long one then we'll send this status all right so that's what's going on here so I guess yeah I guess we can go ahead and try this out now like I said you can use whatever you want to to make this post request I'm gonna use something called rest client which is a vs code extension which is this right here alright so in order to use this within my file structure I'm going create a folder called requests and I'm going to create a file called API dot HTTP and in order to make a request this is actually pretty easy we can just say post and the URL is HTTP localhost 5,000 and we want to go slash API well yes that's what we want but let's get rid of that so API URL shortened and then we have to have a content type and you can see we get these little dropdowns content is application slash Jason and then we want to send the data which is gonna be long URL this actually has to be jason long URL ok so let's grab a long URL I'll go ahead and grab that Amazon link and let's go ahead and paste that in and now we should be able to make our request so I'm gonna click this send request invalid protocol Oh alright let's try that connection is being rejected the service isn't running because it says three thousand five thousand try it again and there we go so you can see with our response we have them the ID which MongoDB creates on its own we have the long URL which is the original Amazon link and then we have the short URL which is localhost 5,000 slash and then a code ok we also have the code itself and we have the date and time now when if you deploy this you you probably want to register like a short domain and then you know so this is really really short localhost 5000 is kind of long but let's check our database if we go to MongoDB or Atlas and we go to collections you can see there it is so it got stored now this link is not going to work right if I go and copy this and I paste this in it's it's looking for this route so what we need to do now is create another endpoint for the codes and that's going to go on the index J I so let's head over to that we can go ahead and close that up you know I guess I guess we'll save that request all right so we can close up URL dot J s now let's go into our routes folder and then index J ass because that's what we're gonna put this so we need to bring in our model and this is this is gonna be pretty easy so dot dot slash models /url and then let's create our route so let's say oops let's say route so it's a get request and it's gonna be to just slash and then whatever the code is and let's do description so the description we're going to redirect to the long or original URL okay so it's gonna be a get request so we'll say router dot get and we're just gonna say in here / : code because obviously this is this is a parameter this is a placeholder so we want this : here we're not actually going to slash code and then let's do a sync and request response and we'll do a try-catch here okay so inside the try let's create a variable called URL and we're gonna use find one again from Mongoose which returns a promise so we want to do a wait URL dot find one we want to find it by the code okay so we're gonna say URL code and we can get whatever's passed into this right here we can get with request dot params dot code okay so we want to match that code we want to find that URL so then we're gonna say if if URL so basically if it's there then we want to return a res dot redirect okay because we're actually gonna redirect to that to the long URL so we'll take that URL object and we want the long URL property okay well that's so that's what we're redirecting to else then let's just return a res dot status of 400 actually I guess we could do a 404 and say dot jason and say no URL found okay and then in the catch here we'll just do a console error and just log whatever is in error and then we'll do a res dot status 500 and we'll just say server error alright and that's it so just to kind of reiterate we're gonna try to do our you know whatever slash code whatever the code is we're gonna check to see if there's a URL with that code if there is we're gonna redirect to it or though we're gonna redirect to the long version if not then we're just going to say that the URL isn't found if you want to do a standard redirect er I mean you can handle it in a different way if you want to but I think that this is fine so now let's let's once again cop be the short URL here and let's open up a new tab and let's go to it and there we go so our service is working we can now generate short URLs and they work and just to kind of try it one more time let's let's let's get a different URL grab this right here so grab that and if we go back to our API HTTP I'm just gonna replace this and let's go ahead and send that okay so we get the response back that should have added a new row in our database let's check it out yep so there it is which one is it this one so now both of these should work okay that's the end that's the PlayStation let's try this one and that's the charger thing okay so that's working good now I just want to show you if we were to insert the same URL so if I were to insert this again let's just send the request it just gives us the data back and it's not gonna add it more than once so if we look in our database and I reload we're still gonna have two rows okay because there's no sense in having the same short URL I'm sorry the same long URL with a different short URL okay unless you have it where different users are creating their own short URLs and things like that all right so I think that's it guys we have our service created like I said I'm probably gonna add on to this for a course where we create a UI and a front-end and all that if you want to create your own front-end with react or view or something like that feel free to do so I'll have the code for this in the link in the description but that's it thanks for watching if you like this please leave a like and I'll see you next time
Info
Channel: Traversy Media
Views: 96,358
Rating: undefined out of 5
Keywords: node.js, nodejs, node.js api, url shortener
Id: Z57566JBaZQ
Channel Id: undefined
Length: 34min 6sec (2046 seconds)
Published: Tue Jul 09 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.