Claude Code Prompts for Gin Go Projects

Copy-paste Claude Code prompts for Gin handlers, middleware, sqlc queries, and table-driven tests. Go 1.22 idioms with context-first error handling.

💥 50p impulse-buy: Power Prompts PDF (first 10 buyers) 30 battle-tested Claude Code prompts · 8-page PDF · paste into CLAUDE.md and never re-type a prompt again · 50p impulse-buy, no commitment

Go's lack of magic makes Claude Code particularly useful — there's less invisible behaviour for it to forget. The prompts below produce idiomatic Gin handlers with proper context handling, structured errors, and table-driven tests.

Prompt 1 — Add a Gin endpoint with sqlc-backed handler

Add POST /api/v1/projects to the gin router.

Constraints:
- Read internal/handlers/users/create.go first — match its shape exactly.
- Request type: ProjectCreateRequest in handlers/projects/types.go.
  Validation tags: binding:"required,min=1,max=100" etc.
- Response type: ProjectResponse, same file.
- SQL query: add CreateProject in db/queries/projects.sql, sqlc generate
  expected externally — write the SQL only.
- Handler signature: func(c *gin.Context). Use c.ShouldBindJSON, return
  c.JSON(http.StatusCreated, resp) on success.
- Errors:
  - validation → c.JSON(400, ErrorResponse{Code:"validation_error", Details: err.Error()})
  - db constraint violation (use errors.As + *pq.Error or pgconn) → 409
  - everything else → c.AbortWithStatusJSON(500, ErrorResponse{Code:"internal"})
  - Log unexpected errors via log/slog with request_id from middleware.
- Register route in router/router.go in the v1 group with the existing auth middleware.

Prompt 2 — Middleware with context propagation

Write a Gin middleware RateLimiter that:
- Limits per (userID, route) to 60 req/min using a token-bucket from
  golang.org/x/time/rate
- Stores limiters in a sync.Map keyed by "userID:routePath"
- On limit: c.AbortWithStatusJSON(429, ErrorResponse{Code:"rate_limited",
  RetryAfterSeconds: int(reservation.Delay().Seconds())})
- Reads userID from context (set by auth middleware as "user_id" — read auth.go first)
- Skips for routes tagged with c.GetBool("skip_rate_limit")

Tests:
- Table-driven test in middleware/rate_limiter_test.go
- httptest.NewRecorder + httptest.NewRequest
- Sub-tests: under_limit_passes, over_limit_returns_429, separate_users_independent,
  skip_flag_bypasses
- Each test sets a fresh limiter; do NOT share state across tests.

Prompt 3 — Diagnose a goroutine leak

The /api/v1/exports endpoint launches a background goroutine and the pprof
goroutine count grows without bound. Read internal/handlers/exports/.

For each goroutine spawned in this package:
- file:line of the 'go ...' statement
- exit condition (what makes the goroutine return)
- whether it's bounded by a context cancel
- whether the caller waits or fire-and-forgets

Identify which one leaks and why. Propose the smallest fix:
- Add context with timeout, OR
- Add a sync.WaitGroup the caller waits on, OR
- Move to a worker pool

Do NOT introduce new dependencies. ants/errgroup are allowed if already in go.mod
(check first).

CLAUDE.md anchor block for Gin

## Stack
Go 1.22, Gin 1.10, sqlc 1.27, Postgres 16, log/slog for logging,
testify only for assert/require — never for mocks.

## Conventions
- Package-by-feature under internal/.
- Handlers: one file per HTTP verb in handlers//.go.
- All handler errors return structured ErrorResponse — never c.String().
- Always pass ctx := c.Request.Context() into service/db calls.
- Tests: table-driven, sub-tests named in lower_snake_case.

Related: Claude API from Go.

Frequently asked questions

Will Claude use gorm or sqlc?
It defaults to whichever it finds in your repo. If empty, it defaults to database/sql. To force sqlc: say `Queries live in db/queries/*.sql, generated to internal/db/. Never write gorm or hand-rolled scanning.`
Will Claude follow effective-Go error wrapping?
Yes if instructed: `Errors wrapped with fmt.Errorf(": %w", err) at every boundary. errors.Is/errors.As for checks, never strings.Contains.` Put it in CLAUDE.md once.
How do I keep Claude from writing generic ResponseHelper structs?
Tell it: `Responses are plain structs per endpoint in handlers//types.go. No generic wrappers.` Generic wrappers are a common Claude pattern that doesn't match idiomatic Go.

Free tools

Cost Calculator → API Cookbook → Diff Summarizer → Skills Browser →

More examples

Claude API Python QuickstartClaude API Node.js / TypeScript QuickstartClaude API Streaming in PythonClaude API Streaming in Node.js / TypeScriptClaude API Tool Use in PythonClaude API Tool Use in Node.js / TypeScript