-
Notifications
You must be signed in to change notification settings - Fork 604
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
setMetadata() method merges existing with new data? #597
Comments
Remember #459? Yeah we switched to PATCH because using PUT destroyed ACLs with BigQuery, making our datasets inaccessible. I'm not sure if this is also the case with Storage but I feel it would be appropriate to remain consistent across our APIs in this library. |
We can still document it for our users. If they want to delete an existing value, I believe the correct way is to set it to null. |
Yes, but I doubt if doing it (delete and set) should be done by the library as it can fail in the middle and leave it in an undesired state. BTW, nulls may be a separate issue which I mentioned to @jgeewax. |
The API call operation is atomic so either the whole thing succeeds or fails. |
I think I see what you were saying. I meant that using PATCH you can delete existing values by setting them to null. We never make 2 calls for setting metadata. That requires you to know about the ones are set already, which is a getMetadata call away. We leave this as an exercise for the user if they want to do that. |
What I was saying is that we should probably not do the following:
|
Oh we'd never do that. The end result is the same as just I meant if you wanted to set completely new metadata, including destroying the ones currently set, you need to know the existing ones and set them to null so as to achieve the same result as using PUT. |
Like this: // metadata is currently { a: '1', b: '2', c: '3' };
rpc.patch(blob, { metadata: { a: 'x', b: null, c: null } }) // need to know b and c exist so you can set them to null
// metadata is now { a: 'x' }; This is the same as: // metadata is currently { a: '1', b: '2', c: '3' };
rpc.put(blob, { metadata: { a: 'x' } })
// metadata is now { a: 'x' }; |
Is it? Is rpc.put doing an update (https://cloud.google.com/storage/docs/json_api/v1/objects/update)? |
So back to the main issue: My concern here is that Can we rename anything ? or are we just OK with adding some docs that explain this? Or do we try to get Google to fix something ? What makes the most sense as a user of this library? |
I doubt that a function that can only append is that useful. |
As a side comment: Metadata (and other properties) on S3 Objects are immutable. To change them you must copy the object. Another option is to make Metadata not an "object" in Javascript, but instead a method that has keys and values. So: file.setMetadata('key', 'value', function(metadata) {}); The idea being, you can always clear out the metadata for any key you know of... ( If we left the existing Thoughts? |
I'm against
The function is not append only, if you know the key you can set it to null and it will be deleted. I wish that acls and contentType weren't overwritten when you set the metadata or that the raw key/value pair of custom metadata was completely separate from the "properties" of the object, but this is an issue I have with the API itself, not our library. Not sure how much easier we could make it without making the user jump through more hoops. |
Because they are -- I'm proposing we make // Set a single key of metadata:
file.setMetadata('client', 1234);
// Remove a single key of metadata:
file.setMetadata('client', null);
// or
file.clearMetadata('client');
// or
file.removeMetadata('client');
// Merge in (or patch) a whole bunch of metadata:
file.patchMetadata({ // or mergeMetadata
important: 'true',
client: '1234'
});
// Clear all metadata
file.clearMetadata(); // I don't think we have a way to make this atomic... The idea would be that we're discouraging people from sending in a big dictionary, because it really isn't what you expect. For all other
Exactly -- if you know the keys... which may be a long list... |
So we're encouraging them to make many tiny requests to set all their metadata fields? That's just silly. I'm more for calling it If anything we should rename the method and force people to update their code.
Yeah we could use UPDATE semantics for that and just not set anything but I don't know why someone would ever want to do this because their acls will be destroyed, effectively locking them out of updating their file ever again. |
There is a balance we have to find. We can use words people know, and have them be lies, or we can use words they don't know and have them be the truth. Right now, thing.setMetadata({first: 1});
assert(thing.getMetadata() == {first: 1});
thing.setMetadata({second: 2});
assert(thing.getMetadata() == {second: 2}); // This *fails*. If we make it operate on single values, then it acts like I'd expect thing.setMetadata('first', 1);
assert(thing.getMetadata('first') == 1);
thing.setMetadata('second', 2);
assert(thing.getMetadata('second') == 2); // This *passes*. Regarding
We couldn't though, right? If we did that it'd blast out more than just the metadata -- it'd remove everything else (ACLs, etc). file.makePublic();
assert(/* file is public */);
file.setMetadata({first: 1});
assert(file.getMetadata() == {first: 1});
file.clearMetadata();
assert(file.getMetadata() == null /* or {} */); // This *passes*.
assert(/* file is public */); // This *fails*, right? |
But I see It would be like if we went the road of If we're just trying to not confuse developers by our terminology as opposed to adding new functionality, can we each ask a non-Google dev what they think and take a vote? :) |
I'm down with that. How do we find impartial people ? I'm asking around inside Google UX (who do studies and whatnot...) but I suspect you guys might have some people we could poll... |
Sounds good, the more thoughts the better. I'm asking a couple JS friends. |
Did you consider my original suggestion (which apparently is consistent with S3). Only accept metadata in create request and make it a read-only attribute (until the underlying issue is fixed) or do you see it as a problem (conceptually or implementation wise)? |
To be clear, that's a further option, removing I suspect people would be a bit miffed at that... |
@stephenplusplus : Any progress on asking around? I'm still seeing how we would do broader user polling on our side. |
I'll follow up with some folks and report back. I was reminded that React uses You can see in |
To be more explicit: setState ... "Merges nextState with the current state." https://facebook.github.io/react/docs/component-api.html#setstate |
Sounds like the resolution to this issue, then, is to update setMetadata's documentation to say "Merge nextMetadata with the current metadata" or similar. |
I like that idea :) Just clearer documentation! |
It's also nice that React does it too, so we aren't just being different
for no good reason....
|
What if React does it because someone else did it for no good reason :) |
Then we're just blind followers jumping off cliffs because our friends do :( That said, I think it's more like jumping into a puddle than off a cliff -- at worst it's slightly surprising for users. Let's make sure we have a good example of what happens when you just "set" new metadata... (that the old data doesn't go away unless you specifically tell it to). |
- [ ] Regenerate this pull request now. Committer: @summer-ji-eng PiperOrigin-RevId: 424244721 Source-Link: googleapis/googleapis@4b6b01f Source-Link: googleapis/googleapis-gen@8ac83fb Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiOGFjODNmYmE2MDZkMDA4YzdlOGE0MmU3ZDU1YjY1OTZlYzRiZTM1ZiJ9
- [ ] Regenerate this pull request now. Committer: @summer-ji-eng PiperOrigin-RevId: 424244721 Source-Link: googleapis/googleapis@4b6b01f Source-Link: googleapis/googleapis-gen@8ac83fb Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiOGFjODNmYmE2MDZkMDA4YzdlOGE0MmU3ZDU1YjY1OTZlYzRiZTM1ZiJ9
- [ ] Regenerate this pull request now. Committer: @summer-ji-eng PiperOrigin-RevId: 424244721 Source-Link: googleapis/googleapis@4b6b01f Source-Link: googleapis/googleapis-gen@8ac83fb Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiOGFjODNmYmE2MDZkMDA4YzdlOGE0MmU3ZDU1YjY1OTZlYzRiZTM1ZiJ9
fix: update protos Source-Link: googleapis/synthtool@0a68e56 Post-Processor: gcr.io/cloud-devrel-public-resources/owlbot-nodejs:latest@sha256:5b05f26103855c3a15433141389c478d1d3fe088fb5d4e3217c4793f6b3f245e Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
🤖 I have created a release *beep* *boop* --- ## [3.1.2](https://togithub.com/googleapis/nodejs-iot/compare/v3.1.1...v3.1.2) (2022-11-10) ### Bug Fixes * **deps:** Use google-gax v3.5.2 ([#593](https://togithub.com/googleapis/nodejs-iot/issues/593)) ([2f547e1](https://togithub.com/googleapis/nodejs-iot/commit/2f547e1c27006a201c9c7066befd35e043fb43c2)) * update protos ([a8e8800](https://togithub.com/googleapis/nodejs-iot/commit/a8e88006f95594575a70494b1ca5f417e5985765)) * Update protos ([#597](https://togithub.com/googleapis/nodejs-iot/issues/597)) ([a8e8800](https://togithub.com/googleapis/nodejs-iot/commit/a8e88006f95594575a70494b1ca5f417e5985765)) --- This PR was generated with [Release Please](https://togithub.com/googleapis/release-please). See [documentation](https://togithub.com/googleapis/release-please#release-please).
[![WhiteSource Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [sinon](https://sinonjs.org/) ([source](https://togithub.com/sinonjs/sinon)) | [`^12.0.0` -> `^13.0.0`](https://renovatebot.com/diffs/npm/sinon/12.0.1/13.0.0) | [![age](https://badges.renovateapi.com/packages/npm/sinon/13.0.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/sinon/13.0.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/sinon/13.0.0/compatibility-slim/12.0.1)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/sinon/13.0.0/confidence-slim/12.0.1)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>sinonjs/sinon</summary> ### [`v13.0.0`](https://togithub.com/sinonjs/sinon/blob/HEAD/CHANGES.md#​1300) [Compare Source](https://togithub.com/sinonjs/sinon/compare/v12.0.1...v13.0.0) - [`cf3d6c0c`](https://togithub.com/sinonjs/sinon/commit/cf3d6c0cd9689c0ee673b3daa8bf9abd70304392) Upgrade packages ([#​2431](https://togithub.com/sinonjs/sinon/issues/2431)) (Carl-Erik Kopseng) > - Update all @​sinonjs/ packages > > - Upgrade to fake-timers 9 > > - chore: ensure always using latest LTS release - [`41710467`](https://togithub.com/sinonjs/sinon/commit/417104670d575e96a1b645ea40ce763afa76fb1b) Adjust deploy scripts to archive old releases in a separate branch, move existing releases out of master ([#​2426](https://togithub.com/sinonjs/sinon/issues/2426)) (Joel Bradshaw) > Co-authored-by: Carl-Erik Kopseng <[email protected]> - [`c80a7266`](https://togithub.com/sinonjs/sinon/commit/c80a72660e89d88b08275eff1028ecb9e26fd8e9) Bump node-fetch from 2.6.1 to 2.6.7 ([#​2430](https://togithub.com/sinonjs/sinon/issues/2430)) (dependabot\[bot]) > Co-authored-by: dependabot\[bot] <49699333+dependabot\[bot][@​users](https://togithub.com/users).noreply.github.com> - [`a00f14a9`](https://togithub.com/sinonjs/sinon/commit/a00f14a97dbe8c65afa89674e16ad73fc7d2fdc0) Add explicit export for `./*` ([#​2413](https://togithub.com/sinonjs/sinon/issues/2413)) (なつき) - [`b82ca7ad`](https://togithub.com/sinonjs/sinon/commit/b82ca7ad9b1add59007771f65a18ee34415de8ca) Bump cached-path-relative from 1.0.2 to 1.1.0 ([#​2428](https://togithub.com/sinonjs/sinon/issues/2428)) (dependabot\[bot]) - [`a9ea1427`](https://togithub.com/sinonjs/sinon/commit/a9ea142716c094ef3c432ecc4089f8207b8dd8b6) Add documentation for assert.calledOnceWithMatch ([#​2424](https://togithub.com/sinonjs/sinon/issues/2424)) (Mathias Schreck) - [`1d5ab86b`](https://togithub.com/sinonjs/sinon/commit/1d5ab86ba60e50dd69593ffed2bffd4b8faa0d38) Be more general in stripping off stack frames to fix Firefox tests ([#​2425](https://togithub.com/sinonjs/sinon/issues/2425)) (Joel Bradshaw) - [`56b06129`](https://togithub.com/sinonjs/sinon/commit/56b06129e223eae690265c37b1113067e2b31bdc) Check call count type ([#​2410](https://togithub.com/sinonjs/sinon/issues/2410)) (Joel Bradshaw) - [`7863e2df`](https://togithub.com/sinonjs/sinon/commit/7863e2dfdbda79e0a32e42af09e6539fc2f2b80f) Fix [#​2414](https://togithub.com/sinonjs/sinon/issues/2414): make Sinon available on homepage (Carl-Erik Kopseng) - [`fabaabdd`](https://togithub.com/sinonjs/sinon/commit/fabaabdda82f39a7f5b75b55bd56cf77b1cd4a8f) Bump nokogiri from 1.11.4 to 1.13.1 ([#​2423](https://togithub.com/sinonjs/sinon/issues/2423)) (dependabot\[bot]) - [`dbc0fbd2`](https://togithub.com/sinonjs/sinon/commit/dbc0fbd263c8419fa47f9c3b20cf47890a242d21) Bump shelljs from 0.8.4 to 0.8.5 ([#​2422](https://togithub.com/sinonjs/sinon/issues/2422)) (dependabot\[bot]) - [`fb8b3d72`](https://togithub.com/sinonjs/sinon/commit/fb8b3d72a85dc8fb0547f859baf3f03a22a039f7) Run Prettier (Carl-Erik Kopseng) - [`12a45939`](https://togithub.com/sinonjs/sinon/commit/12a45939e9b047b6d3663fe55f2eb383ec63c4e1) Fix 2377: Throw error when trying to stub non-configurable or non-writable properties ([#​2417](https://togithub.com/sinonjs/sinon/issues/2417)) (Stuart Dotson) > Fixes issue [#​2377](https://togithub.com/sinonjs/sinon/issues/2377) by throwing an error when trying to stub non-configurable or non-writable properties *Released by [Carl-Erik Kopseng](https://togithub.com/fatso83) on 2022-01-28.* </details> --- ### Configuration 📅 **Schedule**: "after 9am and before 3pm" (UTC). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox. --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/nodejs-monitoring).
- [ ] Regenerate this pull request now. Committer: @summer-ji-eng PiperOrigin-RevId: 424244721 Source-Link: googleapis/googleapis@4b6b01f Source-Link: googleapis/googleapis-gen@8ac83fb Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiOGFjODNmYmE2MDZkMDA4YzdlOGE0MmU3ZDU1YjY1OTZlYzRiZTM1ZiJ9
Looks like if I call
setMetadata
on an object, it merges the data with what's in production...I suspect that we can't .. fix this all that much... but maybe we can at least document it ?
The options we have so far:
setMetadata
getMetadata(key)
andsetMetadata(key, value)
setMetadata
topatchMetadata
ormergeMetadata
setMetadata
/cc @Capstan @aozarov
The text was updated successfully, but these errors were encountered: