Best Practices: Image Organization & Retrieving
What is the best way to organize images (and their respective thumbnail URLs)?
I wanted to post for input/discussion on how to best do this in your application for security and performance concerns. I know there are a lot of videos on how to upload your images, but not so much on the best way to store them and retrieve them.
Currently I have a database with an images table that stores the stem of the URL on EC2, and I use S3 & RDS.
-
File Structure
What is the recommended approach for a scalable image files system? I've seen file structures that organize by just date, and others that have tons of nested folders, is there a more scalable approach between the two?
- Should you organize images by user, by date, by the first letter of the hashed name as the folder or maybe a file prefix?
- Is there any latency added to having thousands of files in on directory, even if you are resolving one image directly each time?
-
Resolving URLs
Right now I am using a helper to construct the image URL based on the function called and the environment. That way we can move production data to test environments by just copying the bucket and its contents in AWS, and not have to edit the database.
So for example:
<img src="{{\Imager::getURL($mainImage->url)}}" alt="Profile Image">or
<img src="{{\Imager::getThumb($mainImage->url)}}" alt="Profile Image">Where $mainImage->url is
/lorem/ipsum/dolor.jpgand the functions would resolve to eithers3.amazonurlhere.com/images/lorem/ipsum/dolor.jpgfor the full image ors3.amazonurlhere.com/thumbs/lorem/ipsum/dolor.jpgfor the thumbnail.- Is it a bad approach to decouple the data and the application domain, or should the full URL be stored in the database?
- Is it better to just store the thumbnail URL in the database? It seems like either way, admin error could easily break images and make it impossible to find where to point to.
-
Database URL Lookups with Domains
I suspect that resolving to the AWS bucket URL is a bit of a security concern. While I'm not sure exactly what that might expose me to, I feel like the most obvious solution would be to rely on a new route and controller function render the image via PHP.
So for example:
myapp.com/images/rawRender/slugwould go to the images controller function, do a database lookup of the uniqueslug, resolve the AWS url of that image and then do a PHP render.My concern is that may be a performance hit. If you are on a page of 50 or so images, there's no way to eager-load those database calls. So as the page loads each image, it will do an additional query, and render accordingly. It's just one row per image, but I feel like it may be a concern as the application scales.
- Is this truly a concern or perhaps more of a long-term load balancing issue?
Please or to participate in this conversation.