Learn Express JS With TypeScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Sometimes I feel Express is sort of dead framework. It's been in Alpha for a couple of years now... https://github.com/expressjs/express/blob/5.0/History.md

I know it works well, no scaling issues, etc but I would like to explore something that leverages modern features

👍︎︎ 3 👤︎︎ u/Omkar_K45 📅︎︎ Sep 24 2021 🗫︎ replies
Captions
rest apis are a staple of the web development industry and the most popular web framework is express i've been using express since 2016 and have built many production grade apis that are serving hundreds of thousands of requests per day by watching this video you'll learn how to build scalable production grade apis with express and typescript you'll learn the basics of express and advanced topics that will keep your api secure maintainable and scalable to follow along with this guide you'll need four tools an editor i'm going to be using visual studio code you'll need nodejs installed i recommend installing node via node version manager or nbm a package manager such as npm or yarn i'll be using yarn you'll get npm when you install node and something to send http requests to your api i'll be using postman if you need to install any of these tools now is a good time to pause the video and go and get these tools so this is the structure that the video will be following we're going to be getting started and we're going to bootstrap our application we're going to dive into routing then we'll be taking a look at middleware we'll be taking a look at error handling application structure and finally security so let's get started by bootstrapping our application i'm in the terminal here and i'm going to type mpx tsc with the init flag and this is going to create a ts config file for us and if we open up our file explorer you can see here we have a ts config file next we'll do yarn in it and this is going to initialize our node.js application and we can press enter for all these questions so the next thing we need to do is to make a source directory so i can do mk dir and i'm going to say source and then i'm going to create a new file inside our source directory called app.ts so i'm going to say touch source app.ts and if we open up our source directory you'll see we have an app.ts the first thing that we need to install is going to be ts node dev so we can say yarn add cs node dev i'm also going to install typescript and these are going to be dev dependencies so i'm going to use the dash and capital d i'm going to open up my package.json and i'm going to create a new entry in here and this is going to be called scripts and i'm going to make one script and this is going to be called dev you can call it start or start dev whatever you like and i'm going to say ts node dev and i'm going to give it the path to my app.ts so i'm going to open up app.ts and i'm just going to console.log in here and say hello world now i can type yarn dev in the console and i should see hello world get printed to the console so we see hello world here and the application just exits to make sure our application doesn't exit every time and just sits here and watches the file i'm going to do dash dash respawn and i'm also going to do dash dash transpile only i'm going to type yarn dev again and you can see here we get hello world and if we save this file it should restart the server and hello world prints again let's stop the server and i'm going to say yarn add express and once that's installed because we're going to be using typescript as well i'm going to say yarn add at types node and at types express and i'm going to install these as dev dependencies so while those are installing we can get started bootstrapping our application so i'm going to import express from express i'm going to say const app equals express and our first route is just going to be hello world i'm going to say app.get and routes take a callback so i'm going to pass in a callback here and the first parameter is the request object and the second parameter is the response there is a third parameter called next that we'll go over soon and i'm going to return res dot send and i'm just going to put a string in here that says hello world the next thing i'm going to do is listen and serve i'm going to say app dot listen and i'm going to pass in a port here so i'm going to pass in port 3000 and then this takes a callback and i'm just going to console.log application listening at http localhost and then port 3000 i'm going to say yarndev and i've missed the route in here so this won't work i'm just going to make this the index file so you can see here application listening at port 3000. so let's make a call request to this application and see what it returns so i can type curl and pass in the address of the server and we get hello world back so because this is a get request we can also make this request in the browser so if i come over to a browser i can put the address into the address bar and you can see we get hello world back so let's talk more about routing so we have a get request here that is listening on this path here which is the index and then we get the request object and then we have a response object so if we wanted to make a handler for a post request we would simply say app dot post and then we can pass in the path here so i can say slash api slash data and we simply pass in a callback here so this is the request and this is the response object so i'm going to console.log the request dot body because a post request can have a body and i'm going to return res dot send status and i'm just going to send back a 200 request and a 200 is ok so let's go over to postman and test out this endpoint so i can put my url in the address bar up here and i can change this to a post request and i can say api data and let's try put some data in the body and i'm going to change this to raw and then i'm going to change the type to jason i'm going to add test and this is going to be true let's send this request and we can see we get back a 200 okay and let's have a look and you notice here that we get undefined and this is because by default express won't pass the request body so to fix this problem it's quite simple we're going to say app.use and i'm going to say express.json and this means that we can now pass json bodies if we want to be able to pass url encoded bodies we're going to do app.use express dot url encoded and i'm going to pass in an option here and this option is going to be extended and i'm going to set this to true but if you don't need to pass url encoded bodies i suggest that you don't add this and for now we're just going to pass json encoded bodies let's go back to postman and we can send this request again and you can see here that we get the json body so this here is middleware and we're going to talk more about middleware later on about how to create your custom middleware and how to use third-party middleware so the final listener that you would use a lot is going to be app.all and this is going to listen to all http methods so if we have a look at what we can use you can see here we have get and post and put we have delete and we should also have patch and these are all http methods so i'm going to say app.all and i'm going to say slash api all let's pass in our request and our response and again i'm just going to return res.send status and the status is going to be 200. so let's go test out our all endpoint so let's start off with a get request so i can send this and you can see that we get a 200 if we send a post request we should also get a 200. if we send a put request we should also get a 200 and we're going to get a 200 for all these methods if we send a request to slash all slash nothing for example we should get a 404 and that's because this route doesn't exist so because we're using typescript we will want to type this request object and our response object so let's come up to our express import and we're going to also import a request interface and we're going to import a response interface now we can type our request and response and we can copy and paste this now if we're unsure what we can do with these two objects here we can say res dot and you can see all the methods that are available on this interface if you want to explore it further you can command click on the interface and you'll dive into the definition and that's the same for the request object so let's talk more about responses so here we're just sending a piece of data but there's a few other responses we can use we can use res.end which will end the response process we can use res.json which will send a json response we can use res.jsonp which will send a json response with jsonp support we can do res.redirect which will send a redirect request res.render which will render a review template res.send which will send a response of various types we can do res.send file which will send a file as an octet stream and we can do res.send status like we do down here and this will just send a status code so let's try a few of these methods let's do res.json and we're going to put a json payload in here so i'm going to say success is true name is tom does heck let's send a get request to the index and you can see if we send this post request we get a 404 because we're not listening for a post request on the index so we need to change this to a get request and you can see we get our json payload here and let's add a res.redirect and we're going to redirect them to http dot com and we can send a request again and you can see that we get a 200 and we've been redirected to this example domain if you don't want postman to follow the redirect you can turn off this automatically follow redirects we'll turn this off and we get the response found redirecting to example so we've seen how we can create individual requests here but we can also chain requests let's remove these requests here and we can say app.route and i'm going to have a route on slash index then i can say dot get and we can pass in our request and our response and let's type these objects and for our get requests we're just going to return res.send you made a get request you can also do a dot post let's copy our callback from our get request paste it into our post so so for our post we can say res.send you made a post request and let's do a put so we can say dot put we can copy our callback here and now we can say you made a put request let's go over to postman and we can try these out we'll make our get request first then you made a get request post request you made a post request and a put now let's send a delete request and we're going to get a 404 to fix this we can say all paste in our callback and we can say you made an x request now we get you made an x request and this is really nice if you want to change some crowd operations for a specific resource so for example you might have slash api books and this will be to get a list of books this will be to create a book this will be to update a book and then you would remove this and you might also want a delete so let's talk about route paths so a route path can be either a string a string pattern or a regular expression let's remove this and say at dot get and we can say slash help and this is just a string we can create a string pattern so we can say slash a b times c d and let's let's.send and we can send this string back and this will match a b c d it will match a b x c cd and or match a b some random letters in between and cd or you could have a regular expression instead of a string here we do backslash backslash and i can put in abc now we can send back abc and let's go to postman and try these let's do splash health we'll send a get request and we get back at 200. let's try a b c d and you can see we get our a b times cd response let's do abx cd and you can see we get the same response and let's put some random characters in the middle here and we get the same response so let's do abc and you can see we get our abc and this is from our regular expression the next thing to talk about is route parameters so often you'll want to put a dynamic path inside your route so let's say app.get say api books and we want to have a book id here we can get access to this parameter by saying rec dot params and let's console log this rec.rams and we're going to return rack.params let's go over to postman and try this out and we can replace book id with one two three and you can see we get book id one two three so we can say this is a book id we can send that and we get our book id so to access this book id we're obviously going to say rec.brands.book id so if we send this request again you can see here that we get this is a book id printed to the console we can have multiple params here and we can just add them in like this so we'll say author id and let's print our params again and i'm going to say 1 and you can see here we get author id of 1 and book id this is a book id we can set params in postman so i can say book id flash author id and we can set these values here so i can say book id is 1 and author id is to send this request and it has replaced our book id and author id in the url and this is really nice because you can just copy this from your express application so let's dissect the components of a route handler so you can see here we have our method and then we have our path here and then we have a callback function here and these callback functions work the same as middleware and the third property on this callback is going to be next and we can type this with next function and you can see it comes from expressed as well so i can move this function out of here and i can name it so i can say function handle get book now i can replace this function in my route let's go over to postman and we should expect this to have the same functionality and it does we could have multiple route handlers and we can do this by calling next so let's copy this function here i'm going to call this handle getbook1 and i'm going to call this candlegetbook2 and inside this function here i'm just going to call next i'm going to log second angler and we're just going to send back the params so let's add these in as an array and we'll go back to postman and we'll check out what it does we send the request and it sends our response back we get our params logged and we get second handler logged so these are going to get hit in order you don't have to split these out like this so you can say function and then i can put in a new function and in this first function i can just call next and then i can do the same in this function so i can send the params along but this is a little bit nicer if you split these out into separate functions so let's talk about middleware so you can see here we have our route path and we have a handler here but if we put a different function inside of here like we did with this handle get books one this is considered middleware and this middleware can do whatever you like so we can alter the request object so we can say rec dot name equals and we can ts ignore this for now if you want to do things like this it's nicer if you use something like lowdash.set so let's put our middleware back into our route and i can remove our second handler and inside our route handler i can just do console.log rec.name and we should expect this to log tom you can see our request is just hanging here and this is because in our middleware we're not calling next so our request gets to our middleware and then it doesn't know what to do you need to call this next function so it knows to move on to the second piece of routing send our request and you can see we get tom logged to the console but we also get a mysterious 404 so let's fix that by calling res.send and i'm just going to return the rec dot name and we're going to need another ts ignoring here because this is a custom parameter that express doesn't know about and we get tom so you can create route middleware and you can add multiple bits of route middleware by putting an array or you can create global middleware so to create global middleware we're just going to create a function called middleware and we're going to append a name called tom to the request.name and we want to apply this to every single route in our application so let's say app.use and i'm just going to pass in my middleware and that's all you do so let's send this request again and you can see we get tom back if you want to create a customizable piece of middleware we can use a programming technique called currying so a middleware here is going to be a function that returns a function so i'm going to put a name in here and i'm going to type this out our name needs to be a string so when we call our middleware we're going to say a name is now tom does tech so we can get our name from here rec.name equals name and we need another arrow here and this needs to be a constant so now we should expect our name to be tom does tech and it is so how this works is our function gets called once here and this function will return this new function and this new function will have the name set as its property as a property in the function this technique is called currying so if we only want to apply this middleware to routes that are after a certain point we can move this endpoint above where we apply the middleware and now let's see what happens so we define our route and then we define our middleware and you can see that our name is undefined and that's because you need to set app.use and your middleware above any route that you want to use that middleware this is a typescript tutorial so having these ts ignores here is not good enough so there's a few different ways to fix this one way would be to use low dash set or a better way for this particular circumstance would be to put the name on res.locals so we can say res dot locals dot name equals name and now we just need to change these references down here to reds.locals.name and we can remove these ti signals and you can see that we will now have the name on res.locals so if we want to type a request body or request params we can have a look at the request interface here and we can see that it is a generic so you can see here we have p equals call.params directory res body equals any rec body equals any request query equals past query strings and so we can pass in our generic params here and we can pass in some empty objects and so if we want to type out the request params for example we would put those in the first object here so we can say name and we expect it to be a string so now we can say rec dot params dot and you can see we get name here but more appropriate for this request we would have a book id and we would also have an author id you can see now we have our book and author id on params if we wanted to type the request body we can hover over a request again and we can see that params is one res body is two and rec body is three so we'll come down to the third object and in here we'll put a name and we'll set that to string so now we can say rec.body dot and we get a name good error handling is a must have in every production grade application if you don't handle errors properly it can lead to all sorts of unexpected behavior and it can lead to memory leaks so express comes with some great error handling and this would differ slightly between express 4 which we're using and express 5. out of the box express can handle errors so let's create an endpoint here called slash error and i'm just going to throw a new error here and this is just going to say boom and if we send a get request to this endpoint you can see here that we get a 500 internal server error and express has handled this error for us so if we want express to handle async errors we can create an async function rows error and i can move this error up into this function i can change our callback to an async function i can say await rows graph and i say res res.send i'm going to be ok we need to define request and response so in express 4 this is just going to hang here and that's because we're not capturing this error in express 5 this error will be captured the same as if the error was in the route like it was before so to do this in express 4 we're just going to use a try catch block and this is generally a good idea for all your errors so you can return the response status code and you can log the error so now we're just going to catch this error and we're going to res.send status and our status is going to be a 400 and if we want to send a message along with this status code i can say res.status and then i can do dot send and we're going to say something bad happened and if our async function succeeds i'm going to do res dot send status of 200. let's send our request again and you can see we get a 400 and we get our message here as well something bad happened so i advise wrapping all your async code in track hatch and sending along the appropriate error message depending on what your error is and this will mean that your applications run smoothly and you're always telling the user and logging what has happened in the application let's talk a little bit about application structure the application structure is important a good application structure will keep your application maintainable so in a previous video i did on express apis i recommended a pattern that is controller service model and i would still recommend that pattern so what do i do is i would create a new file and i'll call this routes and i would define all of my routes in this file so let's just use this one route here and i will create a function and i'll put my routes in here all this function routes and i would pass in app and this is going to be type of express and we can import express from express and we can also import our request response and next if you're getting some funny errors here on your request and response make sure you've imported it from express and you've installed the definitely types package see if i remove request from here you can see that it's not telling me that request is undefined it's giving me this no override matches this call error and this can be quite confusing generally it's because you haven't imported that type from express so let's export defaults routes and inside our application i would call routes and we can pass in our app here next i would make a controllers folder and i would make a new file inside of their controllers for each resource type so in this case we have books so i would make a new file called books and i will call this book stop controller dot ts i would move this function here into our books controller so it's a function get book handler then i would put this function in here and then the controller if you're going to make database calls i would make a new folder called services and inside here i would create a books dot services books.service sorry dot yes and this is where i would make my database calls and if you want to have a model for your database i would make a new folder and i would call this surprise surprise models and then you guessed it i would create a books.model.ts and so services would import the models the controller would import services and your routes would import controllers this is just one way of structuring your application but it's one that i've followed for quite some time now and it's been really good another way of structuring your application would be to create folders for each resource so you could create a new folder here called books and you could move your controller into that folder you would also move the model into that controller so into the books folder and you would have your service in the books folder as well and a very popular backend library called nesgis does the folder structure just like this so let's talk a little bit about application security so security is a really big topic and not one that i could cover in this video because a lot of security issues come down to a poor implementation of business logic but from an application point of view there's one simple fix we can make to our express application and that's adding a piece of middleware called helmet so let's yarn add helmet and we can import helmet from element now we're going to call app.use and i'm going to pass in helmet so let's add a route here so we say app.get so i've just have an index route here and let's make a request to that and we can see what helmet has done before we do that you can see in this response here we have this x powered by express take note of that let's send this request again so when you use helmet you need to execute the function you need to say helmet and then add the execution brackets and we can send this request and you can see we have no x powered by here anymore but we get all these new headers and these headers are recommended to keep your application safe you can customize these headers if you like but i find the headers that helmet adds by default are really good so that is express with typescript if you like the video please make sure you give it a thumbs up and subscribe and i'll see you in the next video thank you for watching
Info
Channel: TomDoesTech
Views: 1,448
Rating: 4.878788 out of 5
Keywords: expressjs, express.js, express typescript, rest api typescript, typescript, express, node, node.js, what is a rest api, how to build a rest api with node.js, tomdoestech
Id: KgnJNJk9-to
Channel Id: undefined
Length: 40min 16sec (2416 seconds)
Published: Tue Sep 21 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.