
No Comments Yet
Be the first to share your thoughts and start the conversation.
Be the first to share your thoughts and start the conversation.
Complete source code available till this point of lesson is available at
export const AccountSchema = z.object({
userId: z.string().min(1, { message: "User ID is required." }),
name: z.string().min(1, { message: "Name is required." }),
image: z.string().url({ message: "Please provide a valid URL." }).optional(),
password: z
.string()
.min(6, { message: "Password must be at least 6 characters long." })
.max(100, { message: "Password cannot exceed 100 characters." })
.regex(/[A-Z]/, {
message: "Password must contain at least one uppercase letter.",
})
.regex(/[a-z]/, {
message: "Password must contain at least one lowercase letter.",
})
.regex(/[0-9]/, { message: "Password must contain at least one number." })
.regex(/[^a-zA-Z0-9]/, {
message: "Password must contain at least one special character.",
})
.optional(),
provider: z.string().min(1, { message: "Provider is required." }),
providerAccountId: z
.string()
.min(1, { message: "Provider Account ID is required." }),
});
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
In this lesson, we dive into creating route handlers for accounts in an API. The process is straightforward, building on previous functionalities established for users. The focus is to establish GET and POST methods to manage account data effectively.
route.ts
file.00:00:02 To get started with the route handlers for accounts, let's head over to app, API, and instead of users, now I'll create a new folder called accounts.
00:00:14 And within accounts, I'll create a new file called route.ts.
00:00:20 Within that route, we simply want to get all the accounts, and then we want to create a new account.
00:00:26 This will be very similar as to what we have in the users.
00:00:30 Get and post.
00:00:32 So you know what?
00:00:33 I'll actually go ahead and copy those two functions.
00:00:38 I'll paste them here and let's see what we have.
00:00:41 We have an exportAsync function get where we try to connect to the database.
00:00:46 We want to do the same thing if we want to get accounts.
00:00:49 We try to get the accounts, not the users.
00:00:52 So we can say accounts is equal to a wait.
00:00:55 account, which is a database model, dot find.
00:00:59 Next, we import the next response from next server.
00:01:02 And then instead of users, we simply pass over the accounts and we also import handle error.
00:01:10 I mean, just look at this.
00:01:11 This is it.
00:01:12 This is done.
00:01:13 I mean, I'm laughing right now because of how easy it is to implement it.
00:01:18 And once you fully understand how this works, it's going to be just super easy to spin up new APIs, new routes, route handlers,
00:01:25 and then call them later on within our frontend.
00:01:29 Let's see our post route.
00:01:30 Surely we'll have to change something here, right?
00:01:33 Well, the answer is yes.
00:01:34 The one thing that we don't have is the user schema.
00:01:38 Remember, there is a back-end validation, there is a validation for us using TypeScript, and then there's front-end validation for any action like creating accounts.
00:01:47 In a similar way of how we have a user schema, we also need to have an account schema.
00:01:52 It's going to be similar to what we have done in the signup where we had the password, email, and all of those validations using regular expressions.
00:02:00 And I really don't feel like typing out all of this by myself.
00:02:04 What you could do is head over to the account model and then ask ChatGPT to generate Zot validation based on this interface.
00:02:13 And you know what?
00:02:14 I actually might ask you to do so.
00:02:16 So I'll go here.
00:02:17 I'll open up the chat by pressing command shift I.
00:02:20 But again, you can totally just go into chat GPT and type it out there.
00:02:26 I'll say, create Zod validation, similar to user schema.
00:02:32 based on, well not based on, I'll say for accounts, based on the following TypeScript interface and Mongoose schema.
00:02:45 And now I'll paste that file right in.
00:02:47 And let's see what it comes up with.
00:02:49 It says add a new schema account schema for validating.
00:02:52 And there we go.
00:02:53 AI is doing its thing.
00:02:56 I'll accept the changes.
00:02:57 So we see what we have there.
00:02:59 It nicely got the user ID, which is a string, which is required.
00:03:02 It got a name saying name is required.
00:03:05 Same thing for an image, which has to be a URL.
00:03:08 Password, this is great.
00:03:10 Provider, yep, this is looking great as well.
00:03:13 And finally, a provider account ID.
00:03:15 All of this is looking great.
00:03:16 What you could do if you want to is add some additional validation for the password, like what we have in the signup schema.
00:03:23 So when you're creating a password, we have all of these different properties.
00:03:27 So you know what?
00:03:28 I'll actually go ahead and copy it and then paste it to override the existing password.
00:03:34 but I will set it as .optional because sometimes we might connect using Google.
00:03:39 So we don't need to have a password within the account.
00:03:42 Great.
00:03:43 Now, feel free to pause the screen and type it out.
00:03:46 Or you know what?
00:03:47 If you don't feel like doing that, I will just provide this right below this lesson so you can copy and paste it here.
00:03:53 With that in mind, let's go back to our route.
00:03:56 And instead of saying user schema.saveParse, now we can say account.
00:04:02 schema coming from validations dot parse.
00:04:06 In this case, we don't have to do any safe parsing because we don't have a password.
00:04:10 Then we can check whether we have an existing account by saying const existing account is going to be equal to account dot find one.
00:04:20 And we can find it by two different criteria.
00:04:23 One will be a provider.
00:04:25 So we want to check if provider is equal to validated data dot provider.
00:04:30 And the second one will be the provider account ID if it is equal to validated data dot provider account ID.
00:04:37 Next, if we don't have an existing account, in this case, we won't throw a general error.
00:04:43 Actually, we'll throw a new forbidden error because that means that an account with the same provider and provider ID already exists.
00:04:55 We can shorten this a bit and say with the same provider already exists.
00:04:59 After that, we don't have to check for the username here.
00:05:03 And if we don't end up in this error, what we can do is simply create a new account.
00:05:08 So say const new account is equal to await account dot create.
00:05:16 We're going to pass the entire validated data.
00:05:19 So no need to do the dot data afterward.
00:05:22 And then we'll return a next response success is true.
00:05:26 And then data is just going to be equal to new account with a status of 201. As you can see, we did have to make some changes,
00:05:35 but overall we're just following a pattern.
00:05:38 Great.
00:05:39 So that's it for the account routes.
00:05:41 Let's just remove these imports, which we don't need.
00:05:43 We are not using the validation error, the user schema, and the user model.
00:05:48 So looking at this diff right here is great because it shows us what we have to modify to add new routes.
00:05:54 We have to add the file with those routes.
00:05:57 We have to add the front end validations.
00:05:59 And in this case, we didn't do anything.
00:06:01 I just removed a comment.
00:06:03 So I'll say implement, create, and read account routes.
00:06:10 Commit, sync, and we're ready to move forward.
00:06:14 I can't wait to test all of these routes on the front end.