Retriving, Listing, and Downloading from S3


There is a lot of information on uploading files to Amazon S3, but surprisingly little about creating client interfaces for browsing bucket contents. In my current Ember project, I’m trying to develop a section of a cloud app that lists various resources (PDFs) for download. Users with admin privileges can upload new resources, providing a title and description that will be shown to other users browsing the list.

S3 seems to be the de facto solution for cloud storage of documents (as opposed to storing all the uploads on your Heroku instance, say), so I’m looking into using that. While my client is currently 99% client-side (with Node.js doing little else but serving up index.html and running some background processes), S3 pretty much requires that I get Node involved to avoid storing access tokens in the client, at the very least.

Where I’m getting stuck is how to go about fetching a list of bucket contents for view in the Ember app so the user can download files.

  1. What’s the best practice for retrieving URLs or keys to populate links? Do I basically need to create a GET endpoint on my server to return a JSON object that I can parse in Ember, using one of several Node AWS libraries to build the response? What information does my client need to build the links?
  2. Since the client isn’t going to have direct authorization, should I assume that a request for download is going to need to be sent back to Node to send on to S3? How does the download actually get to the browser so the user can open or save the file? Note: I don’t want a public bucket, which would allow me to just use public URLs.
  3. The users uploading files are adding metadata that is needed for display in the client file list (I don’t want to show raw S3 keys). How should I go about keeping this information around and keeping it in sync with what’s on S3? It seems like I might have to store it somewhere else (like Firebase, which I’m using for all of the app’s model data) but I can see that easily getting out of sync with S3. S3 has metadata capability but it cannot be edited, and I plan on letting users change the titles and descriptions as needed.

What I think makes sense:

  1. Admin user uploads a file, with the upload handled by Node. Along with the file is sent some metadata. Node not only uploads to S3 but, on successful upload, stores the model data Ember later needs in Firebase.
  2. When listing files in Ember, rely only on the Firebase model data as I would any data my routes are loading.
  3. When I user clicks on a file for download, send the request to Node->S3.
  4. Somehow (how??) the file gets back to the users browser and begins to download onto their computer (or displays if they have a viewer plugin for that MIME type configured).

Has anyone come up against this use case or something similar? How did you implement it?