I
I
Ilya Gerasimov2017-09-06 03:08:10
JavaScript
Ilya Gerasimov, 2017-09-06 03:08:10

How to correctly control the incoming data before inserting/updating into the database?

I don’t know how else to call the topic, I don’t know what to do and why it happens, maybe I just don’t understand something (I just recently started trying nodejs), consider the problem on a simple user registration, a piece of code:

const register = (req, res, next) => {

  const { name, email, password, passwordConfirmation } = req.body

  async.waterfall([
    cb => {
      bcrypt.genSalt(10, (err, salt) => {
        if (err) return cb(err);
        bcrypt.hash(password, salt, cb);
      })
    }
  ], (err, results) => {
    if (err) {
      logger.error(err);
      return ...
    }

    User.findOne({
      where : {
        $or : [
          {name},
          {email}
        ]
      }
    }).asCallback((err, model) => {
      if (err) {
        logger.error(err);
        return ...
      }

      if (model && model.name == name) return ...name already exists
      if (model && model.email == email) return ...email already exists

      // create user
      User.create({
          name,
          email,
          password : results,
        }, (err, model) => {
          if (err) {
            logger.error(err);
            return ...
          }

          // done
          return ...
        })
    })
  })
}

The problem is the following, with 2 simultaneous requests with the same data, the first one will be successfully created, the second one will throw an index duplication error, because despite the check for the existence of name / email, the check request is performed before creating 1 user. I can solve this problem by wrapping this operation in some kind of queue and registering all users strictly in turn, but is this correct?
1e876fd7bd684961aa87bc43ec074094.png
It turned out to reveal this with small stress tests, for the sake of interest, I went to prod, registered 2 requests in the console, poked enter, saw the same thing in the logs ... And I would probably score on this if I didn’t have places in the code where existence checks something a little more important than here, but this is the simplest example.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
I
Ilya Gerasimov, 2017-09-11
@Omashu

I did not find good advice on what to do with conflicting requests, but for now I use transactions, maybe it will help someone.

O
oh, 2017-09-06
well @AnneSmith

so why do you create a user in the database if "name already exists" or "email already exists" ?
there you need the same return and the output of a message to the user like "nice try" :)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question