Repository navigation
storage: API proposal #194
Description
Activity
I like this proposal 💯
Get metadata about a bucket
storage.getBucket('bucket-name', cb); // or (pick one) storage.bucket('ryan-files').getInfo(cb);
storage.bucket()
Though I prefer
getMetadata.Reference to a file/object in a bucket
myBucket.file('stephen.png'); // or (pick one) myBucket.object('stephen.png');
Thanks for the shout out! :)
I really like the file object. It allows us another child in the hierarchy, allowing logical separation of actions. I think they should be full featured objects, removing a lot of functionality from
bucket. Consider if all file objects are duplex streams:var ryan = myBucket.file('ryan.gif'); // upload a file to your bucket's ryan.gif file fs.createReadStream('local_file.png').pipe(ryan); // pipe a readable stream of your bucket's ryan.gif file to a destination ryan.pipe(fs.createWriteStream('local_ryan.gif')); // copy to another bucket - replace myBucket.copy ryan.pipe(anotherBucket.file('ryan-clone.gif')); // get file metadata - replace myBucket.stat ryan.stat(cb); // set file metadata - replace myBucket.write's metadata write only functionality ryan.setMetadata({}); // delete file - replace myBucket.delete ryan.delete(cb); // (sorry)
Footnote: let's do a little better housekeeping. This is the result of a lengthy discussion at #168 based around supporting the creation of buckets. I agree with flushing that convo and starting anew, but we should make sure these discussions are linked, and old ones are closed.
If
ryan.delete(cb)deletes the file then why doesn'tmyBucket.delete(cb)delete the bucket? (we had this whole delegation conversation earlier).If we provide
ryan.pipe(anotherBucket.file('ryan-clone.gif'));then there's no reason why we shouldn't or couldn't also providemyBucket.copy()(for developers who don't want to use the streaming interface and just want plain methods).If ryan.delete(cb) deletes the file then why doesn't myBucket.delete(cb) delete the bucket? (we had this whole delegation conversation earlier).
Fair. But, the other part of my point in regards to
myBucket.deletewas it would be confused withremove, which removes a file. If we have a file object to handle file things, I have less of an issue withmyBucket.deleteandmyFile.delete. Did you agree with me from the other conversation? How do you look at it/which do you prefer?Sure, we can provide quick methods as well, and we can internally use the stream api:
myBucket.copy('local_file.png', anotherBucket.file('ryan-clone.gif')); // where... Bucket.prototype.copy = function(localFilepath, destinationFileObject, callback) { fs.createReadStream(localFilepath).pipe(destinationFileObject) .on('error', callback) .on('complete', callback); };
Yes I like
myBucket.delete(cb)delete a bucket andmyBucket.getMetadata(cb)get bucket metadata etc. The one thing you didn't like from the previous discussion wasmyBucket.create(cb)andstorage.listBuckets()would still have to remain.The one thing you didn't like from the previous discussion was myBucket.create(cb) and storage.listBuckets() would still have to remain.
I may not understand you, but isn't it now
storage.createBucket? I like creating a bucket from the storage object, not from an already created Bucket instance. When I have a Bucket, I think "this refers to an existing remote endpoint," so creating one from that object breaks that model. That's not the same for deleting, as it makes sense to delete an already existing bucket from a Bucket instance.And
storage.listBucketsis cool with me. I think I suggestedgetBucketsorlistBuckets, and I'm still +1 to either.Yeah, this makes sense.
storage.createBucket()is better thanmyBucket.create()and either listBuckets or getBuckets, I'm indifferent.Thanks guys, this is a great discussion!
Could we move it to a public Google Doc? That would allow us to keep an updated snapshot of the proposed API at the top of the doc and a track of considered alternatives, and I think it would make it clearer for newcomers to follow the discussion and understand where are we at.Could we move this to Docs? I have comments,
@silvolu - should I jump on putting this into code next?
I cannot comment ON the doc :/
@rakyll did you manage to add your comments on this proposal?@silvolu added you to the doc
72 remaining items
- added a commit that references this issue
on Feb 17, 2026 - added a commit that references this issue
on Feb 23, 2026 - added 2 commits that reference this issue
on Feb 24, 2026 - added a commit that references this issue
on Feb 26, 2026 - added a commit that references this issue
on Mar 5, 2026 - added a commit that references this issue
on Mar 5, 2026 - added 2 commits that reference this issue
on Mar 9, 2026 - added a commit that references this issue
on Mar 11, 2026 - added a commit that references this issue
on Mar 12, 2026 - added a commit that references this issue
on Mar 18, 2026
New
http://stephenplusplus.github.io/gcloud-node/#/docs/master/storage
Old
Moved to docs: https://docs.google.com/document/d/1SG7DYKEjzX8MiYcPtrKunprT6fgLXIFDsdoVA8ETdow
I took some time to go through what calls the current storage API supports and tried to redesign them to be easier to understand and encapsulate what most developers would like to do with the api. This covers buckets, files, and ACL on them both. The API I propose is below. Let me know if I missed anything or you have questions or a better idea 👍
Initialization
Buckets
Reference to a bucket (local only, no network request)
Create a bucket
Delete a bucket
List all buckets
Get metadata about a bucket
Files/Objects
Reference to a file/object in a bucket
Upload an object to a bucket
Remove an object from a bucket
Copy an object from one bucket to another
ACLs
Create an ACL?
List of scope/permission pairs (may be overkill?)
Set default object ACL for all objects added to bucket
Clear default ACL for all objects added to bucket
Get default ACL for all objects added to bucket
Set ACL of bucket
Set ACL of file/object
Clear custom ACL for file/object
Clear custom ACL for bucket
Get ACL of a file/object
Get ACL of a bucket
Channels
Stop watching resources through this channel
This is provided by
storage.channels.stop()in google-api-nodejs-client