2

So I'm creating a REST API, and when someone calls a method to return data I get the data from an external API, check if the ID of the data already exists and if it does, update it, and if not create it.

The problem is that if another request were to come in for the same resource, my function looks up the data, and finds that it does not exist (yet), however by the time it's got to the save call, the save from the previous function has completed, so the save fails (some fields must be unique).

I've currently setup a queue using nodejs async and a single worker. This works however I think it's really going to cause performance issues!

Does anyone know how I can do this in a way thats not going to cause performance issues?

var storeData = function(APIResponse, id, callback){

  Record.findOne({ id: id }, function(err, data) {

    if(data === null) {
      //No record, so lets create one

      var data = {};
      data.id = id;
      data.title = APIResponse.title;

      var dataToSave = new Record(data);

    } else {
      //data exists in store, lets update it

      data.title = APIResponse.title; //Update title
      var dataToSave = data;

    }

    dataToSave.save(function(err, doc) {
      if(err) {throw err;}

      //A callback to continue with some other processes
      callback(null, APIResponse, doc);

    });
  });

};

Any ideas/suggestions would be really appreciated, Many Thanks

6
  • In your REST call what do you pass into id if you assume data creation? Commented Dec 11, 2014 at 15:01
  • Literally a unique ID for the resource. (e.g. 10191). The idea is that the data is cached for later on Commented Dec 11, 2014 at 15:03
  • But how do you know ID if you are creating a new item? Do you pass null there or some special string or what? Is it always an ID? Commented Dec 11, 2014 at 15:07
  • The REST call will always have an ID attached. So the user may search for this resource and when they select it, the call will contain the ID that is fetched from the external API. (I know the ID because i get it from an external API call that happens beforehand.) Commented Dec 11, 2014 at 15:11
  • 1
    Ah, understood. Did you have a look at this answer? stackoverflow.com/a/16362833/970721 Commented Dec 11, 2014 at 15:18

1 Answer 1

1

Why not just upsert?

var storeData = function(APIResponse, id, callback) {
  var record = {
    id: id,
    title: APIResponse.title
  };

  Record.findOneAndUpdate({ id: id }, record, { upsert: true }, function(err, doc) {
      if(err) { throw err; }
      callback(null, APIResponse, doc);
  });
};
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Timothy, this is what I ended up going with!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.