In this design system, we will explore the intricacies of a secure image-sharing platform. We'll cover various important aspects, such as how images are delivered on the platform, incorporating Gravatar, improving query performance, setting up an API server, utilizing a content delivery network, and adding tags to photos. The design system also sheds light on the platform's database structure, placing emphasis on security considerations and the overall system architecture.
Agenda
- Designing Gravatar
- On-demand Image optimisation
- Tagging photos
- Designing newly unread message indicator
How Images are served
Once the request hits the server
- Reads the URL
- Reads the file from the server at the path (Reads the file from S3)
- Sends the response
Let’s build Gravatar
What is gravatar?
Gravatar is your single embeddable URL for profile picture
https://gravatar.com/{hash(email)}
→ Security (Protecting Personally Identifiable Information)
This URL will display your current profile picture.
Requirements
- Users can upload multiple pictures.
- Users can designate one as active.
- The active picture should be returned as part of the response.
Query Optimization
The following SQL query is highly inefficient and costly. The WHERE clause requires computation and cannot take advantage of indexes.
So, what's the more efficient query?
Updating the photo to mark it active
Getting the active photo
How can we make the above query much better? (As this query is frequently used)
Add a column named active_photo_id
But then we need to update the other queries? YES
Let’s get going by creating an API Server
Uploading a photo api.gravatar.com
Prepare for upload
S3://gravatar/{user_id}/{random_photo_id}
- User requests photo upload service for a new upload
- Photo upload service generates a random id
- Photo upload service generates signed
- Photo upload service sends signed URL to user
Upload Photo
User uploads photo to S3 using pre-signed urls (Learn in-depth about it here)
Render the active photo
To render the active photo for a user, follow these steps:
-
Retrieve the Photo Information
First, you need to obtain the necessary information for rendering the active photo. Here's how to do it:
- Get the
{hash}
from the URL. - Retrieve the active photo's ID from the database using SQL:
- Get the
-
Retrieve the Photo File
Once you have the active photo's ID, you can fetch the actual photo file from an S3 bucket. Use the following S3 path to access the image:
-
Render the Active Photo
Now that you have the image file, you can render it in your HTML or Markdown content using the following
<img>
tag:
Using a CDN to Serve Content
When it comes to serving content efficiently, Content Delivery Networks (CDNs) can play a crucial role. In this example, we'll configure a CDN for gravatar.com
to optimize the delivery of images from our API server at api.gravatar.com/photos
.
Step 1: Configure the CDN
To set up the CDN, follow these steps:
- Configure a CDN with the origin
gravatar.com
, which will point to our actual API server atapi.gravatar.com/photos
.
Step 2: Handling Cache Miss
In some cases, the CDN may experience a cache miss, meaning it doesn't have the requested content in its cache. In such situations, you can redirect the request to the API server to retrieve the content dynamically. Here's how:
- When a cache miss occurs, redirect the request from
https://gravatar.com/hash
tohttps://api.gravatar.com/photos/hash
.
Overall architecture for Gravatar
Tags in photos
Brainstorm
- Who can tag (Authorization) (
Soon
) - Maximum limit of people tag in a photo (
Soon
) - Notification & Throttling (
Soon
) - Self-removal (
Soon
) - Face-recognition & suggestion (SLA) (
Soon
) - Profile Activity (DB) (
Soon
)
Relative Positioning
Location = $(320.720, 120/720)$
This allows us to handle multiple on-demand transformations, it is really necessary to store relative position of the bounding box (or) co-ordinates, as the size of the picture may differ on different devices (It will be a efficient so long as the aspect ratio of the image doesn’t change)
Bounding Box = $LTRB/x,y,w,h$
$L$ = Left
$T$ = Top
$R$ = Right
$L$ = Bottom