FernandoJVideira c4ee0ce4dc chore: rename simple_bank to api_tmpl and clean up for template use
Rename the module, proto service, and all identifiers from simple_bank/
SimpleBank to api_tmpl/ApiTmpl, and regenerate the gRPC/gateway/swagger/
mock code accordingly.

- Scrub real secrets (SMTP password, auth token secret) from api.env/
  api_test.env, untrack them, and add api.env.example/api_test.env.example
- Remove committed build artifacts (tmp/main, tmp/build-errors.log,
  dbml-error.log) and gitignore them going forward
- Fix Dockerfile paths (build target, migrations copy) that referenced a
  stale project layout
- Rewrite README to match the actual cmd/ + internal/ structure and add a
  "using this as a template" section
2026-08-25 03:02:37 +01: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

api_tmpl

A Go backend service template with a working authentication flow (register, login, email verification, refresh tokens), built to be cloned and renamed for new projects rather than run as-is.

Included out of the box:

  • Gin-based HTTP API (internal/handlers/http) with an equivalent gRPC + grpc-gateway API (internal/handlers/grpc, currently wired up but disabled in main.go — see below)
  • PostgreSQL persistence via sqlc-generated queries (internal/db/sqlc)
  • Redis + Asynq background task queue, with an example "send verification email" task
  • PASETO/JWT auth token issuance and middleware, with role-based access control
  • Migrations via golang-migrate
  • Swagger/OpenAPI docs, served both via swaggo (Gin) and grpc-gateway's generated spec
  • Bruno API collection for manual testing (Bruno/)

Using this as a template

  1. Rename the module: replace github.com/FernandoJVideira/api_tmpl with your own module path throughout the repo, and update module in go.mod.
  2. Copy the env templates and fill in real values:
    cp api.env.example api.env
    cp api_test.env.example api_test.env
    
    At minimum, set a real AUTH_TOKEN_SECRET (32+ random characters) and, if you plan to use the email-verification worker task, real SMTP credentials. Neither api.env nor api_test.env is tracked in git (see .gitignore) — don't commit real secrets into their place.
  3. If you rename the module or the gRPC service, regenerate the protobuf/gateway/swagger code:
    make proto
    make mock
    
    This requires protoc, protoc-gen-go, protoc-gen-go-grpc, protoc-gen-grpc-gateway, protoc-gen-openapiv2, and statik on your PATH (brew install protobuf, then go install the rest — see Makefile proto target for the exact plugins).
  4. Update PROJ_NAME / SERVICE_NAME in api.env and api_test.env, and the Swagger metadata in cmd/api/main.go (@title, @description, @contact.email) and proto/service_api_tmpl.proto.

Prerequisites

  • Go 1.25+
  • PostgreSQL, Redis (or use docker-compose.yml for local instances)
  • sqlc, golang-migrate, air (hot reload) — all optional but expected by the Makefile
  • protoc + Go plugins (only needed if you touch proto/*.proto — see above)

Quickstart (development)

  1. Copy env files and fill in secrets (see Using this as a template).
  2. Start local Postgres + Redis:
    make up
    
  3. Run DB migrations:
    make migrate-up
    
  4. Run the server with hot reload:
    make server
    
    Or without air:
    go run ./cmd/api
    
  5. Verify:
    • HTTP API: http://localhost:8080/api/v1/... (see routes in internal/handlers/http/server.go)
    • Swagger UI: http://localhost:8080/swagger/index.html
    • Redis Commander (from docker-compose.yml): http://localhost:8081

By default main.go only starts the Gin HTTP server and the Asynq task processor — the gRPC server and grpc-gateway (runGrpcServer / runGatewayServer in cmd/api/main.go) are implemented but commented out. Uncomment them if you want the gRPC/gateway path running alongside the Gin server.


Background worker (Asynq)

  • Tasks are enqueued by the app and processed by an Asynq server embedded in the same binary.
  • internal/worker/distributer.go — enqueues tasks (TaskDistributor).
  • internal/worker/processor.go — consumes tasks, registers handlers, configures queue weights.
  • internal/worker/task_send_verify_email.go — example task: sends a verification email after user registration.
  • internal/worker/logger.go adapts Asynq's logger to zerolog; edit it to change log formatting.

Environment variables

See api.env.example for the full list with defaults. Notable ones:

  • Server: HTTP_SERVER_ADDR, GRPC_SERVER_ADDR, ENVIRONMENT, ALLOWED_ORIGINS
  • Database: DB_ADDR, MIGRATIONS_URL
  • Redis: REDIS_ADDR, REDIS_PASSWORD, REDIS_DB
  • Auth: AUTH_TOKEN_SECRET, AUTH_TOKEN_MIN_KEY_SIZE, AUTH_TOKEN_EXP, REFRESH_TOKEN_EXP, AUTH_TOKEN_ISS, AUTH_TOKEN_AUD
  • Email: EMAIL_FROM, EMAIL_FROM_NAME, EMAIL_SMTP_PASSWORD
  • Rate limiter: RATE_LIMITER_REQS_COUNT, RATE_LIMITER_TIME_FRAME, RATE_LIMITER_ENABLED

Testing

make test          # go test -v -cover -short ./...

internal/db/sqlc tests hit a real Postgres instance (make up && make migrate-up first). Everything else runs against mocks generated with mockgen (make mock).


Project layout

  • cmd/api/main.go — application entrypoint (wires config, DB, Redis, servers)
  • cmd/db/migrations, cmd/db/query — SQL migrations and queries consumed by sqlc
  • internal/handlers/http — Gin HTTP handlers, routes, middleware
  • internal/handlers/grpc — gRPC server + grpc-gateway wiring
  • internal/service — business logic shared by both HTTP and gRPC handlers
  • internal/db/sqlc — generated DB access layer (Store interface + queries)
  • internal/auth — PASETO/JWT token makers
  • internal/security — password hashing
  • internal/worker — Asynq task distributor/processor
  • internal/mailer — email sending
  • internal/config — env-based configuration (viper)
  • internal/val — request validators
  • internal/domain/role — role constants for RBAC
  • pb/ — generated protobuf/gRPC/gateway code (regenerate via make proto)
  • docs/ — Swagger/OpenAPI specs and the statik-embedded swagger UI
  • Bruno/ — Bruno collection for manually exercising the API

Makefile targets

Run make <target>:

Target Description
test Run unit/integration tests
mock Regenerate mocks (Store, TaskDistributor, services)
up / down / reload Manage local Docker Compose infra (Postgres, Redis)
server Run with hot reload (air)
migration <name> Create a new migration file
migrate-up / migrate-down Apply/rollback migrations
sqlc Regenerate internal/db/sqlc from SQL queries
proto Regenerate pb/, docs/swagger, docs/statik from proto/*.proto
dbdocs / dbschema Generate DB docs / SQL schema from docs/db.dbml
lint Run golangci-lint

Contributing

  • Keep changes small and focused; add/update unit tests where appropriate.
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%