GoDrive is a cloud-storage backend that lets users upload, store, and manage files — similar to the core backend behind services like Google Drive or Dropbox. It handles user authentication, direct-to-storage uploads, file metadata management, and automated cleanup, all running across independent services.
Under the hood, GoDrive uses a modern microservice architecture built with Go, gRPC, PostgreSQL, MinIO (S3-compatible object storage), and NATS for asynchronous background processing.
- Users sign up and log in using a JWT-based auth service.
- Uploads happen via presigned URLs, which allow files to go directly to MinIO without passing through backend services.
- MinIO triggers upload events, which are published to NATS.
- Background workers consume these events and insert file metadata into PostgreSQL.
- Files can be soft-deleted, and a cleanup worker permanently removes them after a grace period.
- All internal services communicate over gRPC, while external clients use an HTTP gateway built with Gin.
This design mirrors real cloud-storage architectures: storage is decoupled, metadata is centralized, and all heavy processing is event-driven.
- User authentication (bcrypt + JWT)
- Presigned URLs for direct file uploads to MinIO
- Event-driven background processing (MinIO → NATS → worker)
- File metadata service backed by PostgreSQL
- Presigned download URLs for secure file access
- Soft deletion with automatic cleanup workers
- Independent microservices communicating over gRPC
- HTTP Gateway (Gin) for external access
- Containerized setup using Docker Compose
flowchart LR
subgraph Client
A["User / Frontend"]
end
subgraph Gateway
B["HTTP Gateway (Gin)"]
end
subgraph AuthService
C["Auth Service (JWT + bcrypt)"]
end
subgraph MetadataService
D["Metadata Service (Go + PostgreSQL)"]
DB[(PostgreSQL)]
end
subgraph Storage
E["MinIO (Object Storage)"]
end
subgraph Messaging
F["NATS (Event Bus)"]
end
subgraph Workers
G["Upload Worker (record metadata)"]
H["Cleanup Worker (delete expired files)"]
end
%% User -> Gateway
A --> B
%% Gateway -> Services
B --> C
B --> D
B --> E
%% Auth Service -> Postgres
C --> DB
%% Metadata Service -> Postgres
D --> DB
%% Upload Event from MinIO
E -. "upload event" .-> F
F --> G
G --> D
%% Soft delete -> cleanup
D -. "soft delete" .-> H
H --> E
%% User -> MinIO (presigned URL upload)
A -. "presigned URL upload" .-> E
The public-facing HTTP API.
Handles authentication and routes user actions to internal services over gRPC.
Manages signup, login, password hashing, and JWT verification.
Stores metadata in Postgres — filenames, owners, timestamps, sizes, soft-deletes.
This service never touches raw file bytes.
Generates presigned PUT/GET URLs and performs actual file deletion in MinIO.
Receives upload-completion events from MinIO through NATS.
Extracts object info and confirms the upload by inserting metadata.
A background worker that periodically:
- Finds soft-deleted files,
- Deletes them from MinIO,
- Removes metadata rows once cleanup succeeds.
- Postgres → metadata
- MinIO → file storage
- NATS → event bus
- Docker Compose → dev orchestration
- Client logs in and receives a JWT.
- Client requests an upload URL from the Gateway.
- Gateway → Storage Service: “Give me a presigned PUT URL.”
- Storage returns the signed URL.
- Client uploads file bytes directly to MinIO.
- MinIO emits an object-created event to NATS.
- Ingest Service receives the event, parses the object key,
and calls Files Service to insert metadata. - The file now appears in
/files.
- Client calls
DELETE /files/:id. - Files Service marks the DB row with
deleted_at. - Janitor Service routinely:
- Finds expired soft-deleted rows
- Asks Storage Service to remove the object
- Deletes the metadata row if successful
Keeps deletes fast for the user and reliable on the backend.
- Language: Go
- APIs: gRPC, REST (Gin)
- Storage: MinIO (S3-compatible object store), PostgreSQL
- Messaging: NATS
- Auth: JWT, bcrypt
- Containerization: Docker Compose
- Dev Tools: Makefiles, Protoc, Postman