Next.js with a separate server - good idea?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
next JS is a full stack framework so we get both a client side as well as a server side so on the client we have client components and on the server side we have server components these days server actions as well as route handlers these are basically your traditional API routes and with any of these three options that you have on the server side you can do the traditional server side tasks you can access your database and any of these you can receive web hooks with these route handlers so you can process payments update your content from your CMS you can even use next Js just as your traditional API server with these route handlers you can also SSR your pages Etc so it covers most of the things that you would want to do on the server side and if you have a simple project that's probably enough but I found that in the real world if you're building a serious project pretty much always at some point you need a separate server a custom back end and in fact you may actually already have a custom server and you're thinking about moving to nextjs but you don't want to leave your already existing server behind you want to keep it that way and so you may have an architecture like this where you have your nextjs app which is basically this entire party is one next s app and then also a custom Ser maybe an Express API maybe PHP Ruby go python pick your flavor but even if you don't have a custom server yet you may still want that in fact you may need it at some point because some of the things you simply cannot do on the server side of a nextjs application because when you deploy it to for sale for example what you get is essentially a bunch of serverless functions behind the scenes right so your pages will be pre-generated as much as possible so you get a bunch of static assets like HTML files but anything that requires Dynamic compute will be mapped behind the scenes for you on forel to a serverless function and that's different from your traditional server which is what people call a long running server so this one will be running even if there are no requests it's still running and that's the downside of them you're paying even if you're not using them but serverless functions you're only paying for what you use and there are other benefits as well but there are also downsides with these serverless functions for example any task May simply not be able to run on a serverless functions so for example if you deploy to forel and you are on the hobby plan a free plan you can actually only run task take at most 10 seconds so if it takes longer you'll get a timeout error now if you upgrade to the Pro Plan by default it's going to be 15 seconds but you can actually maximize this all the way to 5 minutes which is already substantially more than what it used to be but there will still be some tasks that are going to be too long for that for example I was actually building a startup which was rendering videos I was using the remotion library that allows you to create videos with react so what this will do is it will stitch together the video but it may take some time may take you know if it's a longer video may take 20 30 minutes so I cannot run that on the nextjs back end I need to do that on a separate back end so I created a separate nodejs server for that and there are other tasks as well like web scraping that may simply take too long also if you have background tasks or like a a job queue or Chron jobs this may not fit properly within a next next as backend this may be more appropriate to spin out into a separate server as well also the way that serverless functions work is you essentially spin up a lot of them as more and more requests are coming in and they all will make a connection to the database in case you're accessing the database so you may actually also run into issues databased connections to many of them you need to manage the pool of connections they also suffer from cold starts because you're only paying for what you use so as you don't use them they're not going to be up and running that means that once you do start getting requests again may take some time before they're up and running and it could be a little bit slower in the beginning now it's not a huge problem it affects a small percentage of the total amount of request but still something you may run into you also don't have a persistent file system so these serverless functions they don't share the same file system so that means if you're using SQL light for example which is essentially just a file it's part of your file system you cannot use that when you deploy it to forell or if you're just using a Json file to manage data that's not going to work and there are other things as well like websockets that may not really work out of the box in a nextjs back end now some of these things can be worked around but it's just not ideal to put this in a nextjs backend you can technically also host nextjs yourself so you can actually also run it on a long running server it does have more complexity and you may lose some features that could be an option that solves it for your particular use case but most of you will just simply want to have a separate custom server because there are other benefits to that as well for example if you have a custom server you can pick the best tool for the the job so if you have a project that has a lot of machine learning or AI or data processing you may want to use Python because python is more popular for data science type of work or maybe you want to use go for performance or maybe your developers simply have expertise in a different technology so why not use that expertise you can pick any technology you want for this separate server with nextjs you have to use JavaScript or typescript also what if I make a mistake in one of my backend features harm the entire app in nextjs but a custom server if I make a mistake there well it's just it's isolated to just that service we can also deploy this independently of the rest of the application with nextjs if you make a change in a server action or in a server component or route Handler you have to redeploy the entire app imagine you actually have separate teams of people working on the app you're all working in the same app whereas with a custom server you can actually have multiple custom servers and each team could be working on one of them so you get all of these benefit right so I should also put here this is simply a more ergonomic setup I think if you have different teams working on the same project now if you have a background in microservices you probably recognize all of this I'm essentially rediscovering the benefits of having a microservices architecture now you may just want to have one custom server next to your nextjs application and you can still deploy this to for sale by the way so you can also deploy node.js or Express API to for sale now the biggest problem you're going to run into I found was authentication actually so there are solutions to add authentication to the nextjs application but how does that work if you also want to have let's say a separate API server and those API routes also need to be protected so what we want is that if we make a request from our nextjs server site to our custom server we need to be authenticated So This Server site will need to send some token let's say to our custom server custom server can then verify that the token is valid and we may actually also want to send requests directly from the client side to the custom server as well which then also should have a valid access token and what we of course also want is simply within our nextjs app our nextjs server sign may actually also do things like access the database and that of course should also be authenticated so here of course also the client when it sends requests to the back end we also want to make sure that only authenticated users can do that so I'll quickly show you how to do that I'm going to use kind I'm a brand ambassador for kind they have a wonderful solution for authentication and it's free up to 10.5k monthly active user so we have two things here we have the entire nextjs application we can use the nextjs app router SDK by kind and then we have let's say a separate Xpress API server now K actually also has an SDK for that but we only need the app router SDK to create a token and so on and then we can reuse that token to make authenticated requests to our separate server so we don't need both sdks we only need one now I like using the nextjs app router SDK because it also helps us with some utilities on the the client now just to show you how you could set that up in a folder structure right so here I have an API folder where I put my Express API server so all of the express API server stuff goes in here then I have a web folder for my entire nextjs app right so my entire nextjs app just as you would normally use it is all in here and then you can also have a shared folder right so if we have a database here of course my nextjs server site needs to access the database but my custom server may also need to update the database right so here in the shared folder you may have some database related things that you can use in both your custom server as well as in your nextjs application so let me show you the nextjs application as it is right now so here is my nextjs application you can see it's just a pretty standard boiler plate here if I open up the source and if I go to my homepage here I just have this sample app welcome to stock prices and here is what you would see this is the homepage welcome to stock prices log in to VI stock prices and new so let's say we have a dashboard route that should actually be protected where you can view the stock prices and the news right now if I go to/ dashboard I can just go there I'm not authenticated we have zero authentication right now and that's this page here under dashboard you can see here I have my dashboard page and this is the home page this should be public but this should be private so this is all just nextjs right so if we go back to the diagram here what we're doing here is we just have two pages those are actually server components in xjs so those two pages are just here so what we want to do is just protect this first so we we can just use this one app router SDK so in the dashboard I can register my application here with kind I can call that stock prices now next JS is actually considered here a backend web application and then here we have a quick start I will just pick nextjs of course all right now we already created an App so it's existing codebase where is your project running so this is something you need to pay attention to if you have multiple apps running if you would run your Express server let's say on Local Host 3000 then your next GS app is probably running on some other server I am actually running this on Local Host 3,000 I need to set these call back URLs boom boom I need to install this package I already did that I need to add my environment variables right so here in my nextjs application I have .lo I'm going to paste that right here all right let's see all right now within nextjs we also have these route handlers right so your API routes essentially this is all just within nextjs has nothing to do with our custom server we do need to add that here as well so I will copy this path and then here I can create a new folder and then in there we need route. JS and I will just copy this and paste that right here right this is just a bunch of setup all for our nextjs application okay and that should basically be it now we can add sign up and sign in buttons so here what we want to do of course is we want to protect this page the user needs to be signed in so let's actually try protecting this before we add sign in and login buttons so if I go to the dashboard page this is a server component in kind if we want to protect this we can do it right in the server component or we can create a middleware file right middleware also only runs within our nextjs application has nothing to do with our separate custom server so they also show you how to do this with middleware so you can easily protect many different pages in one go so in next this is all all within next JS right so here I would create a middleware dots file and then here I can determine which pages should be protected so here we only want to protect the dashboard page we could do it manually for each page as well with get kind server session I have a complete tutorial on kind so check that out so here middle where right now I'm just protecting dashboard so if I do this I'm not logged in so you can see actually automatically when I try to go there we actually already have a redirect there so if I go to the homepage this is still public if I try to go to dashboard we should be redirected to the login page hosted by kind now it will say something about not being able to authenticate because we haven't decided yet how the user should be able to authenticate so if we go to our application here we can decide how the user should be able to log in maybe with their password passwordless with their phone I'm going to use GitHub here and I will save that right here all right successfully saved if I just try accessing dashboard now again I'm not logged in so automatically I will be redirected to the login page and now I can log in with GitHub I haven't created an account yet so it will prompt me to create an account and now after logging in with GitHub I'm redirected here to dashboard so now I'm logged in and you can see indeed I have my access token here now this is all within nextjs now of course we want to make these requests to our custom server which is also going to be protected and we need to send along this access token to there so we have now protected our nextjs application there are there are many other things we can do here but you can see now when I want to access a particular page that should be protected which is just a server component actually in nextjs and when I try to go there without being logged in I'm automatically redirected to kind and after login I can actually access that pit so now we have set up authentication for our nextjs application but now what if we have a custom server let's take a look there I'm going to close out of this I'm going to close the web folder here let's say we have an Express API server and in here here we have well let's see we have a setup for very simple Express server and so course is of course one of the things you want to take a look at I'm just going to allow everything here and but here we have an API route and here we have API protected and let's say this holds some protected stock prices data how do we make sure that only logged in users can access this API route or at least get back a response with this only when they're logged in so what we're going to do is we're going to make a request from our nextjs server back end to our API route here and then we'll also try to do it directly from the client as well let's try doing this let's try making a request somewhere from our nextjs back end to our API server here so let's see let's go to our nextjs application as well our dashboard page is a server component right so this is server site right so if we look at the diagram one more time that's a server component that's running within the nextjs server site now from here we're going to make a request to that APN R so in the server component if you watch my channel you know that we can do async A8 directly in here without using effect I can make a fetch call directly in the function body here right and we get a response from that so my nexts application is running on Local Host 3000 but the API is running on 3001 and the route to there was API protected so this hopefully gives us some response and let's actually try logging that so console log data and let's see what we get so here on the left side I have my nextjs app running on the right side I have my Express API running remember this is a server component so if you log something you need to open up your ter Al it's not going to be in the browser tools that's client component and actually you can already see I get a message here this is protected stock prices data now how is that possible because I'm not passing along any token so right now this is not protected this API route here is just sending this back to whoever makes this request so if we want to protect this API route we can very easily do that with kind as well so kind actually also gives you a Json web token fifier that you can use here as middleware I can actually just import this from kind's other packet which is called kind note Express the only thing we need from here is actually just this utility they have to verify Json web tokens so here I can then create the middleware we use the imported Json web token verify and here you need to give the domain that you used with kind so this is going to be something like this it's kind's domain but it's going to be your own name in the as the subdomain here now there is something called the audience claim as well that we want to verify and we'll talk about it in a second for now I will just leave this empty this middleware when there is a request coming into this route it will go through the middleware first and it will pull out the request headers and specifically it's going to look for a bearer token you can do that manually as well right so you would do something like request headers authorization and you can grab you can grab the beer token from the incoming request like this yourself and then verify it yourself however here it's a bit easier it will do all of that for you you just plop it in there so now when I try to access that API route like this from our own nextjs server let's see what happens I just need to invoke this and again let's go to our dashboard page so that it will run again now if you keep making request it may seem that you can still access the API route even though we are not passing along the access token so how is that possible well actually it is not possible nextjs actually caches This Server component so if you invoke it again it may actually use a cache from before so that's why we get the same results here so what I like to do is sometimes you kind of have to delete this next folder here so if I delete this and if I just restart the server here the nextjs server now it's restarted if I now invoke This Server component again if I refresh here let's see what we get see so yeah so now you can see we indeed get something here with forbidden and actually here in our Express server we also see something here so here you can see Json web token parse error empty Json web token so we're not passing along any Json web token and so what this middleware will do it will return a response saying for a one error forbidden right so that's why now we're getting this error here so now we have protection in place here on our custom server you need to f a token now right so now when we make a request here and we don't have that we get that error so now of course we want to send that along right so and actually my co-pilot wants to get it from local storage which is not possible because this is a server component there is no local storage but how do we get the access token here then well on the server side anywhere on the server with kind you can use get kind server session so this allows you to get the excess token on the server side all right and actually I just need to add the at in front of it so here we get all sorts of things now what we want is to get the access token but we don't want it in decoded format because we want to send this along so here we want to get the raw access token so then here we get the access token we now that's a function so we do need to call that to get the actual token get access token raw so then here we get the actual access token which we can then pass along right so here we just plop this in there now if I save here now we are passing along the access token to our server and let's actually try logging the access token to double check that we actually get an access token here I will comment out the actual fetch call for now so here of course we need to await this so This is actually a promise and if we do that and now save you can see we are indeed getting this raw access token right so here you can see it's not decoded that's what we need to pass along the API server right so now I'm passing this along as the access token here and now you can see it says something about this is protected stock prices data so now if I go down here on the express server as well you can see we get a message here token is valid so now we have successfully made a request from our own nextjs backend to a custom server which is still protected all right so now what do we want to make a request directly from a client component to this custom server well it would be very similar so let's actually turn this into a client component we can do that by just adding use client typically not recommended for the entire page of course but let's see if we can change this a little bit to so this is not going to work so get kind server session that's all for Server sites whether it's server component server action route Handler that doesn't work on the client side so we can also not make this async so what we can use on the client side is use kind browser which gives us similar things here on the client so here we get access to all of this right so we have all of these properties here now what we want is again get access token not the decoded one the raw one because that's what we want to send along just to quickly log this to the console now we actually need to take a look in the browser so if I refresh here let's see we see access token raw and here you can see now we have our access token on the clock now if we make a fetch call to our API server let's say we're doing some old school fetching with use effect well you would end up with something like this so here you have you would create a function get data so here we would make a fetch call again to same route we pass along the token as part of the authorization header and we will log the actual response so if I save here and now if I scroll up a bit Yeah you can see here I get message this is protected stock prices data so we got a valid response here and indeed here we also see here from the Express server that the token was valid so we use the nextjs SDK it will give us a token and then we can just pass along the token to our custom server which is protected with middleware that's also coming from kind now there's one more thing that we can do to make it safer which is to also work with the audience claim because it's just checking if the token is valid right so when we log in with the next chance SDK it will give us some token but can we just use that token everywhere well no we want the token to only work for this specific custom server so you can use the audience claim for that so in kind I can go to settings and all the way here at the bottom there's API so you can register your apis with kind and actually I already did this so typically in a Json web token you would then see the audience claim typically it's a URL but it's not going to be called or anything but it's just typically a URL since my Express server is running on Local Host 3001 that's what I would use to make it work with the audience claim we do need to add this environment variable here so it needs to be the exact same as how you registered is in your Cent dashboard so this token that's going to be created is going to be meant to be consumed by our API server which is locally at least running on Local Host 3001 and then I want to connect this API to this application nextjs application I have here so very easy to do just one click boom now the separate custom server is sort of connected with my nextjs application so the next time that a token is created in that token there will be an audience claim so let's actually do that let's go back to our application here I'm going to log myself out uh kind of course has login log out buttons as well I have a complete tutorial on kind like I said so here on the dashboard page we could have a log out and I will import that and we will say something like log out okay so we need to click on that so here if I make this a little bit bigger you can see log out if I click on that you can see my cookies are going to become cleared on the homepage we might as well quickly add some login and register buttons as well login link and there's also a register link very easy so now here I can click on log in to log myself in and get a token again I'm going to log in with GitHub again all right so now I'm back in the dashboard page now I have a new token and of course it's encoded here but if we actually decode it here decoded access token so we can see the audience claim so if I save this here here you can see now I have an access token all right so now here when we log this here I get the decoded access token you can see in the audience claim there is now this URL for our API server so this token is meant for this URL that's how you can view it so then here on the API server here we also we have this audience option here and we can specify that we only want to allow tokens that explicitly have that Local Host 3001 in the audience claim so then here when we make request let's see if we can still get the data so I'm going to refresh here and you can see I'm still getting the data here so now this is protected even better there may be other checks that you want to do here like check for the Scopes but that's a topic for another day this was an example of how you can set up your architecture with a custom server next to your nextjs application in including authentication which is which is typically the hard thing to do right in a setup like this but you can see with kind that's very easy to solve so I'm Wesley I'm a brand ambassador for kind so they are sponsoring me but even if they weren't I would still use their solution for my own nextjs applications because authentication is just very hard to do properly yourself especially once you start deviating from the standard path hopefully you found it an interesting video thanks for watching and I hope to see you the next one have a nice day
Info
Channel: ByteGrad
Views: 43,641
Rating: undefined out of 5
Keywords:
Id: C5NnVfbNpq8
Channel Id: undefined
Length: 22min 53sec (1373 seconds)
Published: Mon Mar 25 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.