10 промтов для Go: от микросервисов до CLI-утилит

10 промтов для Go: от микросервисов до CLI-утилит

Go — один из самых востребованных языков для backend. На нём написаны Kubernetes, Docker, Prometheus. Но даже в Go много шаблонного кода. AI-ассистенты могут сгенерировать его за секунды, если правильно составить промт. Здесь — 10 промтов для микросервисов, API и CLI. Каждый с примером результата.

1. Каркас микросервиса

Промт:

Сгенерируй структуру Go-микросервиса с чистой архитектурой: cmd/server/main.go, internal/config, internal/handler, internal/service, internal/repository. Для HTTP используй net/http, добавь middleware для логирования.

Результат:

package main

import (
    "log"
    "net/http"
    "myproject/internal/handler"
)

func main() {
    mux := http.NewServeMux()
    handler.RegisterRoutes(mux)
    log.Fatal(http.ListenAndServe(":8080", handler.Logging(mux)))
}

2. REST API с валидацией

Промт:

Напиши REST API для User (ID, Name, Email). Используй net/http. Реализуй GET /users/{id}, POST /users, PUT, DELETE. Валидируй email, ошибки возвращай JSON.

Результат:

func (h *Handler) CreateUser(w http.ResponseWriter, r *http.Request) {
    var u User
    if err := json.NewDecoder(r.Body).Decode(&u); err != nil {
        writeError(w, http.StatusBadRequest, "invalid json")
        return
    }
    if !isValidEmail(u.Email) {
        writeError(w, http.StatusBadRequest, "invalid email")
        return
    }
    h.service.Create(r.Context(), &u)
    writeJSON(w, http.StatusCreated, u)
}

3. gRPC-сервис

Промт:

Создай protobuf для UserService с GetUser и CreateUser. Сгенерируй Go-сервер с graceful shutdown.

Результат:

service UserService {
  rpc GetUser(GetUserRequest) returns (User);
  rpc CreateUser(CreateUserRequest) returns (User);
}

```go
lis, _ := net.Listen("tcp", ":50051")
s := grpc.NewServer(grpc.Un

aryInterceptor( grpc_recovery.UnaryServerInterceptor(), )) s.RegisterService(&UserService_ServiceDesc, &server{}) go func() { log.Println("gRPC server listening on :50051") if err := s.Serve(lis); err != nil { log.Fatal(err) } }() // graceful shutdown stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt, syscall.SIGTERM) <-stop s.GracefulStop() **Что получили**: protobuf-контракт, работающий сервер с recovery и graceful shutdown. Промт можно расширить: добавить логирование запросов через `grpc_logrus`, метрики через `grpc_prometheus` — просто укажите это в тексте запроса. ## 4. Middleware для паники и CORS **Промт**: Напиши middleware для net/http: Recovery (перехватывает panic и возвращает 500 JSON) и CORS (заголовки Access-Control-Allow-Origin, методы, headers). Примени к mux. **Результат**:go func Recovery(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r http.Request) { defer func() { if err := recover(); err != nil { writeError(w, http.StatusInternalServerError, "internal server error") log.Printf("panic: %v", err) } }() next.ServeHTTP(w, r) }) } func CORS(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r http.Request) { w.Header().Set("Access-Control-Allow-Origin", "") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") if r.Method == http.MethodOptions { w.WriteHeader(http.StatusOK) return } next.ServeHTTP(w, r) }) } ## 5. Работа с PostgreSQL через database/sql **Промт**: Напиши слой repository для PostgreSQL: подключение через sql.Open, миграции из папки migrations, CRUD для User. Используй context и prepared statements. **Результат**:go type UserRepository struct { db sql.DB } func (r UserRepository) Create(ctx context.Context, u User) error { query := INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id return r.db.QueryRowContext(ctx, query, u.Name, u.Email).Scan(&u.ID) } func (r UserRepository) GetByID(ctx context.Context, id int) (User, error) { u := &User{} query := SELECT id, name, email FROM users WHERE id = $1 err := r.db.QueryRowContext(ctx, query, id).Scan(&u.ID, &u.Name, &u.Email) return u, err } **Совет**: попросите также добавить пул соединений (`db.SetMaxOpenConns`, `db.SetMaxIdleConns`) — ассистент сгенерирует настройку за секунду. ## 6. Конфигурация через env **Промт**: Создай пакет config: загрузка переменных окружения (APP_PORT, DB_DSN, LOG_LEVEL) в структуру Config. Добавь дефолты и функцию Validate. **Результат**:go const defaultPort = "8080" type Config struct { Port string DBDSN string LogLevel string } func Load() (Config, error) { cfg := &Config{ Port: getenv("APP_PORT", defaultPort), DBDSN: os.Getenv("DB_DSN"), LogLevel: getenv("LOG_LEVEL", "info"), } if cfg.DBDSN == "" { return nil, errors.New("DB_DSN is required") } return cfg, nil } Теперь при запуске `APP_PORT=9000 ./app` — подхватится порт, а при отсутствии переменной — дефолт. ## 7. Логирование JSON **Промт**: Настрой logrus: вывод в JSON, уровень из env, формат с полями time, level, msg, request_id. Добавь middleware для автоматического логирования HTTP-запросов. **Результат**:go log.SetFormatter(&log.JSONFormatter{}) log.SetLevel(log.InfoLevel) // или из config func RequestLogger(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r http.Request) { start := time.Now() next.ServeHTTP(w, r) log.WithFields(log.Fields{ "method": r.Method, "path": r.URL.Path, "duration": time.Since(start), }).Info("request") }) } JSON-логи легко парсятся в Elasticsearch/Loki — стандарт для продакшена. ## 8. CLI-утилита на cobra **Промт**: Напиши CLI-утилиту с помощью cobra: команда greet с флагом --name, команда calc с подкомандами add/sub. Основная команда — help. **Результат**:go var greetCmd = &cobra.Command{ Use: "greet", Run: func(cmd cobra.Command, args []string) { name, _ := cmd.Flags().GetString("name") fmt.Printf("Hello, %s!\n", name) }, } func main() { rootCmd := &cobra.Command{Use: "app"} rootCmd.AddCommand(greetCmd, calcCmd) rootCmd.Execute() } Теперь у вас полноценный `CLI` с автодополнением и документацией — Cobra делает всё сам. ## 9. Воркер с очередью задач **Промт**: Реализуй worker pool на Go: канал задач (Task функцией), N воркеров, graceful остановка через context. Каждая задача выполняется в отдельной горутине воркера. **Результат**:go type Task func(ctx context.Context) error func WorkerPool(ctx context.Context, tasks <-chan Task, workers int) error { wg := sync.WaitGroup{} for i := 0; i < workers; i++ { wg.Add(1) go func() { defer wg.Done() for task := range tasks { select { case <-ctx.Done(): return default: if err := task(ctx); err != nil { log.Printf("task error: %v", err) } } } }() } wg.Wait() return nil } Такой паттерн используют для фоновых рассылок, обработки файлов и любых тяжёлых задач. ## 10. Миграции БД **Промт**: Настрой golang-migrate для SQL-миграций: CLI-команды up, down, create. Сгенерируй начальную миграцию для таблицы users. **Результат**:xml -- 000001_create_users.up.sql CREATE TABLE users ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE NOT NULL ); -- 000001_create_users.down.sql DROP TABLE IF EXISTS users; Код вызова в Go:go import ( "github.com/golang-migrate/migrate/v4" _ "github.com/golang-migrate/migrate/v4/database/postgres" _ "github.com/golang-migrate/migrate/v4/source/file" ) func main() { m, _ := migrate.New("file://migrations", "postgres://user:pass@localhost/db") m.Up() } ``` --- Как использовать эти промты*: скопируйте текст в ChatGPT, Cursor, Copilot или любой другой ИИ-ассистент. Уточняйте детали — имена полей, библиотеки, стиль кода. Чем точнее промт, тем меньше правок. Go — идеальный язык для кодогенерации: статическая типизация и простота синтаксиса позволяют ИИ выдавать качественный результат с первого раза. Если хотите продолжение — например, интеграционные тесты, Dockerfile или CI-пайплайн для этих микросервисов, — просто напишите об этом. Удачной генерации!

← Все статьи

Комментарии