S3 Image uploading: How it works for our React frontend + Rails API

We are launching our company, Dryftwell, this month in Austin, TX!

Our product provides personalized recommendations (like cocktail bars, hiking trails, history museums, etc ) from a local for your upcoming trip.

We are a mobile-first company and our app is very photo-centric. Each recommendation has 5+ photos on the details page so the user can get a good sense of the vibe. So, for us, while we are still in beta, I spent a bit of extra time looking into the best way to handle images.

The photos are uploaded in our React web-based app by locals. The images then need to be stored somewhere (e.g. S3, Cloudinary, etc.). And then the images need to be accessible by our React app and our iOS app to display.

For us, we had 2 main goals with handling our images:

  • photos loaded instantly in the iOS app
  • photos were easy to upload in the react app

Upload images from our React app

Our web-based React app is how we input all data into our system. It’s used by our locals to add new, cool spots in a city, including the photos. All information ultimately displayed in the iOS app is inputted in this app.

We decided early on that we wanted to own our own data. All information displayed in the iOS app isn’t scrapped from Google or Tripadvisor. It’s all collected by us and stored in our own database.

So, this means, we store our own photos as well.

Which image storage to use? Using Amazon S3

There are a few different options for storing photos. We decided to use AWS S3 because it was easy to set up and felt like the right long-term solution. We were worried about not having a CDN set up (we can easily add it) but so far we haven’t had any image performance issues in the app. If that changes, we have a quick lever to pull to make our images load faster with the CDN.

We have, for the short term, sacrificed auto-resizing of images. Right now, we have a member of our team cropping every photo to the correct dimensions before we upload. We’re going to have to solve this soon to move away from our manual and scrappy startup solution.

Where do we upload from? Uploading from the frontend

There’s two schools of thought with how to upload images:

  1. Directly from the React frontend
  2. Save images to Rails backend and then the backend saves to S3

We ended up going with option 1 because it felt like the more fail proof option. If the save is going through the backend, then handling the failure scenarios get more complicated. So far, uploading via React, has worked great.

React (… and Rails too) also has multiple S3 libraries to make the image uploading fairly straightforward so the dev work required wasn’t substantial.

Saving in our Rails backend

Then, once the images are successfully uploaded to S3, then the product is saved with a POST to the Rails backend. The only piece of the images saved to the Rails backend is an array of filenames not the entire URL.

Best practice for storing the images in our database is to store the filename (rather than the full URL) helps if you end up changing your bucket name. Then you can easily swap the ENV in your app rather than having to go back through and update all the urls. Note — pretty surprising how many people try to store the actual image in the DB…do not attempt this! :) Postgres was not meant for that.

Rails API generates the full URL

The backend then generates the URL (with the S3 prefix) to serve to the iOS app + the display pages of the internal tool. When displayed, using the URL, the iOS app and React app both have the permissions to grab those photos and display in the app.

You can see the images displayed in our iOS app all from S3.

Ta-da! All the images are loading really quick. We’re really happy with the images so far. As with anything, I’m sure this will evolve in the future but I feel like we’re at a really great spot right now.

We have over 500 images in S3 bucket and with probably over 2000 by the time we launch next week! But we’re just getting started and excited to see how we build and expand once we get users and feedback.

Hope you enjoyed!

Co-founder of Dryftwell