PatchPrivatePreviewFeedbackGroup
PatchPrivatePreviewFeedbackGroup copied to clipboard
.NET Ergonomics feedback / discussion
Just a bunch of ideas
Concrete List<> arg
PatchItemAsync takes an IReadOnlyList
, which has to be created explicitly as some concrete type which results in code that looks like this:
List<PatchOperation> patchOperations = new List<PatchOperation>();
patchOperations.Add(PatchOperation.Add("/nonExistentParent/Child", "bar"));
patchOperations.Add(PatchOperation.Remove("/cost"));
patchOperations.Add(PatchOperation.Increment("/taskNum", 6));
patchOperations.Add(patchOperation.Set("/existingPath/newproperty",value));
container.PatchItemAsync<item>(
id: 5,
partitionKey: new PartitionKey(“pkey”),
patchOperations: patchOperations );
If you used a concrete List<>
as the input you could use C#'s target-typed new expression:
container.PatchItemAsync<item>(
id: 5,
partitionKey: new PartitionKey(“pkey”),
patchOperations: new()
{
PatchOperation.Add("/nonExistentParent/Child", "bar"),
PatchOperation.Remove("/cost"),
PatchOperation.Increment("/taskNum", 6),
PatchOperation.Set("/existingPath/newproperty", value),
});
Expression to path string
Also it would be great if Patch Operations could take C# expressions for the paths to compile
patches.Add(p => p.Cost[0], 5)
to
PatchOperation.Add("/Cost[0]", 5)
Fluency
You could define the operation fluently:
var result = await Container.Patch<MyParentType>()
.Add(p => p.Cost[0], 5)
.Increment(p => p.Version, 1)
.ApplyAsync(requestOptions);
Custom value serialization
I dont currently see a way to get away from the Newtonsoft serializer for the individual patch values, unless I'm missing something; the PatchOperations themselves do accept overloads a stream but combining many streams into a single operation may be less efficient than serializing an entire patch operation chain at once.
Regarding custom value serialization ask, we did address it recently. If the value you pass for the individual PatchOperation is of type Stream, then we won't serialize it.
You can see example.
@anujtoshniwal thanks, I'll test that again but I created the issue after I got an exception trying to use a stream.
@onionhammer which version of SDK are you using? Try with 3.0.19-preview1 (link)
@anujtoshniwal I will get back to you on that.
However I think it would probably be more efficient to not have to pass 6 streams for 6 patches in 1 payload
Okay, tested with '3.19.0-preview1' and it does work to send streams, although its not mentioned in the root readme anywhere. Updating the top comment
+1 on the Concrete List<> arg and the Expression to path string and the Fluency.
that would make for MUCH neater code.
IReadOnlyList<PatchOperation> patchOperations = new[] { PatchOperation.Replace("/ShippedDate", DateTime.UtcNow) };
using (Stream stream = Program.ToStream<IReadOnlyList<PatchOperation>>(patchOperations))
{
using (ResponseMessage responseMessage = await container.PatchItemStreamAsync(
id: order.Id,
partitionKey: new PartitionKey(order.AccountNumber),
patchOperations: patchOperations))
{
the use here of patchOperations is confusing. you pass patchOperations in to ToStream which then gets passed in to the Stream that you're using and then you have patchOperations again in the PathItemStreamAsync method.
this is confusing, why do i need it twice? Should PatchItemStreamAsync just take a stream of List<PatchOperation>?