Build a Fullstack App with Next.js, v2 Authentication Handlers
Transcript from the "Authentication Handlers" Lesson
>> All right, so now we're gonna start getting into putting all this stuff together and starting with authentication. So before we can actually make the authentication form and put it on the page and do all that stuff, we need the API routes, we need the functions that call the API routes.
[00:00:17] So when we submit the form, we can actually log in. So we're gonna move away from components and get into some logic. And we're gonna start working on some API stuff. So because it's a form, it's probably gonna be, what, a server component or client component. It's gonna to be a client component, exactly.
[00:00:37] So how do you fetch data on the client? How do you mutate data on the client? Fetch, yeah, nothing changes there. It's pretty much the same thing for now. So that's what we're gonna do. So inside of our lib slash API, call it lib, make a file, call it API.
[00:00:58] And I'm going to make a function just like my notes here called fetcher if you've ever used something like es WR or react query you're not you know this is not new to you just abstracting away the fetch function so you can reuse it Many times cuz it's kind of redundant to have to do all this stuff all the damn time.
[00:01:19] So we're gonna make our own fetcher, that way we can reuse it. So there's no wrong or right way to do this, this is just how I felt like writing it this time. [LAUGH] I change it all the time. So let's do that. So I'm gonna say, const fetcher, make it take an object here.
[00:01:39] So async. And it's gonna take in a URL, a method. What else do I have here? Body and whether it's JSON or not, so it takes a body. And if it's JSON or not, which defaults to true. And all this is gonna do is await, fetch with the URL here, with the method that you passed, like so.
[00:02:16] And if there's a body, you could do body and JSON.stringify the body. And fetch is okay if you add a body with nothing on it. I mean, I guess it really depends on your server. But if you didn't want to add the body field to this object, if there wasn't a body property passed as an argument.
[00:02:41] Anybody know a shortcut where you can do this in one line without having to take this object out in a variable and do an if statement? It's a little cool trick. So if I wanna exclude this body field entirely, if there is no body value the way you would have to do it, you typically you would do this, right?
[00:03:01] You would take this out, you'd say cost options, do something like that. Any like if body, then options dot body equals this, just like a couple of lines. But you could do it on one line too. And you could say dot dot, dot, and [INAUDIBLE] no, go away.
[00:03:24] You can do parentheses here. You can say, dot, dot, dot, if, and then you can say, body and an object, the body. So you can do that. What that would do is basically only spread over this object with the body property if body was true, otherwise nothing happens.
[00:03:49] Because and only works if both conditions are true. So this will have to be true.
>> Now why is this thing just freaking out, I wish it would stop.
>> Man, thank you. So annoying, there we go.
>> So it will take out the body object.
>> Yeah, so what this is doing, it's basically saying, add a body field and set it to body if body was true.
>> Otherwise, it won't even add the field. This will never happen if this isn't true, right? Cuz what's gonna happen is, let's break it down. This turns into true, and then it goes away.
[00:04:34] Then what's left is this object. Then this object has three dots on the left of it, what spreads it and adds a body field. If this is false, this whole statement goes away. So yeah, you do that and then obviously you just gotta stringify this thing. But, just something cool.
[00:04:59] I saw somebody do this a couple of years ago and I was like, I'm gonna steal that [LAUGH]. It's pretty dope. So you got body, what else? I got headers. You should always just make these like this. Just these should just be a default Accept Accept applicationjson. And then Content-Type.
[00:05:30] My goodness. There we go. And then lastly, you wanna be checked for errors. If not, rest out okay. Then handle your errors however you wanna handle them. There's no wrong way to handle them. I think I'm just throwing an error that might get caught somewhere eventually Otherwise, we can just return res.JSON or actually probably do.
[00:06:06] Yeah, if (json). If you are expecting JSON then I can say, data = await rest.json. And then all my APIs, I'll always send back a data property. So for me, it's always whatever this variable is dot data. Cuz every API route that I make, I always send back a data property to keep it consistent.
[00:06:29] I kind of got that from GraphQL. I really liked that that it's always a data property. If it's data, it's always an error property if there's an error. So I started making all my routes like that. Cuz I hate when you only just throw in the result of the database call in the route and you're like, what's the property on this object?
[00:06:45] And you gotta log it and it's just, what if it's always data? Then you can do things. It's way more predictable. So, I'll always just return data from my APIs. So this is always whatever dot data to me. Cool, yes.
>> I've seen Axios being used much less, at least in new projects.
[00:07:04] Do you have any thoughts on this?
>> I've never used Axios.
>> I've used it twice, and it's not because I don't like it, it's cuz I've never felt the need for it. Even when it first came out, I never felt the need for it. When Fetch came out, I really didn't feel the need for it.
[00:07:38] It didn't use Fetch, maybe it uses Fetch now. But unless I'm uploading images, I'm not using XHR, so I only wanna use Fetch. And I don't know what else it offers more than what Fetch does. And depending on how you use the Fetch or where you're using the Fetch, for instance, if we were using this Fetch on a server component, that thing has been hijacked by React and Next.js to have superpowers.
[00:08:03] I'm gonna use that thing, I'm not gonna use Axios. So yeah, no thanks, but it was a good project. Cool, all right, now we just need to make a function for us to register our users and a function for us to sign in. So let's do that. So const register is supposed to take in an object that's, we're just gonna call it user.
[00:08:35] And all its gonna do is just return fetcher or the URL of, let's just say /api/register. We didn't make that yet, but that's what we're saying it's gonna be. It's gonna be /api/register. And its method is gonna be a post. And the body is gonna be the user, hence JSON is true, it's always true, I don't have to put anything there.
[00:09:12] I'm gonna export that. Cool, now we got registered. And we're gonna do the same thing for signin, it's mostly the same. In fact, I'm just gonna copy it, paste it, change it to signin, Change the URL to slide, signin, and there we go, same thing. Yes?
>> So, why are we declaring these functions in our Lib rather than their pages slash API directory?
>> That's a good question. The question was, why we're declaring these in this Lib folder versus declaring the in their perspective components? The reason I'm doing it is because although you can do things in server, well, first of all, these are gonna be using client components and not server components.
[00:10:10] And I would say the top three reasons I would probably move them out is one, when it comes to writing tests, if this isn't a component file, now you gotta set up your test to handle components cuz you're gonna import it from a component file just to be able to get access to this.
[00:10:26] So maybe I just wanna unit test it separately. So that's one thing. Two, I want separation of concerns. Maybe that client component is just full of UI stuff, tell when classes, style components. And the last thing I wanna do is add all this stuff to it. And then three, not in this app, but another example.
[00:10:45] You might reuse this function in more than one place. It might not just be used in that one component, it might also be reused. Just somewhere over here on this page, there might be many points of where someone can register and not just that component. And you don't wanna be importing a component into another component just to get a function from that component.
[00:11:05] You could have just put that component in its own file
>> And to make sure we're talking about the same thing, Next.js is serverless API route like we would [INAUDIBLE]. Is that what you mean by components, is like pages in there?
>> No, actual component.
>> Were you not asking?
>> That's what I'm asking about.
>> Though, so, okay, we still have to make those APIs.
>> This is just the, are you saying, why do we need to fetch those APIs, why can't we just talk to them without the network?
>> So in my experience with an X12, I would maybe in their pages slash API make a register page, and that would have that functionality.
>> And [CROSSTALK] just hit that.
>> So why are we not doing that?
>> No, we are, this functionality is what's gonna hit it. This is the slash API that you're talking about. Yeah, we gotta go make this. So when I click that button on the form, it's gonna make a post request to that API to handle it, right?
[00:12:11] But what's the mechanism from hitting the button on the form to getting to the API, it's this.