Back to projects
[01]Backend, BankingFEATURED

SimpleBank

2024 – 2025

SWAGGER UI

SimpleBank Swagger UI showing API endpoints — create_user, login_user, update_user, verify_email

Auto-generated OpenAPI docs served at /swagger/

WHAT IT DOES

SimpleBank is a production-grade banking backend API built with Go. It handles core banking operations through a dual-protocol server that serves both gRPC and HTTP/JSON from a single service definition. The system includes user authentication, account management with multi-currency support, deadlock-free money transfers, and an async email verification pipeline powered by Redis.

  • Account ManagementCreate and manage bank accounts with multi-currency support (USD, EUR, CAD)
  • Money TransfersTransfer funds between accounts with PostgreSQL transaction isolation (deadlock-free)
  • User AuthenticationPASETO token-based auth with access/refresh token rotation and session tracking
  • Email VerificationAsync email verification workflow via Redis task queue with retry logic
  • Role-Based Access Controldepositor and banker roles with per-endpoint authorization
  • Dual Protocol APISingle service serves both gRPC (binary) and HTTP/JSON via gRPC-Gateway

WHY I BUILT IT

I wanted hands-on experience with production backend patterns that go beyond simple CRUD. This project covers gRPC + HTTP dual serving (common in microservice architectures), async task processing with Redis-backed job queues, database transaction patterns with deadlock prevention, and token-based auth with PASETO. It also gave me practice with type-safe SQL via sqlc and graceful shutdown orchestration using Go's errgroup.

TECH STACK

API & LANGUAGE
Go 1.23gRPCgRPC-GatewayProtocol Buffers
DATABASE & STORAGE
PostgreSQL 16sqlcgolang-migrateRedis 7
AUTH & SECURITY
PASETO v2RBAC
ASYNC & WORKERS
AsynqRedis Task Queue
INFRA & TOOLING
DockerDocker ComposeKubernetes (EKS)zerologSwagger / OpenAPI

ARCHITECTURE

Client ├─ HTTP/JSON ──→ HTTP Gateway (:8080) └─ gRPC ───────→ gRPC Server (:9090) │ Auth Middleware (PASETO + RBAC) │ RPC Handlers ┌────┴────┐ │ │ Store Layer Task Distributor (sqlc) │ │ Redis Queue Transaction │ Manager Task Processor │ (10 + 5 workers) PostgreSQL │ Mail Sender

Request flow — Client → Auth Middleware → Handlers → Store/Redis → PostgreSQL

KEY CHALLENGES

Dual Protocol Serving (gRPC + HTTP)

A single service definition in Protocol Buffers serves both gRPC and HTTP/JSON simultaneously. The HTTP gateway translates JSON requests into gRPC calls, sharing all handler logic without duplication.

Deadlock-Free Money Transfers

The TransferTx implementation orders account locks by ID to prevent deadlocks when concurrent transfers occur between the same pair of accounts. This ensures safe parallel execution without serializing all transfers.

Transaction Composition with Callbacks

Database transactions use a callback pattern that allows composing multiple operations atomically. For example, CreateUserTx creates a user record AND queues an email verification task within the same transaction boundary.

Async Email Verification Pipeline

User registration triggers an async task via Redis/Asynq. The worker generates a secret code, stores it with a 15-minute TTL, and sends a verification email. Priority queues (critical: 10 workers, default: 5) ensure throughput.

Graceful Shutdown Orchestration

Uses Go's errgroup to manage three concurrent services (gRPC server, HTTP gateway, task processor). On SIGTERM/SIGINT, each component shuts down cleanly — gRPC finishes in-flight RPCs, HTTP drains connections, and the worker completes running tasks.

RBAC at the Handler Level

Authorization is enforced per-RPC with role lists. For example, UpdateUser allows both the banker role (can update any user) and the user themselves (can only update their own profile).

HOW TO RUN

git clone https://github.com/moolair/simplebank-golang-backend.git
cd simplebank-golang-backend
docker compose up --build

Starts PostgreSQL, Redis, and the API server. Migrations run automatically on startup. HTTP Gateway at :8080, gRPC at :9090, Swagger UI at /swagger/.

API ENDPOINTS

MethodEndpointAuthDescription
POST/v1/create_userNoRegister a new user
POST/v1/login_userNoLogin and get tokens
PATCH/v1/update_userYesUpdate user profile
GET/v1/verify_emailNoVerify email with code

FUTURE IMPROVEMENTS

  • Real-time notifications via WebSocket for live transaction alerts
  • CI/CD pipeline with GitHub Actions for automated testing and Docker publishing
  • Helm charts with ArgoCD for GitOps-based deployment on EKS
  • Paginated transaction history API with filtering and search