Go - Samples Quickstart

Beginner 10/10 Teacher 10/10 Architect 10/10

Prerequisites

  • Go 1.22+
  • Docker and Docker Compose
  • Optional: golang-migrate CLI, grpcurl, protoc + plugins

1) Sample REST API

# run the server
go run ./cmd/api

# test endpoints
curl -s localhost:8080/health | jq
curl -s -X POST localhost:8080/echo -d '{"message":"hello"}' -H 'Content-Type: application/json' | jq

2) Sample CRUD API (with Migrations)

# start postgres
make compose-up

# run migrations
make migrate-up

# run the API
make run

# test endpoints
curl -s localhost:8080/users | jq
curl -s -X POST localhost:8080/users -d '{"name":"Ada","email":"[email protected]"}' -H 'Content-Type: application/json' | jq

3) Sample gRPC Streaming Service

# generate stubs (if not generated)
protoc -I proto --go_out=./ --go-grpc_out=./ proto/echo.proto

# run server
go run ./cmd/srv

# test stream with grpcurl
grpcurl -plaintext -d '{"msg":"hi"}' localhost:50051 echo.Echo/Stream

4) Observability (OpenTelemetry)

# start local Jaeger + OTel collector
docker compose -f docker-compose.observability.yml up -d

# run your service with OTEL exporter envs
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
# ...run your service...
# view: http://localhost:16686

5) One-command demo (stack)

This compose file starts Postgres, Jaeger, OTel Collector, Prometheus, Grafana; and example service stubs you can wire to your sample REST/CRUD images.

docker-compose.stack.yml

version: "3.9"
services:
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: app
    ports: ["5432:5432"]
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d app"]
      interval: 5s
      timeout: 3s
      retries: 5

  jaeger:
    image: jaegertracing/all-in-one:1.57
    ports: ["16686:16686", "14250:14250"]

  otel-collector:
    image: otel/opentelemetry-collector:0.98.0
    command: ["--config=/etc/otelcol-config.yaml"]
    volumes:
      - ./otelcol-config.yaml:/etc/otelcol-config.yaml:ro
    ports: ["4317:4317", "4318:4318"]
    depends_on: ["jaeger"]

  prometheus:
    image: prom/prometheus:v2.54.1
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
    ports: ["9090:9090"]

  grafana:
    image: grafana/grafana:11.1.0
    ports: ["3000:3000"]
    environment:
      GF_SECURITY_ADMIN_PASSWORD: admin
    depends_on: ["prometheus"]

  rest:
    # example: build your REST sample into an image and use it here
    image: yourorg/sample-rest:latest
    environment:
      OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4318
    depends_on: ["db", "otel-collector"]
    # ports: ["8080:8080"] # if you expose it

  crud:
    image: yourorg/sample-crud:latest
    environment:
      DSN: postgres://user:pass@db:5432/app?sslmode=disable
      OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4318
    depends_on: ["db", "otel-collector"]

otelcol-config.yaml (with Prometheus exporter)

receivers:
  otlp:
    protocols: { grpc: {}, http: {} }
exporters:
  jaeger: { endpoint: jaeger:14250, tls: { insecure: true } }
  prometheus:
    endpoint: 0.0.0.0:9464
service:
  pipelines:
    traces: { receivers: [otlp], exporters: [jaeger] }
    metrics: { receivers: [otlp], exporters: [prometheus] }

prometheus.yml

global: { scrape_interval: 15s }
scrape_configs:
  - job_name: otel-collector
    static_configs:
      - targets: ["otel-collector:9464"]

Makefile (stack)

stack-up:
	docker compose -f docker-compose.stack.yml up -d

stack-down:
	docker compose -f docker-compose.stack.yml down -v