
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
How did you manage to remove the blur property and reach here?
Upgrading gives you access to quizzes so you can test your knowledge, track progress, and improve your skills.
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 explore how to implement dynamic API routes for managing users, specifically focusing on fetching a user by ID, deleting a user, and updating user information. The implementation involves setting up appropriate routes, handling requests and responses, and connecting to a database to perform the required actions.
async
functions to handle GET, DELETE, and PUT requests for user management.00:00:02 Let's implement the dynamic API routes.
00:00:06 Specifically, get user by ID.
00:00:09 We can do that by heading over to API, users, and then creating a new folder with square brackets ID.
00:00:18 And within it, let's create a new route.ts.
00:00:22 Here we can create a new export async function, get, you already know the drill.
00:00:30 And we need to extract the params to get the ID.
00:00:34 So the first parameter is always the request, and the second parameter is the response.
00:00:39 So for the request, we can say that we don't need it right now.
00:00:42 So we can do just an underscore.
00:00:44 And from the response, we can actually extract the params.
00:00:49 And then we can say that this is of a type.
00:00:51 Params is a promise.
00:00:54 which is going to contain an ID of a type string.
00:00:58 And that's going to look something like this.
00:01:00 Next, we can destructure the ID from the params by awaiting the params, because it returns a promise.
00:01:08 And then if an ID doesn't exist, so if there is no ID, we want to throw a new not found error, coming from lib-http-errors,
00:01:19 and we'll pass a string of user, which means user not found.
00:01:24 After that, if we do have an ID, we can open up a new try and catch block.
00:01:29 In the catch, we'll return a handle error call to which we're going to pass the error and specify that this is an API call as API error response.
00:01:41 And in the try, we can await and try to connect to the database by calling the DB connect.
00:01:48 Once we connect, we can extract the user by saying constUser is equal to awaitUser, referring to the user model, dot findById,
00:01:59 which is another one of the methods we can call, to which you can simply pass the ID.
00:02:05 This would be the same as trying to do find one and then passing an object where you're searching for the underscore ID and then pass the ID.
00:02:14 But if you already know that you're searching by ID, you can simply call find by ID and pass the ID as the only parameter.
00:02:21 Next, if we don't have a user, we can say throw new not found error user.
00:02:26 You can see how convenient this is.
00:02:28 Finally, if we do have a user, we can return a next response dot JSON.
00:02:35 to which we'll pass a success is equal to true, data is equal to user, and as the second parameter, we can pass an object of a status of 200. And this
00:02:49 is it.
00:02:49 This is our getUserById.
00:02:52 So we can write that right here.
00:02:53 or you can write it like this, get API users ID.
00:02:57 We can now test that endpoint by going to our API routes tester, by copying the ID of the previous one which we created,
00:03:05 that's this one right here, and then making a GET request to localhost 3000 API users.
00:03:12 We already have that implemented, it should return 1. But if we go to forward slash users and then forward slash this specific ID,
00:03:21 of course, if I could copy it right, I think I'm having an error right here with my font.
00:03:25 But if you get the entire ID right, it should look something like this, users.
00:03:30 And then you paste the entire ID of that user, go to send.
00:03:34 And there we go, we got a 200 with the data containing the data only of that user.
00:03:39 Great.
00:03:40 That means that getUserById works.
00:03:42 Now, what are the other two dynamic routes for the user?
00:03:46 One was get, the other one will be delete.
00:03:49 And the third one will be put, which means update.
00:03:53 So let's say put API user's ID.
00:03:56 Let's start with the delete.
00:03:58 It's going to be similar to the git.
00:04:00 So you can see that copilot will autofill it for me.
00:04:03 We get the request and the params.
00:04:06 Params include the ID.
00:04:09 If there is no ID, we throw a new not found error.
00:04:12 If we do have an ID, we try to connect to the database.
00:04:16 Then we try to find the user by saying await user.
00:04:20 And check this out.
00:04:21 This is a method given to us by Mongoose called find by ID and delete, which does exactly what it says.
00:04:28 It tries to find the user by ID and deletes it.
00:04:32 Finally, if there is no user, then we can return a not user found.
00:04:35 But other than that, if we reach this point, it means a user has been successfully deleted.
00:04:42 So we can return true and data can return the data about the user that was deleted.
00:04:47 This is useful when you want to say something like user Adrian successfully deleted.
00:04:52 And we can return a status of 204, which means deleted.
00:04:55 If you're wondering about what all of these status codes mean, simply Google it and you'll see all of them right here.
00:05:02 For example, 204 means no content.
00:05:03 201 means created.
00:05:08 300s are redirects, 400s are client error messages, and 500 are server errors.
00:05:14 In this case, we are returning the deleted user so maybe a 200 would make sense as well.
00:05:19 Later on, we will expand on this delete function to also delete everything that that user has ever created.
00:05:25 Right now we cannot do that because we don't have any questions, but questions later on will be additional documents that that user can create.
00:05:34 So once we delete the user, we have to delete everything they have created as well.
00:05:40 So we'll definitely get back here.
00:05:42 But finally, let's implement a put functionality as well by saying export async function put where we get a request.
00:05:53 I'll actually use the full request name right here.
00:05:55 Then we get the params.
00:05:58 We await the ID, and if there is no ID, we throw a not found error.
00:06:04 If everything's successful, we try to connect to the database.
00:06:07 And then in this case, this is already pretty good, but it looks like Copilot forgot to validate the data.
00:06:15 And that's definitely something I want to do.
00:06:18 So I'll say const body is equal to await request.json to get access to the data.
00:06:25 Then we want to validate it by saying const validated data is equal to user schema.
00:06:32 So same as when we were creating that user dot partial.
00:06:36 In this case, we can include partial data, not everything.
00:06:40 and then dot parse to which we send the body.
00:06:44 Finally, we can try to update the user by saying const updated user is equal to await user dot find by ID and update.
00:06:56 Again, super descriptive.
00:06:58 To this one, we pass the ID as before, but this time we also have to pass the validated data, because the app needs to know what are we updating.
00:07:08 And finally, we can pass the object of new is set to true.
00:07:13 And why are we passing this new?
00:07:15 Well, that's because by default, find one and update returns the document as it was before update was applied.
00:07:22 But if you set new to true, it will instead give you the object after the update was applied, which is exactly what we want under this updated user.
00:07:31 Finally, if no updated user is returned, we're going to throw not user found.
00:07:38 And at the end, we want to say something like next response, success true, data is the updated user, and the status message is 200. And the reason that
00:07:48 I just accept everything that Copilot gives me is because as you can see, a lot of this is just boilerplate.
00:07:55 We want to get access to the request and the params.
00:07:58 We want to await the params, throw the error message, connect to the database, and then perform the action, and finally return the response.
00:08:07 So I hope this makes sense.
00:08:08 We're still writing it all by hand, but we're just leveraging the auto-completions when they come in handy.