Skip to content

GO-SERVICE-TEMPLATE-SPEC — Go Microservice Starter Repository Specification

Status: Draft Owner: Platform Engineering Repository: simpaisa/go-service-template Runtime: Go 1.22+ Last Updated: 2026-04-03


1. Overview

Canonical Go microservice starter repository for the Simpaisa platform. Provides a production-ready scaffold for building services that integrate with the Simpaisa infrastructure stack: KrakenD API gateway, SurrealDB, NSQ messaging, gRPC, Caddy sidecar, and OpenTelemetry observability. All Simpaisa Go services SHALL be bootstrapped from this template.

2. Directory Structure

go-service-template/
├── cmd/
│   └── {service}/
│       └── main.go                 # Entry point, wire dependencies, start servers
├── internal/
│   ├── handler/
│   │   ├── http.go                 # HTTP handlers (REST API)
│   │   └── grpc.go                 # gRPC service implementations
│   ├── service/
│   │   └── {domain}.go             # Business logic layer
│   ├── repository/
│   │   └── {domain}.go             # Data access layer (SurrealDB queries)
│   ├── model/
│   │   └── {domain}.go             # Domain models and value objects
│   ├── middleware/
│   │   ├── auth.go                 # RSA signature verification middleware
│   │   ├── logging.go              # Request/response structured logging
│   │   ├── tracing.go              # OpenTelemetry trace propagation
│   │   └── recovery.go             # Panic recovery middleware
│   └── config/
│       └── config.go               # Configuration loading (env vars, YAML)
├── pkg/
│   ├── auth/
│   │   ├── rsa.go                  # RSA key management and verification
│   │   └── merchant.go             # Merchant authentication helpers
│   ├── health/
│   │   ├── handler.go              # /health and /ready endpoints
│   │   └── checker.go              # Dependency health checks (DB, NSQ, etc.)
│   └── telemetry/
│       ├── tracer.go               # OpenTelemetry tracer provider setup
│       ├── meter.go                # OpenTelemetry meter provider setup
│       └── logger.go               # Structured JSON logging (slog)
├── api/
│   └── proto/
│       ├── {service}.proto         # gRPC service definition
│       └── buf.yaml                # Buf configuration for proto linting
├── deploy/
│   ├── Dockerfile                  # Multi-stage distroless build
│   ├── Caddyfile                   # Caddy sidecar configuration
│   └── k8s/
│       ├── deployment.yaml         # Kubernetes deployment manifest
│       ├── service.yaml
│       └── configmap.yaml
├── scripts/
│   ├── migrate.sh                  # Database migration runner
│   └── seed.sh                     # Development seed data
├── .spectral.yaml                  # API linting rules (Spectral)
├── .golangci.yaml                  # golangci-lint configuration
├── Makefile
├── go.mod
├── go.sum
└── README.md

3. Entry Point — cmd/{service}/main.go

  • Load configuration from environment variables (12-factor)
  • Initialise telemetry (tracer, meter, logger)
  • Initialise SurrealDB connection pool
  • Initialise NSQ consumer/producer
  • Wire dependency injection (constructor injection, no frameworks)
  • Start gRPC server on configurable port
  • Start HTTP server on configurable port
  • Graceful shutdown on SIGTERM/SIGINT (drain connections, flush telemetry)

4. KrakenD-Compatible Health Endpoints

GET /health — Liveness probe - Returns 200 OK with {"status": "alive"} - No dependency checks (fast response for K8s liveness)

GET /ready — Readiness probe - Checks SurrealDB connectivity - Checks NSQ producer connectivity - Returns 200 OK with {"status": "ready", "checks": {...}} or 503 with failed checks - KrakenD uses this to route traffic only to healthy instances

5. OpenTelemetry (Traces + Metrics + Logs)

  • Traces: OTLP exporter to collector; W3C TraceContext propagation
  • Metrics: OTLP exporter; request duration histogram, error rate counter, active connections gauge
  • Logs: log/slog with JSON handler; trace ID and span ID injected into every log line
  • Resource attributes: service.name, service.version, deployment.environment, service.namespace
  • Configurable sampling rate (default 10% in production, 100% in sandbox)
  • Graceful shutdown flushes all pending telemetry

6. Structured JSON Logging

  • log/slog as the logging abstraction (Go 1.21+ stdlib)
  • JSON output in production, text output in development
  • Standard fields: timestamp, level, msg, trace_id, span_id, service, request_id
  • Sensitive fields redacted (PII, keys, tokens)
  • Log levels configurable via environment variable: LOG_LEVEL=debug|info|warn|error

7. SurrealDB Client Wrapper

  • Connection pool with configurable max connections
  • Namespace and database selection from config
  • Query helper methods: Query(), Select(), Create(), Update(), Delete()
  • Automatic retry on transient connection errors
  • Health check method for readiness probe
  • Context propagation for tracing

8. NSQ Consumer/Producer

Producer: - Publish to named topics with JSON-serialised messages - Connection pooling and automatic reconnection - PublishAsync() for fire-and-forget patterns - Message envelope: {id, type, timestamp, correlation_id, payload}

Consumer: - Subscribe to topics with configurable channel names - Concurrent message handling with configurable MaxInFlight - Automatic message retry with backoff (NSQ native) - Dead letter handling after max attempts - Graceful drain on shutdown

9. gRPC Server

  • Service definitions in api/proto/ using Protocol Buffers v3
  • buf for proto linting and breaking change detection
  • gRPC reflection enabled in non-production environments
  • Unary and server-streaming interceptors for auth, logging, tracing
  • Health service (grpc.health.v1) for load balancer integration

10. Caddy Sidecar — Caddyfile

:443 {
    reverse_proxy localhost:{HTTP_PORT}
    tls internal
    log {
        output stdout
        format json
    }
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
    }
}
  • TLS termination at sidecar level
  • Security headers injected automatically
  • Access logs in JSON format
  • Health endpoint passthrough

11. Dockerfile (Multi-Stage Distroless)

# Build stage
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /service ./cmd/{service}

# Runtime stage
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=builder /service /service
USER nonroot:nonroot
ENTRYPOINT ["/service"]
  • No shell, no package manager in runtime image
  • Non-root user by default
  • Image size target: < 20MB

12. Makefile

.PHONY: build test lint run proto migrate

build:          ## Build the service binary
test:           ## Run unit tests with race detector
lint:           ## Run golangci-lint
run:            ## Run locally with hot reload (air)
proto:          ## Generate gRPC stubs from proto files
migrate:        ## Run database migrations
docker-build:   ## Build Docker image
docker-run:     ## Run service in Docker

13. CI Pipeline (Bitbucket Pipelines)

Stages: linttestbuildscanpush

  1. Lint: golangci-lint, buf lint (protos), spectral lint (OpenAPI)
  2. Test: go test -race -cover ./... with coverage threshold (>80%)
  3. Build: Multi-arch Docker image (amd64, arm64)
  4. Scan: Trivy container vulnerability scan; gosec static analysis
  5. Push: Push image to container registry with semantic version tag

14. API Linting — .spectral.yaml

  • Enforce Simpaisa API standards on any OpenAPI specs in the repo
  • Rules: consistent naming (camelCase), required operationId, standard error schema, pagination format
  • Run in CI alongside Go linting

15. Configuration

Environment variables (12-factor):

Variable Description Default
SERVICE_NAME Service identifier required
HTTP_PORT HTTP server port 8080
GRPC_PORT gRPC server port 9090
SURREALDB_URL SurrealDB connection URL ws://localhost:8000
SURREALDB_NS SurrealDB namespace simpaisa
SURREALDB_DB SurrealDB database required
NSQ_LOOKUPD_ADDR NSQ lookupd address localhost:4161
NSQD_ADDR NSQd address for publishing localhost:4150
OTEL_EXPORTER_ENDPOINT OTLP collector endpoint localhost:4317
LOG_LEVEL Logging level info
ENVIRONMENT Deployment environment development