Skip to content
/ go-api-template Public template

Golang Rest API Template with clear, scalable structure. Built with simplicity and flexibility in mind.

Notifications You must be signed in to change notification settings

sash20m/go-api-template

Repository files navigation

Go API Template (Golang)

Opinionated starter for building a scalable Go HTTP API with Postgres (and optional RabbitMQ), with a clean transport/service/repository split and consistent JSON responses.

The Idea

This template aims to stay flat, explicit, and easy to extend while keeping clear boundaries:

  • Transport: thin edge (HTTP handlers / queue consumers). Parse input, call services, render output.
  • Service: business logic + orchestration (and optional event publishing).
  • Repository: data access via sqlx + SQL (easy to debug and optimize).

Adding a new domain should feel repeatable: create a small slice in transport/service/repository, wire it, ship it.

Core decisions

  • Router: chi (github.com/go-chi/chi/v5) for composable routes and middleware.
  • Responses: a single renderer (internal/libs/renderer) standardizes JSON envelopes.
  • Errors: return internal/errors.HTTPError to get consistent statusCode + errorCode.
  • Config: one schema in config/config.go, loaded from env; accessible via config.CONFIG.
  • Queue: RabbitMQ is optional; when disabled, publishing becomes a no-op (NoopPublisher).

Features

  • HTTP routing: chi with composable middleware
  • Postgres: sqlx repositories + SQL migrations via golang-migrate
  • Queue (optional): RabbitMQ publish/consume with routing-key → handler router
  • Config: environment-driven (supports -envfilename)
  • API ergonomics: standardized JSON success/error envelopes
  • Ops/dev: Docker Compose (DB + RabbitMQ), Air hot-reload, golangci-lint

Quickstart (local dev)

Prereqs: Go (see go.mod), Docker (recommended for DB/queue).

  1. Create env file:
cp .env.example .env
  1. Start dependencies:
docker compose up
  1. Run migrations:
go run cmd/migration/main.go -envfilename=.env
  1. Run the API:
go run cmd/api/main.go

Optional hot reload:

go install github.com/cosmtrek/air@latest
air

Configuration

Create .env from .env.example. Minimum keys to boot:

  • App: ENV, PORT, VERSION, ALLOWED_ORIGINS
  • Database: DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD
  • RabbitMQ (optional):
    • RABBITMQ_ENABLED (true|false)
    • RABBITMQ_URL (required when enabled)
    • RABBITMQ_PREFETCH (optional, default 20)

Docker-first defaults (used by docker-compose.yml):

  • DB_HOST=go-api-template-db
  • RABBITMQ_URL=amqp://guest:guest@go-api-template-rabbitmq:5672/

If you run services outside Docker, switch hosts to localhost.

Project layout (high level)

cmd/                    # Entrypoints (api server, migration runner)
config/                 # Env/config schema + loader
internal/
  server.go             # Wiring + graceful shutdown
  transport/            # HTTP + queue entrypoints (thin)
  service/              # Use-cases / orchestration
  repositories/         # sqlx data access
  model/                # Domain + DB models
  errors/               # Typed HTTP errors + error codes
  libs/                 # Shared infra (db, queue, renderer, utils, crypto)
  migrations/           # SQL migrations
scripts/                # Helper scripts

Architecture (quick tour)

If you’re looking for “where to change what”, start here:

  • Entrypoints: cmd/api/main.go, cmd/migration/main.go
  • Composition + lifecycle: internal/server.go (router, middleware, DB, optional queue, graceful shutdown)
  • HTTP wiring: internal/transport/http/http_transport.go (+ per-domain folders under internal/transport/http/)
  • Queue wiring: internal/transport/queue/queue.go + internal/transport/queue/router.go
  • Migrations: internal/migrations/ (plain SQL, golang-migrate format)

Conventions

  • Layering:
    • Transport parses input, calls service, renders output
    • Service contains business logic (and publishes events)
    • Repository talks to Postgres (sqlx + SQL)
  • Response envelopes (via internal/libs/renderer):
    • (2xx): { "data": <any>, "timestamp": "<utc>" }
    • (4xx/5xx): { "errorCode": <int>, "statusCode": <int>, "message": "<string>", "timestamp": "<utc>" }
  • Errors: return internal/errors.HTTPError to control statusCode + errorCode consistently.

Examples included

  • Users HTTP routes: see internal/transport/http/users/handler_routes.go (e.g. GET /api/users/{id}, POST /api/users/)
  • Auth middleware scaffold: internal/transport/http/middlewares/auth.go (replace with JWT/session validation)
  • Queue handler example: see internal/transport/queue/ for a sample routing-key handler

Adding a new domain (checklist)

For a resource like orders:

  • Model: internal/model/orders.go
  • Repo: internal/repositories/order_repository.go
  • Service: internal/service/orders.go (wire in internal/service/types.go)
  • HTTP: internal/transport/http/orders/ (handler + routes + types/mapper)
  • Wire: add to internal/transport/http/http_transport.go and register under /api
  • Queue (optional): add routing keys/topology/handlers under internal/libs/queue + internal/transport/queue

Also: rename the module in go.mod and update imports from go-api-template to your module path.

Lint

golangci-lint run

License

MIT — see LICENSE.

About

Golang Rest API Template with clear, scalable structure. Built with simplicity and flexibility in mind.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published