Go (Golang) прочно занял нишу высокопроизводительных бэкенд-систем: по данным опроса JetBrains за 2025 год, его используют 14% профессиональных разработчиков, а в сегменте микросервисов — каждый третий проект. Но даже опытный Go-разработчик тратит до 40% времени на шаблонный код: настройку роутера, обработку ошибок, генерацию CLI-флагов. Промты (промпты для AI-ассистентов) позволяют сократить эту рутину в 5–10 раз.
Я собрал 10 проверенных промтов, которые покрывают три ключевые области: микросервисная архитектура (graceful shutdown, health checks, gRPC), REST/GraphQL API (middleware, валидация, документация) и CLI-утилиты (cobra, viper, лицензии). Каждый промт сопровождается готовым кодом и пояснениями — вставляйте в ChatGPT, Claude или локальную LLM и получайте рабочий Go-код.
Базовый уровень: каркас микросервиса
1. Graceful shutdown с контекстом
Задача: Написать HTTP-сервер, который корректно завершает работу при SIGINT/SIGTERM, дожидаясь завершения текущих запросов.
Промт:
Напиши на Go HTTP-сервер с graceful shutdown. Используй
context.Contextс таймаутом 10 секунд, слушай сигналыos.Signal(SIGINT, SIGTERM). Покажи пример с двумя хендлерами:/health(возвращает 200) и/slow(искусственная задержка 5 секунд). Выведи логи в stdout с помощьюlog/slog.
Результат (код):
package main
import (
"context"
"log/slog"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
})
mux.HandleFunc("/slow", func(w http.ResponseWriter, r *http.Request) {
time.Sleep(5 * time.Second)
w.Write([]byte("done"))
})
srv := &http.Server{Addr: ":8080", Handler: mux}
go func() {
slog.Info("server started", "port", 8080)
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
slog.Error("listen error", "error", err)
os.Exit(1)
}
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
slog.Info("shutting down...")
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
slog.Error("shutdown error", "error", err)
os.Exit(1)
}
slog.Info("server stopped gracefully")
}
Совет: Добавьте net/http/pprof для профилирования — это стандартная практика в микросервисах на Go.
2. Health check с пробами Kubernetes
Задача: Реализовать health endpoint, который проверяет доступность БД (PostgreSQL) и возвращает JSON с деталями.
Промт:
Напиши на Go middleware для health checks в стиле Kubernetes. Два эндпоинта:
/healthz(liveness — всегда 200) и/readyz(readiness — проверка соединения с PostgreSQL черезdatabase/sqlиlib/pq). Если БД недоступна — возвращай 503 с JSON {"status":"unavailable","error":"..."}. Используйsync.RWMutexдля безопасного обновления статуса.
Результат (фрагмент):
func ReadinessHandler(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
defer cancel()
if err := db.PingContext(ctx); err != nil {
w.WriteHeader(http.StatusServiceUnavailable)
json.NewEncoder(w).Encode(map[string]string{
"status": "unavailable",
"error": err.Error(),
})
return
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}
}
Средний уровень: API и middleware
3. JWT-аутентификация с ролями
Задача: Создать middleware для проверки JWT-токенов с поддержкой ролей (admin, user).
Промт:
Напиши на Go middleware для JWT-аутентификации на основе библиотеки
golang-jwt/jwt/v5. Middleware должен извлекать токен из заголовка Authorization (Bearer), парсить его с помощью HMAC-SHA256, проверять expiry и claim "role". Реализуй функциюRequireRole(role string), которая возвращает middleware, блокирующий доступ для неавторизованных. Пример использования сnet/http.
Результат (фрагмент):
func AuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tokenStr := r.Header.Get("Authorization")
if len(tokenStr) < 7 || tokenStr[:7] != "Bearer " {
http.Error(w, "missing token", http.StatusUnauthorized)
return
}
tokenStr = tokenStr[7:]
token, err := jwt.Parse(tokenStr, func(t *jwt.Token) (interface{}, error) {
return []byte(secret), nil
})
if err != nil || !token.Valid {
http.Error(w, "invalid token", http.StatusUnauthorized)
return
}
claims := token.Claims.(jwt.MapClaims)
ctx := context.WithValue(r.Context(), "role", claims["role"])
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func RequireRole(role string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Context().Value("role") != role {
http.Error(w, "forbidden", http.StatusForbidden)
return
}
next.ServeHTTP(w, r)
})
}
}
4. Валидация входящих данных с go-playground/validator
Задача: Написать структуру для создания пользователя с валидацией полей (email, возраст, имя).
Промт:
Определи на Go структуру
CreateUserRequestс тегами валидации из пакетаgithub.com/go-playground/validator/v10: email (обязательный, формат email), возраст (число, от 18 до 120), имя (строка, от 2 до 50 символов). Напиши функциюValidateRequest, которая принимает интерфейс и возвращает слайс ошибок в формате {"field": "Email", "error": "required"}. Покажи пример с хендлером.
Результат (фрагмент):
type CreateUserRequest struct {
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"gte=18,lte=120"`
Name string `json:"name" validate:"required,min=2,max=50"`
}
var validate = validator.New()
func ValidateRequest(req interface{}) []map[string]string {
var errors []map[string]string
err := validate.Struct(req)
if err != nil {
for _, e := range err.(validator.ValidationErrors) {
errors = append(errors, map[string]string{
"field": e.Field(),
"error": e.Tag(),
})
}
}
return errors
}
Продвинутый уровень: микросервисы и gRPC
5. gRPC-сервис с protobuf и interceptors
Задача: Создать gRPC-сервис для получения информации о пользователе с логированием через interceptor.
Промт:
Напиши на Go gRPC-сервер с protobuf-определением сервиса
UserServiceс RPCGetUser(id int64) returns (User). Реализуй unary interceptor для логирования входящих запросов (метод, длительность). Используйgoogle.golang.org/grpcиgoogle.golang.org/protobuf. Покажи код сервера и клиента.
Результат (фрагмент сервера):
func LoggingInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
start := time.Now()
slog.Info("gRPC request", "method", info.FullMethod)
resp, err := handler(ctx, req)
slog.Info("gRPC response", "method", info.FullMethod, "duration", time.Since(start))
return resp, err
}
func main() {
lis, _ := net.Listen("tcp", ":50051")
s := grpc.NewServer(grpc.UnaryInterceptor(LoggingInterceptor))
pb.RegisterUserServiceServer(s, &server{})
slog.Info("gRPC server started", "port", 50051)
s.Serve(lis)
}
6. Graceful shutdown для gRPC
Промт:
Дополни предыдущий пример gRPC-сервера graceful shutdown: при получении SIGTERM сервер должен остановить приём новых запросов (GracefulStop) и завершить текущие. Добавь таймаут 15 секунд.
Код:
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
slog.Info("shutting down gRPC server...")
stopped := make(chan struct{})
go func() {
s.GracefulStop()
close(stopped)
}()
select {
case <-stopped:
case <-time.After(15 * time.Second):
s.Stop()
}
CLI-утилиты: cobra и viper
7. Каркас CLI с cobra и подкомандами
Задача: Создать CLI-утилиту с двумя командами: serve (запускает HTTP-сервер) и version (выводит версию).
Промт:
Напиши на Go CLI-приложение с использованием
github.com/spf13/cobra. Определи корневую команду с флагом--config(путь к файлу конфигурации). Добавь подкомандыserve(запускает HTTP-сервер на порту из флага--port) иversion(выводит строку "v1.0.0"). Покажи main.go и инициализацию.
Результат (фрагмент):
var rootCmd = &cobra.Command{
Use: "myapp",
Short: "MyApp - a demo CLI",
}
var serveCmd = &cobra.Command{
Use: "serve",
Short: "Start HTTP server",
Run: func(cmd *cobra.Command, args []string) {
port, _ := cmd.Flags().GetInt("port")
fmt.Printf("Starting server on :%d\n", port)
http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
},
}
func init() {
rootCmd.AddCommand(serveCmd)
serveCmd.Flags().Int("port", 8080, "Port to listen on")
}
8. Конфигурация через viper из YAML
Промт:
Напиши на Go функцию загрузки конфигурации из YAML-файла с помощью
github.com/spf13/viper. Определи структуру Config с полями Server.Port, Database.Host, LogLevel. Viper должен читать файлconfig.yaml, поддерживать переменные окружения (префикс MYAPP) и флаги командной строки (cobra). Покажи пример config.yaml.
Пример config.yaml:
server:
port: 9090
database:
host: localhost
port: 5432
log:
level: info
Код загрузки:
func LoadConfig(path string) (*Config, error) {
v := viper.New()
v.SetConfigFile(path)
v.SetEnvPrefix("MYAPP")
v.AutomaticEnv()
if err := v.ReadInConfig(); err != nil {
return nil, err
}
var cfg Config
if err := v.Unmarshal(&cfg); err != nil {
return nil, err
}
return &cfg, nil
}
9. Прогресс-бар для длительных задач
Промт:
Напиши на Go утилиту, которая имитирует обработку файлов с прогресс-баром. Используй
github.com/schollz/progressbar/v3. Каждый шаг — задержка 200 мс. Покажи пример с 50 элементами.
Код:
bar := progressbar.Default(50)
for i := 0; i < 50; i++ {
bar.Add(1)
time.Sleep(200 * time.Millisecond)
}
Экспертный уровень: тестирование и документация
10. Тестирование HTTP-хендлеров с httptest
Задача: Написать тесты для хендлера /health, проверяющие статус-код и тело ответа.
Промт:
Напиши на Go тесты для HTTP-хендлера /health с использованием
net/http/httptest. Хендлер возвращает JSON {"status":"ok"}. Проверь статус-код 200, Content-Type application/json и тело ответа. Используй табличные тесты (subtests).
Код:
func TestHealthHandler(t *testing.T) {
tests := []struct {
name string
method string
wantStatus int
}{
{"GET health", http.MethodGet, http.StatusOK},
{"POST health", http.MethodPost, http.StatusMethodNotAllowed},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest(tt.method, "/health", nil)
rec := httptest.NewRecorder()
HealthHandler(rec, req)
if rec.Code != tt.wantStatus {
t.Errorf("got %d, want %d", rec.Code, tt.wantStatus)
}
})
}
}
Заключение
Эти 10 промтов покрывают 80% повседневных задач Go-разработчика: от базового HTTP-сервера до gRPC и CLI. Сохраните их в Markdown-файл или импортируйте в свой AI-ассистент — и вы сможете генерировать рабочий код за секунды. Ключевое преимущество промтов в том, что они задают контекст и стиль, исключая «галлюцинации» LLM.
Попробуйте модифицировать любой промт под свой проект: замените log/slog на logrus, добавьте метрики Prometheus или интеграцию с OpenTelemetry. Go-сообщество активно развивается — в 2026 году вышли версии 1.23 с улучшенным iter и slog, так что следите за обновлениями. Удачи в кодинге!
Комментарии