This is a massive refactoring of the insert/update flow that gives us consistent bulk requests with optional idempotent behavior.
Since we have so many intersecting options (insert,update, insert-or-update , idempotent or not, with implied parent relationship or without one), we need a way for the users to build a backend request they need in each specific situation. I came up with an interface like that:
<T> CreateOrUpdateBuilder<T> update(Class<T> type);
<T> CreateOrUpdateBuilder<T> create(Class<T> type);
<T> CreateOrUpdateBuilder<T> createOrUpdate(Class<T> type);
/**
* Returns a CreateOrUpdateBuilder that would perform an idempotent
* create-or-update operation on the request objects. The operation will
* fail if it can't be executed as idempotent. The condition is usually that
* all object's ID should be passed explicitly in request or can be implied
* from a relationship. Otherwise the server will have no way of mapping
* update data to an existing object and the update can't be idempotent.
*/
<T> CreateOrUpdateBuilder<T> idempotentCreateOrUpdate(Class<T> type);
/**
* A builder for create (insert) or update operations for a single entity type.
*/
public interface CreateOrUpdateBuilder<T> {
/**
* Set an explicit id for the update. In this case only a single object is
* allowed in the update.
*/
CreateOrUpdateBuilder<T> id(Object id);
/**
* Sets up a relationship clause for all objects in this update.
*/
CreateOrUpdateBuilder<T> parent(Class<?> parentType, Object parentId, String relationshipFromParent);
/**
* Sets up a relationship clause for all objects in this update.
*/
CreateOrUpdateBuilder<T> parent(Class<?> parentType, Object parentId, Property<T> relationshipFromParent);
/**
* Sets up a relationship clause for all objects in this update.
*/
CreateOrUpdateBuilder<T> toManyParent(Class<?> parentType, Object parentId,
Property<? extends Collection<T>> relationshipFromParent);
UpdateResponse<T> process(String entityData);
}
This will effectively deprecate current "insert" and "update" operations (the are a special case of the builder) and remove all the recent related/relatedNew API (which is hopefully not widely used yet).