I have an API that in order to insert a new item it needs to be validated. The validation basically is a type validator(string, number, Date, e.t.c) and queries the database that checks if the "user" has an "item" in the same date, which if it does the validation is unsuccessful.
Pseudocode goes like this:
const Item = require("./models/item");
function post(newDoc){
  let errors = await checkForDocErrors(newDoc)
  if (errors) {
    throw errors;
  }
  let itemCreated = await Item.create(newDoc);
  return itemCreated;
}
My problem is if I do two concurrent requests like this:
const request = require("superagent");
// Inserts a new Item
request.post('http://127.0.0.1:5000/api/item')
.send({
  "id_user": "6c67ea36-5bfd-48ec-af62-cede984dff9d",
  "start_date": "2019-04-02",
  "name": "Water Bottle"
})
/* 
   Inserts a new Item, which shouldn't do. Resulting in two items having the
   same date.
*/
request.post('http://127.0.0.1:5000/api/item')
.send({
  "id_user": "6c67ea36-5bfd-48ec-af62-cede984dff9d",
  "start_date": "2019-04-02",
  "name": "Toothpick"
})
Both will be successful, which it shouldn't be since an "user" cannot have two "items" in the same date.
If I execute the second one after the first is finished, everything works as expected.
request.post('http://127.0.0.1:5000/api/item') // Inserts a new Item
.send({
  "id_user": "6c67ea36-5bfd-48ec-af62-cede984dff9d",
  "start_date": "2019-04-02",
  "name": "Water Bottle"
})
.then((res) => {
  // It is not successful since there is already an item with that date
  // as expected
  request.post('http://127.0.0.1:5000/api/item') 
  .send({
    "id_user": "6c67ea36-5bfd-48ec-af62-cede984dff9d",
    "start_date": "2019-04-02",
    "name": "Toothpick"
  })
})
To avoid this I send one request with an array of documents, but I want to prevent this issue or at least make less likely to happen.
SOLUTION
I created a redis server. Used the package redis-lock and wrapped around the POST route.
var client = require("redis").createClient()
var lock = require("redis-lock")(client);
var itemController = require('./controllers/item');
router.post('/', function(req, res){
  let userId = "";
  if (typeof req.body === 'object' && typeof req.body.id_user === 'string') {
    userId = req.body.id_user;
  }
  lock('POST ' + req.path + userId, async function(done){
    try {
      let result = await itemController.post(req.body)
      res.json(result);
    } catch (e) {
      res.status(500).send("Server Error");
    }
    done()
  })
}
Thank you.
 
     
    