question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[FEATURE REQ] Introduce a response object for Add, Update, and Upsert entity methods

See original GitHub issue

Library or service name. Azure.Data.Tables

Is your feature request related to a problem? Please describe. This response object would be called something like “EntityUpdateInfo” and would have at least an ETag property but in the future could contain a property with the whole T entity if the Prefer: return-content header is able to be specified as a parameter (don’t know if there’s plans to support this).

When using Azure.Data.Tables to insert, update, or upsert a record to a table, it’s important to have the latest etag returned in the response headers to continue a chain of operations based on optimistic concurrency. If the etag is not surfaced in the API you must either:

  1. Tease the ETag out of the returned Response.Headers.ETag.Value (not terrible, but not ideal)
  2. Query the entity again (UNSAFE, the entity may have been changed!)

As a nice to have, it would be great if the a Timestamp was included as well on this new response type, which is what WindowsAzure.Storage does by parsing the etag (perhaps a bad idea, especially if the behavior is different on Cosmos DB). I can’t find the source of WindowsAzure.Storage but if you decompile it with ILSpy there is a ParseETagForTimestamp method much like this Java one: https://github.com/Azure/azure-storage-android/blob/2c643c37c6b8c9081058add284c601a2393afc93/microsoft-azure-storage/src/com/microsoft/azure/storage/table/TableResult.java#L168-L180

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
joelverhagencommented, Mar 23, 2021

As an aside, I’m a huge fan of Azure Table Storage (cheap+simple+fast) so I’m quite passionate about this new Azure.Data.Tables SDK. I am moving my side project over to the new SDK one module at a time and will be opening issues/PRs as I come upon things.

0reactions
christothescommented, Mar 23, 2021

Thank you for the detailed and thoughtful feedback!

I moved my entire codebase’s blob and queue usage to the new Azure.* SDKs and I never had to use the Response object. There was always a model that specifically described that the service was returning in specific terms, rather than the generic HTTP response shape that Response describes. For example, consider BlobContentInfo.ETag returned by BlobClient.UploadAsync.

The dilemma here is that by default, we do not echo the entity in the response for these operations. So if we did return a model type, it would need to be something that is just the ETag. Other than returning the whole entity, which seems like it would be inefficient in the main line case, I’m not sure if it would make sense to create a model containing just the ETag.

Also, the ETag is nullable on Response.Headers.ETag but I think Table storage will always return an ETag for these operations so caller (code using the SDK) needs to do the research to be sure that you can safely do ETag.Value all the time and not check for null.

If the ETag were null for some reason this would cause serious problems for a sequence of optimistic concurrency calls! You’d either have to do a subsequent, unconditional entity update with no etag (dangerous) or perform a GET and diffgram-like operation to determine if the current entity state matches what was just PATCH/POSTed so that the returned etag can be used.

When calling UpdateEntity, the ETag value is required. We’ll throw if it is a default value, and unless it is set to “*”, it will never be treated as an unconditional update.

Sorry, I think what I said was confusing. What I mean is that (AFAIK) none of the Azure.Data.Tables APIs modify the provided entity. The provided entity is only read from (e.g. via reflected property getters) for producing the HTTP request body. I was thinking that perhaps this was a design philosophy and that was why the ETag was not being automatically updated/set on the entity provided to Add/Update/Upsert. I think I got this “feeling” originally from #19671 but it also sort of makes sense, if you ask me, considering the Merge Table Storage operation which cannot bring the provided entity up to the current full state without another round trip since more properties may exist on the server which are not known about.

Said another way, WindowsAzure.Storage updates the entity ETag when performing these operations so I was expecting the new SDK to either a) have strongly typed model containing the subsequent etag (akin to the Azure.Storage.Queue) or b) update the provided entity (akin to WindowsAzure.Storage).

OK, interesting. Yes, I think I prefer having the operations not affect the supplied entity. Updating just the ETag seems inconsistent, and updating the whole entity makes some assumptions that the object is not being used again for something else by the caller.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Use Upsert to Create or Update a record - Dataverse
The UpsertRequest instance arrives with the Target Property set with an Entity instance containing the data for a Create or Update operation ...
Read more >
Insert Or Replace Entity (REST API) - Azure Storage
The Insert Or Replace Entity operation replaces an existing entity or inserts a new entity if it does not exist in the table....
Read more >
[Feature Request] Upsert generation · Issue #2363
to upsert I need to build my query with createQueryBuilder but onConflict only excepts string queries, which makes it very difficult with large ......
Read more >
upsert with return functionality · Issue #1090 · typeorm ...
I added onConflict method to insert query builder . This functionality was made just to support onConflict clause inside InsertQueryBuilder and ...
Read more >
upsert - Add or replace entity in Azure Table Storage
Do I really have to manually query for the existing row first and call DeleteObject on it? That seems very slow. Surely there...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found