- Scalabale image service that allow users download, search, and upload images.
- Support for Encryption when uploading image, Decryption when downloading image.
- pub/sub when uploading image
- Golang/Chi mux, gRPC for the backend.
- NextJS for the frontend
- GCP (Google Cloud Platform) (Cloud Run, Firestore, Cloud Storage, Pub/Sub) for deploying the backend services.
- Vercel for deploying the frontend.
- Explore Bazel with this project.
Rename .env.example to .env and fill the correct values.
- DONE: make encryption/decryption key read from env variable
- DONE: Pub/Sub when uploading image
We have two type of services gRPC, and RESTful services.
This service is authenticated to call other gRPC services on Google Cloud (Cloud Run), and this is the only services exposed to the world.
Used Technologies: Golang, and Chi mux for handling routs.
- Welcome page: this the root path return Simple html Welcoming the user
/
- Health check
GET /health
- Download image
GET /download/{image_name}
image_name: required
- Search for image
GET /search?q={search_keyword}
search_keyword: optional: if not provided we return latest images uploaded
- Upload Image
This trigger pub/sub service.
POST /upload
multipart/form-data:
username: required: username who is upload the image
file: required: image supported type (png, jpeg, gif)
hashtags: optional: metadata in format ["hashtag1", "hashtags2", ...]
We cannot call those services directly, those services required authentication from the caller in Google Cloud (Cloud Run).
-
Download service that allow user to get download the image by image name.
the service proto is
message DownloadPhotoRequest { string img_name = 1; } message DownloadPhotoResponse { bytes img_blob = 1; } service DownloadPhoto { /* * RPC for download a photo */ rpc Download(DownloadPhotoRequest) returns (DownloadPhotoResponse); }
-
Upload service that allow user upload image with it's metadata to search for image later.
Require username, and file.
Optional hashtags.
the service proto is
message UploadImageRequest { string obj_name = 1; bytes image = 2; } message UploadImageResponse {} message CreateMetadataRequest { string obj_name = 1; string user = 2; repeated string hashtags = 3; } message CreateMetadataResponse {} service UploadPhoto { /* * RPC for upload a photo to the image database */ rpc Upload(UploadImageRequest) returns (UploadImageResponse); /* * RPC for create hashtag-image mapping in the metadata database */ rpc CreateMetadata(CreateMetadataRequest) returns (CreateMetadataResponse); }
-
Search service that allow user to search for images with hashtags attached with the image.
if search keyword is empty it will return latest image uploaded.
the service proto is
message GetThumbnailImagesRequest { // if keyword=="latest", return recent photo // in the service, we will update metadata such as download_times accordingly string search_keyword = 1; } message GetThumbnailImagesResponse { // get the storage image-serving address and return repeated string storage_url = 1; } service GetThumbnail { /* RPC for getting the UIDs of images relevant to the keyword */ rpc GetThumbnail(GetThumbnailImagesRequest) returns (GetThumbnailImagesResponse); }