Complete AI prompt library for Go developers. Covers REST APIs with Chi/Gin, GORM or sqlc, JWT middleware, goroutine patterns, context propagation, Docker builds, testing with testify, and high-performance microservice design.
Go in 2026: Speed, Simplicity, and Concurrency
Go's combination of static typing, garbage collection, goroutines, and minimal syntax makes it the language of choice for high-performance microservices, CLI tools, and platform infrastructure. Getting great Go code from AI requires specifying idiomatic patterns: explicit error handling, context propagation, interface-driven design, and table-driven tests. These prompts produce code a senior Go engineer would approve at code review.
1. Go Microservice Structure
You are a senior Go engineer who has built microservices handling 100K+ requests per second.
Design the structure for a production Go microservice for task management:
- HTTP: Chi router (chi v5)
- Database: PostgreSQL with sqlc (type-safe SQL generation) + pgx v5 driver
- Cache: Redis with go-redis/v9
- Auth middleware: JWT validation (golang-jwt/jwt/v5)
- Config: environment variables via envconfig or viper
- Logging: structured JSON with slog (standard library, Go 1.21+)
- Observability: OpenTelemetry traces + Prometheus metrics
Deliver:
1. Directory structure: cmd/, internal/{handler,service,repository,model}, pkg/
2. main.go: dependency wiring with graceful shutdown (signal handling, server.Shutdown with timeout)
3. Config struct with validation (required fields, defaults)
4. Middleware stack: requestID, logger, recovery, auth, CORS, rate limiter
5. Health check endpoint: /health returns JSON with DB ping, Redis ping, version
2. HTTP Handler with Idiomatic Error Handling
You are a Go HTTP expert writing idiomatic Go code.
Build HTTP handlers for the Task resource using Chi router:
Handler methods: ListTasks, GetTask, CreateTask, UpdateTask, DeleteTask
Each handler:
- Accept (w http.ResponseWriter, r *http.Request)
- Extract organizationID from context (set by auth middleware)
- Decode JSON body with json.NewDecoder(r.Body).Decode() — limit body to 1MB with http.MaxBytesReader
- Validate with a custom Validator (struct tags: validate:"required,min=3,max=255")
- Call service layer, propagate context: ctx := r.Context()
- Error handling: switch on custom error types, map to HTTP status codes
- Write JSON response: helper respondJSON(w, status, data) using json.NewEncoder
Custom error types:
type NotFoundError struct { Resource string; ID string }
type ValidationError struct { Fields map[string]string }
type UnauthorizedError struct { Message string }
Error handler middleware: wraps handlers, catches panics, maps domain errors to HTTP responses (never expose internal errors in production)
Idiomatic Go requirements:
- No named return values
- Errors always as last return value
- context.Context always as first argument to service methods
- Interfaces for all dependencies (testable)
3. sqlc Database Layer
You are a sqlc and PostgreSQL expert for Go applications.
Set up sqlc for a Go task management service:
sqlc.yaml configuration:
- engine: postgresql
- schema: db/schema/
- queries: db/queries/
- output: internal/repository/db/ (generated code)
- emit_json_tags: true, emit_db_tags: true
- null_style: sql_null_types (use sql.NullString, not pointers)
Schema (db/schema/tasks.sql):
- tasks table with all columns, soft delete, tenant isolation
- Indexes: composite [organization_id, status, due_date], [organization_id, assigned_to]
Queries (db/queries/tasks.sql):
-- name: GetTaskByID :one
-- name: ListTasksByOrganization :many (with filter params, ORDER BY, LIMIT OFFSET)
-- name: CreateTask :one (RETURNING *)
-- name: UpdateTask :one (partial update with CASE WHEN for optional fields)
-- name: SoftDeleteTask :exec (UPDATE set deleted_at)
-- name: CountTasksByStatus :many (GROUP BY status, returns []CountByStatusRow)
Repository interface and implementation:
- ITaskRepository interface matching generated method signatures
- TaskRepository wraps generated *db.Queries
- Transaction helper: WithTx(ctx, fn) for wrapping multiple queries in a transaction
Output: sqlc.yaml, schema SQL, queries SQL, and repository interface + wrapper.
4. Goroutine Patterns & Concurrency
You are a Go concurrency expert.
Implement these concurrent patterns for a Go microservice:
1. Worker pool for background job processing:
- Pool of N workers (configurable via env)
- Jobs sent via buffered channel: chan Job
- Each worker: for-select loop with ctx.Done() cancellation
- Graceful shutdown: close channel, WaitGroup.Wait() before returning
- Backpressure: non-blocking send with select{case ch <- job: default: return ErrQueueFull}
2. Fan-out notification sender:
- Receive one TaskAssigned event
- Fan out to 3 senders concurrently: email, push notification, in-app
- All 3 must complete (or fail) before returning
- Timeout: cancel all if any takes longer than 5 seconds
- Collect all errors (errgroup.Group from golang.org/x/sync/errgroup)
3. Rate-limited external API caller:
- Call third-party API with global rate limit: 10 req/second
- golang.org/x/time/rate Limiter with Wait(ctx)
- Retry with exponential backoff on 429 and 5xx
- Circuit breaker: stop trying after 5 consecutive failures, reset after 30 seconds
Show: all three patterns with proper context propagation, cancellation, and error handling.
5. JWT Middleware
You are a Go security engineer.
Build JWT authentication middleware for a Chi router:
Middleware (func(http.Handler) http.Handler):
- Extract token from Authorization: Bearer header
- Validate with golang-jwt/jwt/v5: RS256 (load public key from env)
- Check claims: exp (not expired), iss (correct issuer), aud (correct audience)
- Extract: userID (sub), organizationID, role, planTier
- Store in context: use typed context keys (type contextKey string, not plain string)
- On error: respond immediately with JSON 401, never call next
Context helpers:
- UserFromContext(ctx) (User, bool)
- OrganizationIDFromContext(ctx) (uuid.UUID, bool)
- RequireRole(role string) func(http.Handler) http.Handler — 403 if wrong role
Rate limiting middleware:
- Per-user rate limiting using go-redis sliding window
- Key: ratelimit:{userID}:{endpoint}
- Configurable limits per plan tier (free: 100/hour, pro: 1000/hour)
- Return 429 with Retry-After header
Output: auth middleware, rate limit middleware, context key types, and Chi router setup showing middleware chain.
6. Table-Driven Tests with testify
You are a Go testing expert.
Write table-driven tests for the TaskService.CreateTask method:
[PASTE TaskService.CreateTask SIGNATURE AND IMPLEMENTATION]
Test structure:
tests := []struct {
name string
input CreateTaskInput
mockSetup func(*MockTaskRepository, *MockEventPublisher)
expectedError error
expectedTask *Task
}{
// happy path
// validation: title too short
// validation: due date in past
// duplicate title in project (repository returns ErrDuplicateKey)
// repository connection failure
// event publisher failure (task still created — eventual consistency)
}
Requirements:
- Generate mock with mockery: //go:generate mockery --name=TaskRepository
- Use testify/assert for non-fatal assertions, testify/require for fatal (stop test on failure)
- t.Parallel() on each subtest for faster CI
- Table entries: use descriptive name strings, not 'test case 1'
- Assert: exact error type with errors.As, not just non-nil
- Assert: mock expectations were met (mock.AssertExpectations(t))
Output: full test file with all table cases, mock setup, and testify assertions.
7. Good vs Bad Go Prompts
| Task | ❌ Bad Prompt | ✅ Good Prompt |
|---|---|---|
| Error handling | "Handle errors in my Go code" | "Add idiomatic Go error handling: wrap with fmt.Errorf('%w', err) at each layer, define NotFoundError and ValidationError custom types, use errors.As in the HTTP handler to map to 404/400, log only at the top handler layer (not in service or repository layers)." |
| Concurrency | "Run tasks concurrently in Go" | "Implement errgroup.Group for fan-out: send email + push notification + in-app concurrently. Cancel all on 5-second timeout via context.WithTimeout. Return combined error if any fail. All goroutines must respect ctx.Done()." |
| Testing | "Test my Go service" | "Write table-driven tests for TaskService.Create with testify. Table: happy path, title too short, DB duplicate key, event publisher failure. Mockery-generated mocks. t.Parallel() per case. Assert exact error types with errors.As. mock.AssertExpectations." |
Generate a custom Go prompt → Try PromptPrepare free
Found this helpful? Share it.