Component Behavior Standards

Upsert Object

Iteration 1: Upsert Object By ID

Config Fields
  • Object Type (dropdown)
Input Metadata
  • One input per field in the ID that is optional.  This field is marked as being the ID.
  • Inputs for other fields on the body.  All fields that are not nullable and can’t be populated by the system on create should be required.
Pseudo-Code
function upsertObjectById(obj) {
  // If the object's ID is split across more than one field, we should check 
  // that either all ID fields are populated or that none are.  Otherwise we
  // should throw an exception.

  const objectToUpdate = GetObjectById(obj.id);   // Usually GET verb
  if(objectToUpdate == null) {
    const createdObject = CreateObject(obj);    // Usually POST verb
    EmitData(createdObject);
  } else {
    const updatedObject = UpdateObject(obj, id);   // Usually POST/PATCH verb
    EmitData(updatedObject);
  }
}
Output Data
  • The object post creation/update as reported by the system
Gotcha’s to lookout for
  • Updates should be partial updates
  • Make sure to Url Encode IDs appearing in HTTP urls

Iteration 2: Update Object By Unique Criteria

Additional Config Fields
  • Upsert Criteria: Drop down with all sets of unique constraints for the object in question
Input Metadata Changes
  • The fields that are part of the upsert criteria are marked as being part of the criteria.  If the criteria is something other than the ID, they should be marked as required.  
  • (There is a hypothetical edge case here where the system auto-populates the unique criteria)
Pseudo-Code
function upsertObjectByUniqueCriteria(obj, uniqueCriteria) {
  // Ensure unique criteria are all populated (unless ID)
  // If criteira is th the object's ID and it is split across more than one field, we should check 
  // that either all ID fields are populated or that none are.  Otherwise we
  // should throw an exception.

  const objectsToUpdate = GetObjectsByCritieria(uniqueCriteria);   // Usually GET verb
  if(objectsToUpdate.length == 0) {
    const createdObject = CreateObject(obj);    // Usually POST verb
    EmitData(createdObject);
  } else if (objectsToUpdate.length == 1) {
    const updatedObject = UpdateObject(obj, objectsToUpdate[0].id);   // Usually POST/PATCH verb
    EmitData(updatedObject);
  } else {
    throw new Error(`More than one matching object found.`);