Fastify Course πŸš€ The Performant Node.js Web Framework

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome this video will be a full introductory course to the fastify node.js web framework let's start with an introduction to fastify we'll talk about what fastify is and what makes it different from other similar tools so what is fastify fastify is a node based web application framework or in other words an HTTP https server it can be used to power restful apis or any other API that is HTTP based it can also render templates although not directly but through its excellent plugin infrastructure you can use it to server-side render a handlebars template or many other templating languages it can also of course serve static files through https and although it doesn't allow database access with the built-in internals as fast device plugin based and extensible it has plugins for database access for the most popular database systems such as MySQL postgres mongodb redis and others so why use fastify when there are other node.js based web Frameworks in fact if you remember when you learned node.js or if you're learning node yet right now the first framework you've heard of probably was expressed and the reason for that is that Express is much more popular than any other node.js framework if we look at the Google Trends search interest comparing Express fastify and to other web Frameworks based on node Cola and happy you can see that Express is vastly more popular and the GitHub stars reflect although not the same a similar picture these stats are not perfect and they don't reflect perfectly the actual developer usage of these Frameworks but it shows that Express is much more popular than all other web Frameworks based on node.js so what makes fastify better than expressed and in which aspects is it better the most important ideology before kind fastify is to provide better performance by focusing on the lowest possible overhead on each HTTP request let's see why this is important this is a benchmark with a synthetic hello world request and it shows requests per second that each framework could achieve when basically benchmarked with many requests as you can see fastify outperforms all other Frameworks but most importantly outperforms Express vastly while Express could achieve a little bit over 11 000 requests per second fast Define achieved more than 49 000. now this is a synthetic hello world Benchmark it's meant to show the overhead of the framework on a simple request with a basic response body it doesn't mean that your API can achieve 49 000 requests per second if you use fastify but it means that the overhead is lower and the actual framework is faster this is the actual aim and philosophy behind fastify and while the other Frameworks like Co and happy also perform well their focus is not the maximum amount of performance which is why fastify outperforms them let's now build an app with fastify I have an empty folder opened in my code editor and the first thing I'll do is initialize an npm project next I'll create a source directory and an index.js file we have to install fastify as a dependency using npm install fastify our change my node mod node package type to module so that I can use es6 import syntax and now I'm ready to build my fastify app the first thing I'll do is import fastify from the fastify package and to create a firstify application we just run fastify as a function it accepts an object of options and I will actually set the first option which is logger that is by default false logger when Walker is set to false you will not see any works in the console while the application is running which I don't want for development so I want to set it to true I want to see the works to start the actual HTTP server we have to do fastify listen and provide an options object which I'll specify the port in I want my app to run on Port 3002. this function can actually fail so I'll put it in a try catch block if it throws an error I can use the fastify walk function to walk an error using the fastify Walker and the workshe function has an error method which accepts an error this is very handy actually and if we catch an error I want to exit the program with exit code 1. this will just stop the node.js application now we have created the fastify server and started it on Port 3002 we don't have any endpoints defined so the first the first one I will Define between the instantiation of the server and the listening will be a get method similar to express and other Frameworks we have a get function on attach the fastify object and first we specify the route in this case I want to do a get method on the rootral we accept the Callback Handler with a request and reply objects and that's a function of course and here in the request object we have all of the HTTP requests attributes including the headers and other details on the reply objects we have methods which can we can use to send back or reply like reply send where we can send a response here or alternatively fastify offers an even better method which is to just return an object for example and in this case my object will be message hello world let's now start the server to do so I will add a start script which will be just node Source index that will just start my index file in the source directory so let's run my fastify app now and as you can see the Walker says that the server is listening at localhost 3002 and if I open that in a web browser I immediately get my Json respond on response on the root route which is message hello world now this is the most simple app you can build with fastify there is also an alternative Syntax for defining routes let's check it out it's called fastify route the route method accepts an object of properties the first hunt of course being the method in most cases in this case I want the second get method we also have a URL option where we will specify this routers hello Dash let's include the parameter as well which in this case I want to be name so this route will work under hello and any name parameter right here in this case John it's currently not defined so I get an error not found 404 okay so let's continue its definition the next item we need is the Handler which will be an actual function similar actually the same print function structure as in the get function the get function includes the method as a function then we get the URL here and we specify the Handler as a third parameter this is just an alternative syntax for the same thing we have request and reply and we can return an object again with message and this time I want a message to include my parameter which I can access from the request object right here and the request object has a params property that includes all parameters and I want the name parameter actually I had a typo there all right if I refresh now nothing happens because I haven't refreshed my program I would actually want a watcher for development to do so I will install as a developer dependency nodemon and I'll include a second node script which I'll call Dev which will just run Source index with nodemon let's clear and run the dev script now the same server started the same program but if I save it restarts so now I can refresh and I have I get my message hello including my parameter John if I change that to do it changes now here we have other capabilities in any Handler it doesn't matter if it's the route or this syntax we can also Define a Json schema for every part of the request both the request and the response we do so under the schema property and here we can first Define a schema for the parameters we do so by specifying properties name and then I can Define the required type of name I can also specify the required parameters although this is not extremely useful because implicitly your parameters become required as you get as you define the route with the URL parameter in it so this route will only be accessible if the parameter is provided still we can also Define a schema for the response by specifying response then the Response Code we can specify schemas for different response codes this is a 200 Response Code which is for success of course and here we use the same properties message type string this is how my response is structured and I can specify required properties again I would like message to be required I specify that in an array so how is my schema helpful right now nothing could change basically because everything is valid from the request to the response but if I don't pass message for example in the response I will get an internal server error telling me exactly what I've missed message is required in this case and I didn't have to do any checks in my Handler for that in many web Frameworks you have to do that manually with code here you can do so with Json schema which might is convenient and some people really like the syntax other people hate it you can make your own conclusions I think it's fairly concise for what it can achieve in terms of validation this schema works for parameters response as you can see it also can be used for query string to validate in query parameters such query parameters could be type for example or whatever I mean they are defined let's say we have a last name here let's say we pass name as one parameter and last name as a second one so I'll pass John and last name of the and inquiry string I would expect properties of type last name type string and I will require them also what happens now is nothing but if I remove my query parameters I get a validation error query string points have required property last name if I include it again uh my error goes away and I can of course use this um this property using request query string last name let's check that out sorry it's actually request query last name to correct myself and we can now read both the parameter and the query string to Output Json response and we validate that with a schema we can use the same schema with the alternative syntax while not using fastify route but fast if I get how we do that is we can pass on options object right here that can include a schema and this schema can actually be the same format as right here it makes no difference whatsoever you can use whichever syntax you prefer and find cleaner this one is more Json heavy this one is more functional and I personally like the more functional syntax I think it looks more concise and cleaner and it's closer to the other code you have in your code base as opposed to a lot of Json basically so this is uh uh okay this is how you Define basic routes you would usually want to have multiple files in order to structure your endpoints into controllers for example if you're building a restful API so I would want to separate these two greetings in a separate greetings controller let's say in Express we could do that with a router here we can use a plugin let's first make a controller file I'll call it greetix controller and it will be a function that accepts three parameters the first one is the fastify application server the second one is the options and the third one is done and that's how you define a fastified plugin quite straightforward you have to call done when the plugin finishes all of its subroutine stuff and here you have access to the fastify server and we can Define our routes right here so I'll copy this one the first one we made that just returns hello world and uh let me just remove the options because we don't have any and I'll remove the second route for now now I have a route here defined in my controller how do I register this controller with fastify to do so I'll first import the function greetings controller and to register a plugin as this function is a festify plugin I just specify firstify register the function and then I have a couple of options I will use the prefix option this is a URL prefix I want my controller to be under the greetings route of its endpoints so as my only Handler right now is under the root URL and my entire controller is prefixed by greetings to access this new route in my controller let me just see okay I have a syntax error I have to export this function of course so I was I was mentioning here we have defined a controller under the root route but my entire control is prefixed under greetings so to access this endpoint now I cannot just open the root make a get request to the root domains I have to make a request to the greetings endpoint and as you can see my plugin is working and that's because I've prefixed all my controller methods with this prefix that's very useful in addition controllers are actually encapsulated so any modifications you make here will to the fastify server will not have an effect on the main runtime or other controllers that's extremely useful um by modifications I mean multiple things for which I'll talk about later but we can do decorators Hooks and other things all right let's add another method to our controller we had a method that was outputting um a parameter name parameter so let's do that as well it's in request param's name so now this will be under greetings let me see I actually want it under root name so that I can say Greetings jump and I get my endpoint hello John now it's recommended to specify at least the response schema why is that [Music] um let me first specify the scheme object I can do so as a constant up here because it's just an object response schema having a specified response schema will actually improve the fastified performance because it can serialize Json easier all right response to 100 I expect properties and specifically a message property of type string all right and I can use my response schema in both of my endpoints because they both return a message and everything is working the same way except again if I do not return a message I will get an empty object because message is not a required property if I make it required I will get an error let me see I have a syntax here somewhere okay required shouldn't be in properties it should be we needed yeah I get messages required if it's not required it will just not be serialized this is why um 35 will be faster if you specify the response schema so I would recommend at least specifying that although the request parameters request body is very good to have validated I would say required if you're building any API that is used by many users or of any significance whatsoever except training and learning so this is how you define a controller and also a fastify plugin and use it plugins are not the only extensibility option of fastify you can also use hooks hooks are code that executes in at a certain life cycle event in this case this code defines a new hook that executes on request this is a fastified lifecycle event we'll look at a graph of all lifecycle events of a request in fastify but essentially only request is the first hook that fastify executes after a request is made in this hook will execute some code which will specify in place of this comment and then go on with the other code of the request with the other code of any request in fast in your fastify server instance and this will be passed to all sub-components and plugins underneath this context now let's look at the application life cycle there are multiple hooks after every step in a fastifier request this is essentially a single HTTP request that starts with incoming request and ends with an outgoing response as you can see you basically have seven hooks you can use to do anything you want after each step and the first one is on request that fires after the router and instance Walker run then you have pre-parsing pre-validation pre-handler pre-serial serialization on Sand and a hook after the entire request finishes what this Hook is frequently used for is for example authentication with the Json web token or attaching a user object after Authentication picking of attaching a user object you would typically when you do authentication here whatever authentication with the Json web token well doesn't matter you would want to usually in some cases attach an object of user information to the request so that it can be passed to the next hand or whatever it is and to do that we can use what is called a decorator here's what a decorator is here we have a fastify hook that executes pre-handler this means if you remember the lifecycle methods that this hook will execute just before the user Handler which is the function or the function we specified to handle the request and this uh hook for pre-handler attaches a user object to the request and specifies just a string but in a real application that wouldn't be just a string it would usually include the user ID or the the name of the user in some cases if you need it the user email or other things and then it fires the done callback so that the hook terminates now if we look later in the get request because we have this free Handler for hook now in any request we actually have a user attached to the request which we do here and that's exactly what a hook is used for in fastify so why do we need decorators at this point I mean at hook basically adds this property and we can read it so why is this first line necessary fatified decorate request user empty string decorators are used to attach properties whatever they are to the native artifier request object or other object and they are necessary because if you don't use a decorator here this will deserialize uh basically the request object what this means simply is you'll get worse performance because fast if I would not know what the structure of the request object is anymore so in order to do this uh you're required to actually decorate your request that is if you want the best performance and you should always want it this is considered uh just the basic syntax of fastify you have to decorate objects in order to add custom properties to them with your data and that's what that's what decorators are used for we specify an empty string here to specify to fastify that this user object on the request will be a string if your property will be an object an array or something else you have to specify it as now this is just a specificity that you can read for in the documentation the fastified docs for decorators let's now talk about data access fastify has excellent plugins for data access one of these is fastify MySQL but we also have plugins for postgres mongodb radius level DB and you can find others as well these are the ones included in the official documentation and some of the most used databases so let's do a demo with one of these plugins specifically fastify MySQL it's what I've chosen to do a demo with this is the fastify application we'll be building so far and here on this uh computer I have a MySQL server running where I've prepared a simple database for this example I have a bookstore DB in my MySQL DB and a books table which includes uh just a table of ID title and author and I have four books here just for demonstrative purposes so how do we instantiate and use MySQL or in fact any basically fastified plugin to do so we have to install it of course um we'll install it with npm and that's 45 MySQL after it installs I will import it and we will use the same register function I'll just add a comment here that this is controllers database access code and I'll just do fastify register my plugin and then options for it classify MySQL uses the MySQL to node module here I can space it I have to specify the MySQL host which in my case this vocal host because my server is running on this machine and uh I have to also specify the user which in this case is root and a password okay I fetched the local MySQL password you would never store a production passwords in code you have to always use an environment variable a secret and there are many ways to store MySQL password or even authenticate your MySQL or database server in other ways this is not how you do it except when doing uh you know training and learning Etc this is easier in this case and this server is local only for development on this PC no one has access to it so this is perfectly safe in this case and we can specify the database which in this case is called bookstore and I will also set promise to true this will change the entire API of this plugin to promises and not callbacks which is very handy now I've registered this plugin and I can access it in my fastify object it's basically accessible under fastify MySQL now but to demonstrate this usage I'll make a new controller which I'll call the books controller because the database is a bookstore basically and again I'll Define a controller function which has a fastify options and uh done parameters I'll call done and exported by default all right now I will import this control right here and I will register it just like my greetings controller I will say books controller and I'll do the books route as is by restful best practices and let's um register a get endpoint on their books that will retrieve all books this is request reply and I will basically now retrieve all books to do so I will get the response from and this has to be an async function as I'll be dealing with promises in my MySQL plugin so to access the plugin I go to 45 MySQL and we have an execute method this execute method accepts unscale query which will in this case will be select everything from books quite straightforward and that's it in this case and I have to await this because it's a promise and the response is actually an array where the first item will be my books and in this case I want to return a reply that will include the books object with all of my books and that's how we do that let me see I have a syntactic error somewhere but where is that oh no not a weight an async function okay uh let's start my server again because it turned it off to install fastify MySQL no syntax errors let's refresh and now to get my books I should be able to do so under the books wrap and here we go again I need to specify the response schema because that's the best practice uh under 200 no sorry First Response 200 and then I expect books to be of type array and here in my hand door I will say an options object with the schema that will be responsible okay let's make a post request because so far we've only made get request bit stratified just to practice post to the same endpoint I want the I don't need this response schema exactly um request reply um in this case we would want book to be in the request body basically and we will make on MySQL request to fastify mySQL this time the query will be a little bit different we'll do an insert into query that will be books and we'll insert into title and alter these columns and the values will be here we use two question marks the execute uh MySQL function provides the Pro allows us to add additional values and this is important to use because otherwise You're vulnerable to SQL injection attacks and we will pass the title and the author essentially these values in the array will be will replace the question marks in the order you provide them and in the order you type the question marks and this should be a valid SQL query now this is also valid for the first schema we should have a try catch block because the MySQL function can always throw an error any database connectivity and in case of an error just return it it's a returnable object in fastify so that will be perfectly fine here also we will do a try catch book and in case of an error return it otherwise I will return a status 200 object just to indicate that everything is fine here we will Define a schema again I'll call that post schema and it will basically include uh a body validation this time which will expect the following properties we want a book object let me see yeah a book object in the request body um book of type object so book will be required and the response is quite straightforward all right so that should be the post schema let me see I have a syntax error required book yeah I'm missing a comma all right so this is my post request uh now we can test it basically to test it I'll use Postman because it's a post request and that's an easy to to test your post requests let me close this and make a new post request to my HTTP server HTTP not https books that's under Port 3002 and in the headers I will include contents hype that will be application Json of course and the body will be raw Json it will include a book object with title test book and with alter that will have the value of test author all right and if I send this request now I get a status 200 and if I check my SQL client I've created my book now because I have validation and schema if for example I don't have my book object I'll get an error which is pretty great um it says that we've created a controller with data access through MySQL which is great that's very useful if you're building a restful API with this I'll wrap this introductory course we learned what fastify is what separates it from other similar tools we learned how to create a fastify app how to create endpoints abstract away controllers work with plugins create a custom plugin and do database access we talked about Hooks and decorators these are the basics of fastify what makes fastify great is its extensibility and plugins which you can explore there are many plugins which will allow you to do a lot of things fastify is very complete and mature at this point and you can use it for your next restful API ensuring you have Optimal Performance if you like the content Please Subscribe in order to get updates when the next video is released take care
Info
Channel: NL Tech
Views: 8,953
Rating: undefined out of 5
Keywords: nodejs, programming, course, tutorial, software, engineering, software engineering, development, api, rest, web, graphql, express, koa, hapi, fastify, fastify.js, fastifyjs, koa.js, koajs, hapi.js, hapijs, express.js, node, es6, ecmascript, es7, es2022, controller, model, mvc, model-view-controller, server, http2, http, https, protocol
Id: btGtOue1oDA
Channel Id: undefined
Length: 36min 30sec (2190 seconds)
Published: Sun Sep 24 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.