2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-30 01:25:45 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00
2026-01-08 01:15:07 +00:00

simple_bank

simple_bank is a small example backend service in Go that demonstrates a banking-style API with:

  • HTTP gateway (grpc-gateway) and gRPC server
  • PostgreSQL for persistent storage (SQLC generated queries)
  • Redis + Asynq for background task queue / worker processing
  • Migrations via golang-migrate
  • Email verification task example

This repository is intended as a reference/demo for building a production-ish Go service with background jobs.


Features

  • RESTful HTTP gateway (default :8080) backed by gRPC (default :9090)
  • gRPC API and generated protobufs (uses grpc-gateway)
  • Database operations generated with sqlc
  • Background job dispatching and processing with asynq (Redis)
  • Config-driven via environment variables
  • Example Send Verification Email background task

Prerequisites

  • Go 1.20+ (or compatible)
  • PostgreSQL
  • Redis
  • make/migrate/other CLIs (optional for migrations)
  • Docker & Docker Compose (recommended for local dev)

Quickstart (development)

  1. Copy environment example (or use api.env):

    • Main variables you will want to set:
      • DB_ADDR (Postgres connection string)
      • REDIS_ADDR (Redis host:port)
      • HTTP_SERVER_ADDR (default :8080)
      • GRPC_SERVER_ADDR (default :9090)
      • ENVIRONMENT (e.g. development to enable console logs)
  2. Start local infra with Docker Compose (if you want local Postgres + Redis):

    • (This repo includes a docker-compose.yml with Postgres and Redis)
    • Example:
      • docker-compose up -d
    • Confirm Postgres and Redis are reachable at the addresses in your env.
  3. Run DB migrations:

    • Using golang-migrate CLI (example):
      • migrate -path db/migrations -database "postgres://postgres:postgres@localhost:5432/simple_bank?sslmode=disable" up
    • Adjust the database URL to match your DB_ADDR environment variable.
  4. Download dependencies and build:

    • go mod download
    • go build -o simple_bank ./...
  5. Run the service:

    • With the environment loaded (example):

      • export $(cat api.env | xargs) # or use your preferred env loader
      • ./simple_bank
    • Running the binary will:

      • start the task processor (asynq server) that consumes background jobs
      • start gRPC server (on GRPC_SERVER_ADDR)
      • start the HTTP gateway (on HTTP_SERVER_ADDR) in a goroutine/handler
    • Alternatively, run directly with go run:

      • go run ./main.go
  6. Verify:

    • HTTP gateway: http://localhost:8080 (or whatever HTTP_SERVER_ADDR you configure)
    • gRPC: connect at the configured GRPC_SERVER_ADDR
    • Redis dashboard / Redis Commander: if using docker-compose, a redis-commander service may be available

Background Worker (Asynq)

  • Tasks are enqueued by the app and processed by an asynq server embedded in the application.
  • The worker configuration (queues and handlers) lives under worker/:
    • worker.NewRedisTaskProcessor creates the asynq server (asynq.Server) with queue weights and error handler.
    • worker.NewRedisTaskDistributor creates a client to enqueue tasks.
    • Example queue names: CriticalQueue, DefaultQueue.

Customizing logs and formatting for asynq:

  • The asynq server can be given a custom logger via asynq.Config.Logger. This project includes worker/logger.go which adapts logs to zerolog. Edit worker/logger.go if you want to change asynq log formatting/fields.
  • If you also want to capture/format other libraries' logs (for example libraries that use the standard log package), redirect stdlib logs to your zerolog instance at startup.

Environment Variables

Important variables (see api.env for full list):

  • Server:
    • HTTP_SERVER_ADDR (default :8080)
    • GRPC_SERVER_ADDR (default :9090)
    • ENVIRONMENT (development for console logs)
  • Database:
    • DB_DRIVER (e.g. pgx)
    • DB_ADDR (postgres connection string)
    • MIGRATIONS_URL (e.g. file://db/migrations)
  • Redis:
    • REDIS_ADDR (e.g. localhost:6379)
    • REDIS_PASSWORD
    • REDIS_DB
  • Auth / Tokens:
    • AUTH_TOKEN_SECRET, AUTH_TOKEN_EXP, REFRESH_TOKEN_EXP
  • Email:
    • EMAIL_FROM, EMAIL_SMTP_PASSWORD (used by the worker email task)
  • Rate limiter:
    • RATE_LIMITER_REQS_COUNT, RATE_LIMITER_TIME_FRAME, RATE_LIMITER_ENABLED

Testing

  • Unit tests:
    • go test ./...
  • Integration tests:
    • Ensure Postgres and Redis are running and configured as in api.env before running tests that depend on external services.

Development tips

  • To change queue weights, error handling or task handlers, edit worker/processor.go.
  • To change how tasks are enqueued, review worker/distributer.go.
  • To adjust logging format globally, modify main.go startup logger configuration and worker/logger.go.
  • Protobuf / gRPC: regenerate stubs if you change proto files (this project uses pb/ and generated code).

Project layout (high level)

  • main.go — application entrypoint
  • api/ — Gin HTTP handlers (HTTP server)
  • gapi/ — gRPC server, grpc-gateway wiring
  • worker/ — asynq task distributor & processor, custom logger
  • db/ — SQLC generated code and migrations
  • pb/ — generated protobuf/gRPC code
  • docs/statik — static files (swagger UI) bundled with the binary

Troubleshooting

  • If migrations fail:
    • Confirm DB_ADDR is correct and database is reachable.
    • Check that db/migrations contains the migration files and paths are correct.
  • If Redis jobs don't process:
    • Confirm the app can reach Redis (REDIS_ADDR).
    • Ensure the process that runs the asynq server is running (the app starts it by default).
  • If logs appear in different formats:
    • Redirect stdlib logs into zerolog or update worker/logger.go to include more structured context.

Contributing

  • Fork and open pull requests.
  • Keep changes small and focused; add/update unit tests where appropriate.

If you'd like, I can:

  • Add a short example curl snippet for the HTTP API endpoints.
  • Add a sample docker-compose snippet and explicit commands for local development.
  • Add a "Deploy" section with production tips (env secrets, TLS, metrics, etc.).
S
Description
No description provided
Readme
41 MiB
0 Stars 1 Watchers 0 Forks
Languages
Go 94%
Shell 4%
Makefile 1.7%
Dockerfile 0.3%