Kinvey's BaaS currently doesn't support partial entity updates. So, if you want to update an entity in the MongoDB, you have to do the following:

  • Find the entity by some property
  • Update that entity's copy
  • Save the updated entity copy

It's really not too big a deal, but it is if you do it over and over. I decided to roll my own "partial update" custom endpoint. Here's the code for it.

function onRequest(request, response, modules){

    var collectionToUpdate = request.body.collection;
    var keyValuePairs = request.body.keyValuePairs;
    var id = modules.collectionAccess.objectID(request.body._id);

    // Initialize for use in later functions
    var entity;

    if( ! id ) {
        return response.error('An _id was not provided');
    }

    if( ! keyValuePairs || keyValuePairs.length < 1 ) {
        return response.error('keyValuePairs is required');
    }

    /**
     * Notify that processing is complete.
     *
     * NOTE : Any desired response body should be set elsewhere
     *
     * @returns {boolean}
     */
    var sendResponse = function() {

        return response.complete();

    };

    /**
     * Walk through each of the keyValuePairs to update the entity fetched from the db.
     */
    var updateEntity = function() {

        keyValuePairs.forEach( function( keyValuePair ) {

            entity[ keyValuePair["key"] ] = keyValuePair["value"];

        });

        saveEntity();

    };

    /**
     * Save the modified entity to the database.
     */
    var saveEntity = function() {

        modules.collectionAccess.collection(collectionToUpdate).save(entity, function( error , success) {

            if( error ) {

                return response.error('Failed to save entity');

            }

            // Saving just returns 1.  So, send back the updated entity.
            response.body = entity;

            sendResponse();

        });
    };

    // Get the entity from db  based on the _id
    modules.collectionAccess.collection(collectionToUpdate).findOne( {"_id" : id}, function( error, retrievedEntity) {

        if( error ) {

            return response.error(error);

        }

        if( retrievedEntity === null ) {

            return response.error('No matching entity found.');

        }

        entity = retrievedEntity;

        // Update the entity
        updateEntity();

    })


};

Then, to update it send all the required info like this:

{
	"collection" : "NameOfCollectionGoesHere",
	"_id" : "TheIdOfTheEntityGoesHere",
	"keyValuePairs" : 
		[
			{
				"key" : "TheNameOfTheFieldGoesHere",
				"value" : "TheValueToUpdateToGoesHere"
			}
		]
}

Here's an example:

{
	"collection" : "FamilyMembers",
	"_id" : "xxxx62cxxxxfcbf4xxxx7bfd",
	"keyValuePairs" : 
		[
			{
				"key" : "nickName",
				"value" : "Bobby"
			}
		]
}

Let me know if you have any suggestions on how to improve this.