36. Creating users

In this video we going to take a look at an endpoint I've created for adding new users.

I've just got the basics done for this one; I haven't added authentication or any other juicy stuff that we'll be doing in this module.

You may recall in the 3rd module we set up this user model and validation.

You'll see I've also now added a new router file at server/routes/users.js, and also a new controller file at server/controllers/user.js.

I've also added the user router file to our Express server. I've made it so that any user routes routes we added will be prefixed with the path "/users", exactly like how our item routes are prefixed with "items".

server/index.js

app.use("/users", require("./routes/users"));

Controller method

Let's take a look at the controller method which I've named create. This is the method that will be used to create a new user.

So, the client will send the user name, email, and password as JSON in the body of a POST request.

We can pass req.body directly to the User model.

Next, we'll try and save that user model. If it succeeds, we send the user details back to the client.

If the save fails, as it might do if model validation fails, we send a 400 Bad Request status.

We also send back the error object in the response body, that way the client can then parse this error object to find out why their request failed.

server/controllers/users.js

const User = require("../models/User");

exports.create = async (req, res) => {
  const user = new User(req.body);
  try {
    const doc = await user.save();
    res.send({ user: doc });
  } catch (err) {
    res.status(400).send(err);
  }
};

User route file

Let's now take a look at the router file which I've only partially created.

At the top we're requiring Express, and create a new instance of our router. We also require the users controller.

Finally, we export the router so that it can be required by another script.

routes/users.js

const express = require("express");
const router = express.Router();
const UsersController = require("../controllers/users");

module.exports = router;

Responding with controller

To complete the POST /useres endpoint, let's now call router, and add our first route by calling the route method and passing in the root path, which will be mapped to the /users path.

In order to create a new user, we want the client to make a POST request with the user's name, email and password to the root path.

So let's call post now, and pass in our controller method.

server/routes/users.js

const express = require("express");
const router = express.Router();
const UsersController = require("../controllers/users");

router
  .route("/")
  .post(UsersController.create);

module.exports = router;

Smoke test with Postman

Let's now do a smoke test with Postman. So let's create a new request and call this one POST /users. We'll give it the request URL {{url}}/users.

Now, let's add a body, being sure to set the data type to raw and the content type to JSON.

For our first smoke test, we'll provide valid data here, meaning a name that's at least 2 characters long, so I'll put "Anthony"; we'll need an email that is a valid email and is unqiue, so I'll put "[email protected]", and a password of at least 6 characters, so I'll put "test1234".

{
  "name": "Anthony",
  "email": "[email protected]",
  "password": "test1234"
}

Make sure your server is running, and let's send this request off. We can see a 200 response with the new user's details iin the response body.

Sad test

If we keep the data the same and send off the same request again, we'll get a 400 status back. If you look at the error message, you can see that this is because we have a duplicate email i.e. we've violated the unique constraint on our model. In this case, that's a good thing because it confirms our validation is working.

So let's now save that new Postman request to our collection.

And with that, we can see our POST /users route works now, though we still have a whole bunch of things we want to add to it, like we want to hash our password rather than store it in plain text and of course we'll need to add our authentication headers, which will be the topic of the next few videos.

Discussion

2 comments