Introduction
Go (Golang) has become the language of choice for building scalable microservices, high-performance APIs, and robust command-line tools. According to the 2025 Stack Overflow Developer Survey, Go is used by 13.5% of professional developers, with a particular concentration in backend and systems programming. Its simplicity, built-in concurrency, and fast compilation make it ideal for modern cloud-native development.
But even experienced Go developers can get stuck on repetitive tasks: designing service boundaries, writing boilerplate HTTP handlers, or debugging race conditions. That's where AI prompts come in. By using well-crafted prompts, you can generate production-ready code, architecture patterns, and testing strategies in seconds.
This collection contains 15 battle-tested prompts I use daily in my Go workflow. Each prompt includes a real usage example, code output, and practical tips. Whether you're building a new microservice, refactoring an API, or writing a CLI utility, these prompts will save you hours.
1. Generate a Minimal HTTP API Server
Prompt:
"Create a Go HTTP API server with the following: use the standard
net/httppackage (no external frameworks), define routes for GET /users and POST /users, parse JSON request bodies, return JSON responses with proper status codes, include middleware for logging requests, and add graceful shutdown with signal handling. Output the completemain.gofile."
Why it works: This prompt specifies constraints (standard library), clear endpoints, middleware, and deployment concerns. It produces a ready-to-run server.
Example output (partial):
package main
import (
"encoding/json"
"log"
"net/http"
"os"
"os/signal"
"time"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
var users = []User{{ID: 1, Name: "Alice"}}
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
log.Printf("%s %s %s", r.Method, r.URL.Path, time.Since(start))
})
}
func getUsers(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(users)
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /users", getUsers)
srv := &http.Server{Addr: ":8080", Handler: loggingMiddleware(mux)}
go func() {
log.Println("Server starting on :8080")
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt)
<-quit
log.Println("Shutting down...")
}
Tips: Adjust port and routes as needed. The prompt can be extended with database integration or authentication.
2. Design a Microservice with Clean Architecture
Prompt:
"Generate a Go microservice project structure following Clean Architecture principles. Include directories:
cmd/server/(entry point),internal/handler/(HTTP handlers),internal/usecase/(business logic),internal/repository/(data access), andinternal/entity/(domain models). Provide a sampleUserentity with CRUD operations, using PostgreSQL as the database anddatabase/sqlfor queries. Output the directory tree and the content ofinternal/usecase/user.go."
Why it works: Clean Architecture separates concerns, making the code testable and maintainable. This prompt produces a template you can reuse for any service.
Example output (directory tree):
my-service/
├── cmd/server/main.go
├── internal/
│ ├── entity/user.go
│ ├── handler/user.go
│ ├── usecase/user.go
│ └── repository/user.go
├── go.mod
└── go.sum
Example output (usecase/user.go):
package usecase
import (
"my-service/internal/entity"
"my-service/internal/repository"
)
type UserUsecase struct {
repo *repository.UserRepository
}
func NewUserUsecase(repo *repository.UserRepository) *UserUsecase {
return &UserUsecase{repo: repo}
}
func (uc *UserUsecase) GetUser(id int) (*entity.User, error) {
return uc.repo.FindByID(id)
}
func (uc *UserUsecase) CreateUser(name, email string) (*entity.User, error) {
user := &entity.User{Name: name, Email: email}
if err := user.Validate(); err != nil {
return nil, err
}
return uc.repo.Save(user)
}
3. Add Structured Logging with slog
Prompt:
"Write a Go function that configures structured logging using the
log/slogpackage (introduced in Go 1.21). The logger should output JSON to stdout, include a service name attribute, support different log levels (DEBUG, INFO, WARN, ERROR), and be context-aware (acceptcontext.Contextto extract trace IDs). Provide an example of usage in an HTTP handler."
Why it works: Structured logging is essential for debugging microservices. The prompt focuses on the modern slog package, which is now part of the standard library.
Example output:
package logger
import (
"context"
"log/slog"
"os"
)
func New(serviceName string) *slog.Logger {
return slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelDebug,
})).With("service", serviceName)
}
func FromContext(ctx context.Context) *slog.Logger {
if logger, ok := ctx.Value("logger").(*slog.Logger); ok {
return logger
}
return slog.Default()
}
4. Create a RESTful API with Chi Router
Prompt:
"Build a RESTful API in Go using the
chirouter. Define routes for CRUD operations on aProductresource: GET /products, GET /products/{id}, POST /products, PUT /products/{id}, DELETE /products/{id}. Use an in-memory slice as the data store, return proper HTTP status codes (200, 201, 204, 400, 404, 500), and include request validation (name required, price > 0). Output the completemain.go."
Why it works: chi is a popular lightweight router. The prompt specifies validation and status codes, producing production-quality code.
Example output (route registration):
r := chi.NewRouter()
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Route("/products", func(r chi.Router) {
r.Get("/", listProducts)
r.Post("/", createProduct)
r.Route("/{id}", func(r chi.Router) {
r.Get("/", getProduct)
r.Put("/", updateProduct)
r.Delete("/", deleteProduct)
})
})
5. Generate a CLI Tool with Cobra
Prompt:
"Write a Go CLI tool using the Cobra library. The tool should have three commands:
init(initialize a config file),run(start a process with optional flags--verboseand--port), andversion(print version info). Use Viper for configuration management. Output themain.goand thecmd/root.gofile."
Why it works: Cobra is the de facto standard for Go CLI tools (used by Kubernetes, Hugo, etc.). The prompt covers commands, flags, and config.
Example output:
var rootCmd = &cobra.Command{
Use: "mycli",
Short: "A CLI tool for managing services",
}
var runCmd = &cobra.Command{
Use: "run",
Short: "Run the service",
Run: func(cmd *cobra.Command, args []string) {
verbose, _ := cmd.Flags().GetBool("verbose")
port, _ := cmd.Flags().GetInt("port")
// start service
},
}
func init() {
runCmd.Flags().BoolP("verbose", "v", false, "verbose output")
runCmd.Flags().IntP("port", "p", 8080, "port to listen on")
rootCmd.AddCommand(runCmd)
}
6. Implement Graceful Shutdown for a gRPC Server
Prompt:
"Write Go code for a gRPC server that handles graceful shutdown. Use the
google.golang.org/grpcpackage. The server should listen on port 50051, accept OS signals (SIGINT, SIGTERM), stop accepting new requests, drain existing connections with a 30-second timeout, and log each step. Output the complete server setup code."
Why it works: Graceful shutdown prevents dropped requests during deployment. The prompt includes timeout and logging.
Example output (shutdown logic):
func main() {
lis, _ := net.Listen("tcp", ":50051")
s := grpc.NewServer()
// register services
go func() {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
<-sigCh
log.Println("Shutting down gRPC server...")
s.GracefulStop()
}()
log.Println("Server starting on :50051")
s.Serve(lis)
}
7. Write Unit Tests with Testify
Prompt:
"Generate Go unit tests for a
Calculatorstruct with methods:Add,Subtract,Multiply,Divide. Use thetestify/assertandtestify/suitepackages. Include table-driven tests for edge cases (division by zero, negative numbers, large integers). Output the complete test file."
Why it works: Table-driven tests are idiomatic in Go. Testify simplifies assertions.
Example output:
func (s *CalculatorTestSuite) TestDivide() {
tests := []struct {
name string
a, b int
expected int
errExpect bool
}{
{"positive", 10, 2, 5, false},
{"divide by zero", 10, 0, 0, true},
{"negative", -10, 2, -5, false},
}
for _, tt := range tests {
s.Run(tt.name, func() {
result, err := s.calc.Divide(tt.a, tt.b)
if tt.errExpect {
s.Error(err)
} else {
s.Equal(tt.expected, result)
}
})
}
}
8. Add Middleware for Rate Limiting
Prompt:
"Write a Go HTTP middleware that implements token bucket rate limiting. Use the standard library. The middleware should accept parameters:
rate(requests per second) andburst(maximum burst). Use a sync.Mutex for thread safety. If the rate limit is exceeded, return HTTP 429 Too Many Requests with a Retry-After header. Output the middleware function and an example usage in an HTTP server."
Why it works: Rate limiting is critical for API stability. The prompt specifies algorithm and headers.
Example output:
type RateLimiter struct {
mu sync.Mutex
tokens float64
rate float64
burst int
lastTime time.Time
}
func (rl *RateLimiter) Allow() bool {
rl.mu.Lock()
defer rl.mu.Unlock()
now := time.Now()
elapsed := now.Sub(rl.lastTime).Seconds()
rl.tokens += elapsed * rl.rate
if rl.tokens > float64(rl.burst) {
rl.tokens = float64(rl.burst)
}
rl.lastTime = now
if rl.tokens >= 1 {
rl.tokens--
return true
}
return false
}
9. Validate JSON Requests with Custom Struct Tags
Prompt:
"Write Go code that validates incoming JSON requests using struct tags and a custom validation function. Support tags:
required,min,max,pattern. For example:Name string \json:\"name\" validate:\"required,min=3,max=50\"``. Return a map of field errors. Output the validator function and an example handler."
Why it works: Validation is a common pain point. This prompt provides a lightweight alternative to third-party libraries.
10. Generate SQL Queries with sqlx
Prompt:
"Write Go code using
jmoiron/sqlxto perform CRUD operations on auserstable with columns: id (SERIAL PRIMARY KEY), name (VARCHAR(100)), email (VARCHAR(255) UNIQUE), created_at (TIMESTAMP). Use named parameters for inserts and updates. Include a function to get a user by email. Output the repository file."
Why it works: sqlx extends database/sql with named parameters and struct scanning.
11. Implement a Worker Pool for Concurrent Tasks
Prompt:
"Write a Go worker pool that processes jobs concurrently. Use channels for job submission and results collection. The pool should accept a number of workers (goroutines) and a job function. Jobs should be cancellable via context. Output the worker pool implementation and an example that processes URLs."
12. Add Health Checks to a Microservice
Prompt:
"Write Go code that adds health check endpoints to a microservice. Implement two endpoints: GET /healthz (liveness) and GET /readyz (readiness). The readiness check should verify database connectivity by pinging PostgreSQL. Use the
database/sqlpackage. Return JSON with status and component details."
13. Create a Simple In-Memory Cache with TTL
Prompt:
"Write a Go in-memory cache with TTL (time-to-live) support. Use a map with a mutex for thread safety. Implement methods:
Get(key string) (interface{}, bool),Set(key string, value interface{}, ttl time.Duration),Delete(key string), andCleanup()to remove expired entries periodically. Output the complete cache package."
14. Parse and Transform JSON with Generics
Prompt:
"Write Go generic functions to parse JSON from an io.Reader and transform a slice of structs. The function
ParseJSON[T any](r io.Reader) ([]T, error)should decode a JSON array. The functionTransform[T, U any](items []T, fn func(T) U) []Ushould apply a transformation. Output both functions with an example."
15. Configure Environment-Based Settings
Prompt:
"Write Go code that loads configuration from environment variables using the
ospackage andstrconv. Define aConfigstruct with fields: Port (int), DatabaseURL (string), Debug (bool), MaxConnections (int). Provide a functionLoadConfig() (*Config, error)that reads from env vars with sensible defaults. Output the config package."
Conclusion
These 15 prompts cover the most common tasks in Go development: from setting up servers and microservices to writing tests and CLI tools. By using them in your daily workflow, you can focus on business logic instead of boilerplate. I recommend saving them as a reference and adapting them to your specific project needs.
For more advanced patterns, check the official Go documentation at go.dev/doc and the Go blog at go.dev/blog. Happy coding!
Comments