Azure-cosmos-dotnet-v3: PatchAPI: Add JSON patch support

Created on 14 May 2020  Â·  7Comments  Â·  Source: Azure/azure-cosmos-dotnet-v3

Scenario's:

  • Limited to single document always
  • Composable for Transactional batch
  • Order performed as requested (with-in single document)
  • Structure updates (Add, delete, replace, etc..), conditional aspect
  • Special operations (increment, numeric types)

Will follow later

Non goals

  • Chain results in TransactionalBatch scenario (ex: update a doc, use result to update another doc)
  • Support custom JS lambda

Open clarifications

  • What's status code when the patched document is larger than 2MB?

413 - Payload Too Large

  • What's status code when the inflight patched document is larger than 2MB but eventual size is valid?
    We will only track the final size of item generated and any intermediate size during the application of PatchSpec will not be considered. Any artifacts (ConfirmedPatchHistory) generated during creation of PatchSpec will not be accounted for in 2MB size.
  • Service structure validation: What validations are performed on final result?
    None
  • How many mutations per document (or batch) are supported?
    Maximum 100 operations per Patch request.
  • What's the REST API version?
  • Any guards to cover for client encryption? (accidental encryption override/corruption)
    With our current non-deterministic encryption model where server does not know which properties are encrypted, we would not support Patch on documents which has encrypted data. However, with upcoming deterministic encryption model – patch will be supported.
  • Can the patch be used to rename document id (not PK)?
    Yes
  • Client encryption and patch consistency
    Repeat point.
  • What will it be ChangeFeed ChangeType?
    Replace

Finalized OM

```C#

public abstract class Container
{
// Single document
ItemResponse PatchItemAsync(
string,
PartitionKey,
IReadOnlyList,
ItemRequestOptions,
CancellationToken);

// Single PK, Transactional-batch
TransactionalBatchBuilder CreateTransactionalBatch(PartitionKey pk);

}

public abstract class TransactionalBatchBuilder
{
// Results in nested builder pattern
TransactionalBatchBuilder PatchItem(
string id,
IReadOnlyList patchOperations,
ItemRequestOptions);

TransactionalBatchResponse Execute(CancellationToken token);

}

public abstract class PatchOperation
{
public PatchOperationType Operation;
public string path;
static PatchOperation CreateAddOperation(string path, T payload);
static PatchOperation CreateRemoveOperation(string path);
static PatchOperation CreateReplaceOperation(string path, T payload);
static PatchOperation CreateSetOperation(string path, T payload);
}

// { op = "add", Path="", value="" }
public class PatchOperationType
{
Add,
Remove,
Replace,
Set
}

### _Alternative OM considered_
```C#
public abstract class Container
{
    // Single document
    ItemResponse<T> PatchItemAsync(
        PartitionKey, 
        string, 
        ItemPatchSpecfication,
        ItemRequestOptions,
        CancellationToken);

    // Single PK, Trasnactional-batch
    TransactionalBatchBuilder CreateTransactionalBath(PartitionKey pk);
}

public abstract class TransactionalBatchBuilder
{
    // Results in nested builder pattern
    TransactionalBatchBuilder PatchItem(
        string id, 
        PatchSpecfication spec, 
        ItemReqeustOptions);

    TransactionalBatchResponse Execute(CancellationToken token);
}

public class ItemPatchSpecfication
{
    private List<PatchOperation> ops;

    ItemPatchSpecfication Add<T>(string path, T payload);
    ItemPatchSpecfication Delete(string path);
    ItemPatchSpecfication Replace<T>(string path, T payload);
    ItemPatchSpecfication Move(string path, string path);
    ItemPatchSpecfication Get(string path);

    ItemPatchSpecfication increment(string path);   
}

// { op = Add, Path="", value="" }
internal class ItemPatchOperation // Union type
{
    Operation;
    from;
    Path;
    Value;
        ...
}
  1. Single document mutations(or patches)

    • Composable through builder

    • Support multiple types (representing nested types)

  2. Same list of PatchOperation can be leveraged for both SingleItem and TransactionalBatch scenarios
  3. Actual operation contract is not public. Will explore it when its a goal
    > Operation contract is made public (based on feedback for Batch).
  4. Patch values has to go-through custom serializer
  5. Response semantics still TBD
    > Consistent with other APIs.

Notes:

  1. Path as string literal: Error prone typing, serialization inference. One option is to have overload can infer path through full payload (ex: Add(T item) with assumption that only one root-nested path present. Its a convenience overload and based on user feedback we can explore.
  2. 2.

ref:
https://tools.ietf.org/html/rfc6902
https://www.nuget.org/packages/Microsoft.AspNetCore.JsonPatch/

/cc: @j82w, @ealsur , @FabianMeiswinkel , @kushagraThapar , @moderakh , @milismsft

feature

Most helpful comment

Any ETA on GA?

All 7 comments

Increment/decrement operations might require validation on the server. What if I the value is not numeric? Will it fail the operation? I can't find them on the RFC 6902.

I would like to understand the plans on how/when we will support patch in the backend first. IMO adding a convenience API is going to cause dissatisfaction - it makes it look like we support patch, customers expect efficient (lower RU cost) patch but ultimately see the same high RU cost. In addition without fully understanding the plans of teh back-end we risk that we would need to make breaking chnages later to accomodate whatever approach the backend chose to support patch.

@FabianMeiswinkel patch in BE is already in works. I will forward related offline.

One more question to add: Will Patch support Etag for scenarios when 2 Patch operations for the same path happen concurrently?

Any ETA on GA?

Some sort of ETA would be extremely helpful as my team looks to transition to Cosmos DB

End of year is tentative for preview of patch feature.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

thomaslevesque picture thomaslevesque  Â·  7Comments

miiitch picture miiitch  Â·  5Comments

darthmolen picture darthmolen  Â·  4Comments

ealsur picture ealsur  Â·  8Comments

lukasz-pyrzyk picture lukasz-pyrzyk  Â·  3Comments