Rock8Cloud
Blueprints

Go — Blueprint

REST API backend with Go 1.23, Gin, and PostgreSQL

REST API backend built with Go 1.23, Gin, and PostgreSQL. Intended as a starting point for Kubernetes-deployed services: one table, one API endpoint, Swagger UI, full Docker support out of the box.

Tech stack:

LayerTechnology
LanguageGo 1.23
HTTP frameworkGin
Database driverpgx/v5 (pgxpool)
Migrationsgolang-migrate (embedded)
API docsswaggo/swag + gin-swagger

The application starts on port 8080 (overridable via PORT). Opening / redirects to the Swagger UI at /swagger/index.html.

View on GitHub →

Project Structure

├── main.go              # Entry point: Gin router, migrations, PORT env var
├── db.go                # Connection string builder + pgxpool setup
├── migrate.go           # golang-migrate with embedded migrations/
├── handler.go           # SpaceTarget struct, infoHandler, listTargets
├── migrations/
│   ├── 000001_init.up.sql    # Creates space_target table + seed data
│   └── 000001_init.down.sql  # Drops the table
└── docs/                # Auto-generated by swag init — do not edit manually

Key design decisions:

  • db.go builds the connection string from DATABASE_URL (if set) or from individual DB_* variables, then creates a pgxpool.Pool — a connection pool managed by pgx directly, without an ORM.
  • migrate.go embeds the migrations/ directory at compile time using //go:embed. On startup, main.go runs migrations before the server accepts requests.
  • Swagger docs are generated from Go annotations in handler.go by swag init. The docs/ directory is committed to the repo so the binary can be built without the swag tool at runtime. When adding new endpoints, regenerate with swag init.
  • The Dockerfile runs swag init in the build stage so the final image is always up to date.
  • To add a new endpoint: add a handler function with swag annotations in handler.go (or a new file), register the route in main.go, and run swag init.

Environment Variables

The application runs on port 8080 by default.

VariableRequiredDefaultDescription
PORTno8080HTTP port

Database connection is configured via one of two approaches:

VariableRequiredExample
DATABASE_URLyespostgres://user:pass@host:5432/dbname?sslmode=require

Option B — Individual variables

VariableRequiredDefaultDescription
DB_HOSTnolocalhostDatabase host
DB_PORTno5432Database port
DB_NAMEnospacedbDatabase name
DB_USERnopostgresDatabase user
DB_PASSWORDnopostgresDatabase password
DB_SSL_MODEnodisableSSL mode, e.g. require or disable

DATABASE_URL takes precedence. If it is set, the individual DB_* variables are ignored.


Running Locally

With Docker Compose

docker compose up

Starts the application together with a PostgreSQL instance and sets DATABASE_URL automatically. No additional configuration needed.

Standalone

# install swag once (generates Swagger docs from annotations)
go install github.com/swaggo/swag/cmd/swag@latest

# generate docs and build
swag init
go build -o server .

# run — Option A
DATABASE_URL=postgres://postgres:postgres@localhost:5432/spacedb?sslmode=disable ./server

# run — Option B
DB_HOST=localhost DB_USER=postgres DB_PASSWORD=secret ./server

# or run without building
swag init && DATABASE_URL=postgres://postgres:postgres@localhost:5432/spacedb?sslmode=disable go run .

On this page