{"id":37156501,"url":"https://github.com/ymanshur/simplebank","last_synced_at":"2026-01-14T18:34:03.156Z","repository":{"id":148711525,"uuid":"610656510","full_name":"ymanshur/simplebank","owner":"ymanshur","description":"A simple bank service in Go","archived":false,"fork":false,"pushed_at":"2025-12-06T13:20:27.000Z","size":7327,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-10T07:58:05.941Z","etag":null,"topics":["gin","grpc","kubernetes","learning-project"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ymanshur.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-03-07T08:06:37.000Z","updated_at":"2025-12-06T13:20:31.000Z","dependencies_parsed_at":"2025-10-06T06:26:34.060Z","dependency_job_id":null,"html_url":"https://github.com/ymanshur/simplebank","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ymanshur/simplebank","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymanshur%2Fsimplebank","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymanshur%2Fsimplebank/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymanshur%2Fsimplebank/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymanshur%2Fsimplebank/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ymanshur","download_url":"https://codeload.github.com/ymanshur/simplebank/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ymanshur%2Fsimplebank/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28430848,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T16:38:47.836Z","status":"ssl_error","status_checked_at":"2026-01-14T16:34:59.695Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gin","grpc","kubernetes","learning-project"],"created_at":"2026-01-14T18:34:02.519Z","updated_at":"2026-01-14T18:34:03.142Z","avatar_url":"https://github.com/ymanshur.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Simple Bank Service\n\n[![CI](https://github.com/ymanshur/simplebank/actions/workflows/ci.yml/badge.svg)](https://github.com/ymanshur/simplebank/actions/workflows/ci.yml)\n\nThis repo is perhaps the first project I've undertaken outside of my primary professional focus.\n\nI am committed to maintaining this repository as a resource for my professional development in Go. I intend that this repository will serve as a valuable asset for anyone seeking to learn how to develop robust software products using Go best practices.\n\nPlease let me know if you have any requests or problems about this project by creating an issue or discussion\n\nThank you for watching!\n\n## About\n\nSimple Bank Service is a comprehensive banking API that provides secure account management, money transfers, and user authentication with email verification.\n\n### Key Responsibilities\n\n- Create and manage bank accounts, which are composed of the owner’s name, balance, and currency.\n- Record all balance changes to each of the accounts. So every time some money is added to or subtracted from the account, an account entry record will be created.\n- Perform a money transfer between 2 accounts. This should happen within a transaction, so that either both accounts' balances are updated successfully or none of them are.\n- Handle user registration, authentication, and email verification\n\n**TODO APIs including:**\n\n1. Top up a balance account through a payment gateway such as Midtrans.\n2. Release the balance from an account in the booking-action schema.\n\n### Features\n\n- **Graceful shutdown**: It can stop receiving new requests, and wait for all on-going requests to be completed before shutting down (related issue [#28](https://github.com/ymanshur/simplebank/issues/28))\n\n## Architecture Overview\n\n### System Context\n\n![Simple Bank Architecture Diagram](assets/simple-bank-architecture.svg)\n\n### Key Components\n\n- **HTTP API Server (Gin)** - REST endpoints for web clients with JWT authentication\n- **gRPC Server** - High-performance API for service-to-service communication\n- **gRPC Gateway** - Translates HTTP requests to gRPC calls for unified API access\n- **Database Layer (SQLC)** - Type-safe SQL operations with transaction support\n- **Background Workers (Asynq)** - Asynchronous email processing and task management\n- **Token Management** - Dual support for JWT and PASETO tokens\n\n### Data Flow\n\n1. **Client Request** - HTTP request hits gRPC Gateway or direct gRPC call\n2. **Authentication** - Token validation using JWT/PASETO makers\n3. **Business Logic** - Request processed through appropriate handler (`api/` or `gapi/`)\n4. **Database Operations** - SQLC-generated code executes type-safe SQL queries\n5. **Background Tasks** - Email verification and other async tasks queued to Redis\n6. **Response** - JSON response returned via HTTP or gRPC protocol\n\n## Project Structure\n\n```bash\nsimplebank/\n├── api/                 # HTTP/REST API handlers (Gin framework)\n│   ├── server.go        # HTTP server setup and routing\n│   ├── account.go       # Account management endpoints\n│   ├── transfer.go      # Money transfer endpoints\n│   ├── user.go          # User management endpoints\n│   └── middleware.go    # Authentication middleware\n├── gapi/                # gRPC API handlers\n│   ├── server.go        # gRPC server setup\n│   ├── rpc_*.go         # Individual RPC method implementations\n│   └── converter.go     # Protocol buffer conversions\n├── db/                  # Database layer\n│   ├── migration/       # SQL migration files\n│   ├── query/           # SQL query definitions\n│   ├── sqlc/            # Generated type-safe Go code\n│   └── mock/            # Generated mock interfaces\n├── pkg/                 # Shared packages\n│   ├── token/           # JWT and PASETO token management\n│   ├── util/            # Configuration and utilities\n│   ├── worker/          # Background task processing\n│   └── mail/            # Email sending functionality\n├── proto/               # Protocol buffer definitions\n├── pb/                  # Generated protobuf Go code\n├── docs/                # API documentation and Swagger specs\n├── deployment/          # Docker configuration\n│   ├── Dockerfile       # Multi-stage build configuration\n│   └── start.sh         # Container startup script\n├── docker-compose.yaml  # Local development environment\n├── Makefile             # Build and development commands\n└── main.go              # Application entry point\n```\n\n## Technology Stack\n\n### Core Technologies\n\n- **Language:** Go (1.24.6) - Chosen for performance, concurrency, and strong typing\n- **HTTP Framework:** Gin - Fast HTTP web framework with middleware support\n- **gRPC Framework:** Google gRPC - High-performance RPC framework with Protocol Buffers\n- **Database:** PostgreSQL - ACID-compliant relational database for financial data\n- **Cache/Queue:** Redis - In-memory store for background task queuing\n- **Containerization:** Docker - Containerization for development and deployment\n- **CI/CD:** GitHub Actions - Continuous integration and testing\n\n### Key Libraries\n\n- [SQLC](https://github.com/sqlc-dev/sqlc) - Generates type-safe Go code from SQL queries\n- [Migrate](https://github.com/golang-migrate/migrate) - Database migration management\n- [Asynq](https://github.com/hibiken/asynq) - Distributed task queue for background processing\n- [Viper](https://github.com/spf13/viper) - Configuration management with environment variable support\n- [Zerolog](https://github.com/rs/zerolog) - Structured logging with JSON output\n- [Testify](https://github.com/stretchr/testify) - Testing toolkit with assertions and mocks\n- [PASETO](https://github.com/o1egl/paseto) - Specification and reference implementation for secure stateless tokens.\n- [CORS](https://github.com/rs/cors) - Cross Origin Resource Sharing W3 specification\n\n## Running The Services\n\n1. Clone the repository\n\n    ```bash\n    git clone https://github.com/ymanshur/simplebank.git\n    ```\n\n2. [Dependencies installation](#dependencies)\n3. [Setup infrastructure](#setup-infrastructure)\n4. [Run and test your services](#run-your-services-on-the-local-machine)\n\n### Dependencies\n\n- [Go](https://golang.org/) v1.23\n- [Migrate CLI](https://github.com/golang-migrate/migrate/tree/master/cmd/migrate) is database migrations written in Go\n\n    ```bash\n    # Versioned installation\n    mkdir -p $GOPATH/src/github.com/golang-migrate\n    git clone github.com/golang-migrate/migrate $GOPATH/src/github.com/golang-migrate/\n    cd $GOPATH/src/github.com/golang-migrate/migrate/cmd/migrate\n    git checkout $TAG  # e.g. v4.15.0\n\n    # Replace the postgres build tag with the appropriate database tag(s) for the desired databases\n    go build -tags 'postgres' -ldflags=\"-X main.Version=$(git describe --tags)\" -o $GOPATH/bin/migrate $GOPATH/src/github.com/golang-migrate/migrate/cmd/migrate/\n    ```\n\n- [SQL Compiler](https://docs.sqlc.dev/en/latest/overview/install.html) that generates type-safe code from SQL\n\n    ```bash\n    go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest\n\n    ```\n\n    for Go version under 1.21\n\n    ```bash\n    sudo snap install sqlc\n    ```\n\n- [GoMock](https://github.com/golang/mock) is a mocking framework for the Go programming language\n\n    ```bash\n    go install github.com/golang/mock/mockgen@v1.6.0\n    ```\n\n    Alternatively, use a [maintained fork](https://github.com/uber-go/mock?tab=readme-ov-file#installation) instead\n\n    ```bash\n    go install go.uber.org/mock/mockgen@latest\n    mockgen -version\n    ```\n\n- [DB Docs](https://dbdocs.io/docs) is a simple tool to create web-based documentation for your database.\n\n    ```bash\n    npm install -g dbdocs\n    dbdocs login\n    ```\n\n- [DBML CLI](https://www.dbml.org/cli/#installation)\n\n    DBML (Database Markup Language) is an open-source DSL language designed to define and document database schemas and structures.\n\n    ```bash\n    npm install -g @dbml/cli\n    ```\n\n    `dbml2sql` is used to convert a DBML file to SQL\n\n    ```bash\n    dbml2sql --version\n    ```\n\n- Install gPRC, OpenAPI, and Statik dependencies by\n\n    ```bash\n    # Go v1.24\n    go install tool\n    ```\n\n    According to [tool directive](https://github.com/grpc-ecosystem/grpc-gateway?tab=readme-ov-file#using-the-tool-directive-in-go-124) for dependencies of binary package\n\n### Setup infrastructure\n\nStart database PostgreSQL container service:\n\n```bash\nmake postgres\n```\n\nCreate `simplebank` database:\n\n```bash\nmake createdb\n```\n\nRun db migration up all versions:\n\n```bash\nmake migrateup\n```\n\nRun db migration down all versions:\n\n```bash\nmake migratedown\n```\n\n### Run your services on the local machine\n\n```bash\nmake server\n```\n\nTest your services:\n\n```bash\nmake test\n```\n\n### Run your services and the infrastructures in Docker containers\n\nComplete the necessary environment variables in the app.env (copy from [app.env.example](/app.env.example)) file.\n\nThe following command will create PosgreSQL and Redis volume data in [tmp](tmp) directory and run the [docker-compose.yaml](deployment/docker-compose.yaml) file with build in detach mode.\n\n```bash\nmake containers\n```\n\nAlternatively, if you have already created PostgreSQL and Redis containers, you just have to run the following command to create only the application container\n\n```bash\nmake run\n```\n\n## Documentation\n\n### Database\n\nUpdate your database design in [docs/schema.dbml](docs/schema.dbml), build the DB documentation:\n\n```bash\nmake dbdocs\n```\n\nYou can access my DB documentation for this project at [this address](https://dbdocs.io/ymanshur/simplebank)\n\n### OpenAPI\n\nOpen \u003chttp://localhost:8080/swagger\u003e to see API documentation based on the gRPC Gateway proto definition, see my own at [this address](https://ymanshur.github.io/simplebank/docs/swagger/)\n\n## Code Generation\n\nGenerate schema SQL file with DBML CLI:\n\n```bash\nmake dbschema\n```\n\nGenerate SQL CRUD with `sqlc`:\n\n```bash\nmake sqlc\n```\n\nGenerate DB mock with GoMock:\n\n```bash\nmake mock\n```\n\nCreate a new DB migration:\n\n```bash\nmake migratecreate name=\u003cmigration_name\u003e\n```\n\nGenerate [protobuf](https://grpc.io/docs/languages/go/quickstart/#regenerate-grpc-code) files and update the [API documentation](#openapi)\n\n```bash\nmake proto\n```\n\n## Tips\n\n### How to hit the endpoint using [endpoints.http](docs/collection.http) as a playground\n\n1. Install [REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) extension\n2. To control environment variables, add the following lines to .vscode/settings.json\n\n    ```json\n    \"rest-client.environmentVariables\": {\n        \"local\": {\n            \"authority\": \"localhost:8000\",\n            \"accessToken\": \"\",\n            \"refreshToken\": \"\"\n        },\n    },\n    ```\n\n3. Copy the returning access and refresh token into environment variables\n4. Run the HTTP or Gateway server and follow REST Client documentation to [make a request](https://github.com/Huachao/vscode-restclient?tab=readme-ov-file#making-request)\n\n    ![REST Client Example](assets/rest-client-example-1.png)\n\n### Control Workspace environment variables\n\nAdd the following line to .vscode/settings.json\n\n```json\n{\n    \"terminal.integrated.env.linux\": {\n        \"POSTGRES_USER\": \"\",\n        \"POSTGRES_PASSWORD\": \"\",\n        \"DB_NAME\": \"simplebank\"\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fymanshur%2Fsimplebank","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fymanshur%2Fsimplebank","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fymanshur%2Fsimplebank/lists"}