A production-style REST API that powers a social-media backend with users, posts, comments, and likes. It uses MySQL for durable storage, Redis for hot-path caching and atomic view counting, and ships with Docker/Kubernetes manifests for deployment.
- Performance-minded design: Read-heavy endpoints are cached in Redis; views are incremented atomically in Redis and flushed to MySQL periodically to avoid write amplification.
- Production-ready ergonomics: Health checks, auto-migrations, separate read/write DB handles, versioned routes, and K8s manifests (server, Redis, MySQL primary/replica, Nginx, HPA).
- Go HTTP server using Gorilla
muxand GORM (MySQL driver). - Models:
User,Login,Post(withViews),Comment,Like(unique(PostID,UserID)). - Redis caches list endpoints and post blobs/like counts; background goroutine periodically syncs view counts to MySQL.
- Versioned API under
/apis/v1.
- Language/Frameworks: Go 1.23, Gorilla
mux, GORM - Storage: MySQL 8 (primary/replica ready), Redis 7
- Infra: Docker, Kubernetes (manifests under
hack/deploy/), Nginx, HPA - Testing: Ginkgo + Gomega, Miniredis
- Start dependencies (Docker):
docker run -d --name sm-mysql -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=social_media_app \
mysql:8
docker run -d --name sm-redis -p 6379:6379 redis:7- Export environment variables:
export DB_WRITE_HOST=127.0.0.1:3306
export DB_READ_HOST=127.0.0.1:3306
export DB_USER=root
export DB_PASSWORD=root
export DB_NAME=social_media_app
export REDIS_HOST=127.0.0.1
export REDIS_PORT=6379
export SERVER_PORT=8080- Build and run:
go mod download
go build -o bin/server ./cmd/server
./bin/server- Smoke test:
curl -i http://localhost:8080/apis/v1/health
curl -X POST http://localhost:8080/apis/v1/user \
-H 'Content-Type: application/json' \
-d '{"username":"alice","email":"alice@example.com","password":"secret"}'
curl -X POST http://localhost:8080/apis/v1/post \
-H 'Content-Type: application/json' \
-d '{"user_id":1,"title":"Hello","content":"World"}'
curl http://localhost:8080/apis/v1/post/1
curl http://localhost:8080/apis/v1/post- Health:
GET /apis/v1/health - Users:
GET /user,POST /user,GET|PATCH|DELETE /user/{user_id} - Posts:
GET /post,POST /post,GET|PATCH|DELETE /post/{post_id} - Likes:
POST|DELETE /post/{post_id}/likes - Comments:
GET|POST /post/{post_id}/comments,PATCH|DELETE /comments/{comment_id}
Note: Create/update endpoints return a simple { "message": "..." }. Fetch the resource after a mutation.
- Separate
DBReaderandDBWriterGORM connections for read/write split. - Redis keys: list caches (
userlist,postlist), per-post blobs (post:{id}), per-post likes (post:{id}:likes), and views (post:{id}:views). - Background job started at boot to
SyncViewsToDBon an interval. - Health check verifies both MySQL and Redis connectivity.
- Manifests:
hack/deploy/{mysql,redis,server,nginx} - With Minikube:
minikube start
kubectl apply -f hack/deploy/mysql/
kubectl apply -f hack/deploy/redis/
kubectl apply -f hack/deploy/server/
kubectl apply -f hack/deploy/nginx/- The
Makefiletargetmake buildbuilds, loads into Minikube, and rolls out the image (scales down/up safely).
cmd/server: entrypoint wiring config → DBs → Redis → router → HTTP serverpkg/api/handlers: HTTP handlers (users, posts, comments, likes, health)pkg/models: GORM models (User,Login,Post,Comment,Like)pkg/database: DB init, connection, and migrationspkg/config: env var configpkg/utils: JWT token helpershack/deploy: Kubernetes manifests (MySQL primary/replica, Redis, server, Nginx)
- Passwords are hashed with bcrypt at signup.
- Access/refresh JWTs are generated and stored with the
Loginrecord but not yet returned or enforced; the API is effectively open. Add middleware + login endpoint to enable auth.
- CORS middleware and proper auth/login + token verification.
- Pagination, filtering, and sorting for list endpoints.
- Rate limiting and metrics endpoint (Prometheus) re-enable.
- Return created/updated resources in mutation responses.