15 промтов для Go: микросервисы, API и утилиты командной строки

Go — язык, который завоевал сердца разработчиков бэкенда и инфраструктуры. Простота, высокая производительность и встроенная поддержка конкурентности делают его идеальным для микросервисов, REST API и CLI-утилит. Но даже опытные Go-разработчики тратят часы на шаблонный код, настройку роутинга и отладку. Я собрал 15 промтов, которые помогут вам ускорить разработку: от генерации каркаса микросервиса до оптимизации производительности. Каждый промт проверен на практике; примеры кода можно сразу адаптировать под свой проект.

Базовые промты: каркас и инструменты

1. Генерация структуры микросервиса с Graceful Shutdown

Задача: Создать минимальный микросервис, который корректно обрабатывает сигналы завершения.
Промт: "Напиши на Go микросервис на net/http с graceful shutdown, логами через slog и хендлером /healthz. Используй сигналы SIGINT и SIGTERM."
Результат:

package main

import (
    "context"
    "log/slog"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(http.StatusOK)
        w.Write([]byte("ok"))
    })

    srv := &http.Server{Addr: ":8080", Handler: mux}

    go func() {
        slog.Info("Server started on :8080")
        if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            slog.Error("Server error", "err", err)
        }
    }()

    quit := make(chan os.Signal, 1)
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
    <-quit

    slog.Info("Shutting down...")
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    if err := srv.Shutdown(ctx); err != nil {
        slog.Error("Shutdown failed", "err", err)
    }
    slog.Info("Server exited")
}

Пояснение: Промт даёт готовый шаблон, который можно вставить в main.go. Используется стандартный пакет slog (Go 1.21+), что исключает лишние зависимости.

2. Настройка роутера chi с middleware

Задача: Подключить популярный роутер chi с логированием и CORS.
Промт: "Создай Go-приложение с роутером chi, добавь middleware для логирования запросов (через chi middleware) и CORS через rs/cors. Хендлеры: GET /api/v1/users и POST /api/v1/users."
Результат:

package main

import (
    "encoding/json"
    "net/http"

    "github.com/go-chi/chi/v5"
    "github.com/go-chi/chi/v5/middleware"
    "github.com/rs/cors"
)

func main() {
    r := chi.NewRouter()
    r.Use(middleware.Logger)
    r.Use(middleware.Recoverer)

    c := cors.New(cors.Options{AllowedOrigins: []string{"*"}})
    handler := c.Handler(r)

    r.Get("/api/v1/users", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("list users"))
    })
    r.Post("/api/v1/users", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("create user"))
    })

    http.ListenAndServe(":3000", handler)
}

Пояснение: chi — один из самых популярных роутеров в Go. Промт сразу даёт работающий пример с двумя самыми часто используемыми middleware.

Промты для API и микросервисов

3. CRUD для сущности с in-memory хранилищем

Задача: Реализовать полноценный CRUD для модели User без БД.
Промт: "Напиши на Go REST API для управления пользователями (ID, Name, Email) с in-memory хранилищем. Используй mux, JSON, методы GET, POST, PUT, DELETE. Добавь валидацию: email не пустой, name не короче 2 символов."
Результат: Код объёмный, поэтому приведу ключевые фрагменты. Структура:

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

type Store struct {
    mu    sync.RWMutex
    users map[int]User
    nextID int
}

Хендлеры используют json.NewEncoder и json.NewDecoder. Валидация проверяется перед записью.
Пояснение: Этот промт закрывает 80% задач по написанию простого CRUD. В реальном проекте хранилище заменяется на PostgreSQL или MongoDB, но логика хендлеров остаётся той же.

4. Работа с PostgreSQL через database/sql и sqlx

Задача: Подключить БД и выполнить запрос с транзакцией.
Промт: "Напиши Go-код, который подключается к PostgreSQL через database/sql и lib/pq, создаёт таблицу users (id serial, name text) и вставляет 3 записи в транзакции с откатом при ошибке. Используй sqlx для сканирования в struct."
Результат:

db, err := sqlx.Connect("postgres", os.Getenv("DATABASE_URL"))
if err != nil {
    log.Fatal(err)
}

tx := db.MustBegin()
tx.MustExec("CREATE TABLE IF NOT EXISTS users (id serial primary key, name text)")
tx.MustExec("INSERT INTO users (name) VALUES ($1)", "Alice")
// ...
tx.Commit()

Пояснение: sqlx расширяет database/sql, позволяя сканировать строки прямо в структуры. Промт явно указывает использовать транзакции — это стандарт промышленной разработки.

5. gRPC-сервер и клиент для сервиса User

Задача: Создать gRPC эндпоинт для получения пользователя.
Промт: "Сгенерируй .proto файл с сервисом UserService (rpc GetUser(UserRequest) returns (UserResponse)). Напиши серверную часть на Go, которая возвращает тестового пользователя, и клиент, который вызывает этот метод."
Результат:

syntax = "proto3";
package user;

message UserRequest { int32 id = 1; }
message UserResponse { string name = 1; string email = 2; }

service UserService { rpc GetUser(UserRequest) returns (UserResponse); }

Сервер реализует интерфейс pb.UserServiceServer, клиент подключается через grpc.Dial.
Пояснение: gRPC — стандарт для межсервисного взаимодействия в микросервисной архитектуре. Промт даёт шаблон, который легко расширить до полноценного сервиса.

6. Graceful Shutdown для gRPC сервера

Задача: Добавить корректное завершение gRPC сервера.
Промт: "Дополни gRPC сервер из предыдущего примера graceful shutdown с помощью signal.Notify. Используй Ghttp.Server и его GracefulStop()."
Результат:

func main() {
    lis, _ := net.Listen("tcp", ":50051")
    s := grpc.NewServer()
    pb.RegisterUserServiceServer(s, &server{})

    // канал для сигналов
    go func() {
        sig := make(chan os.Signal, 1)
        signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
        <-sig
        slog.Info("Shutting down gRPC server...")
        s.GracefulStop()
    }()

    slog.Info("gRPC server listening on :50051")
    if err := s.Serve(lis); err != nil {
        log.Fatal(err)
    }
}

Пояснение: Без graceful shutdown при рестарте контейнера теряются активные запросы. Промт подходит для продакшн-нагрузки.

7. Конфигурация через viper с переменными окружения

Задача: Загрузить конфиг из YAML и переменных окружения.
Промт: "Используя viper, загрузи конфигурацию приложения: порт, строку подключения к БД, уровень логов. Сначала читай config.yaml, затем переменные окружения (с префиксом APP_). Реализуй struct Config с тегами mapstructure."
Результат:

var Config struct {
    Port    string `mapstructure:"port"`
    DB      string `mapstructure:"database_url"`
    LogLevel string `mapstructure:"log_level"`
}
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AutomaticEnv()
viper.SetEnvPrefix("APP")
viper.BindEnv("port", "APP_PORT")
if err := viper.ReadInConfig(); err == nil {
    viper.Unmarshal(&Config)
}

Пояснение: Viper — стандарт де-факто для конфигурации в Go. Промт показывает паттерн 12-factor app: конфиг из переменных окружения переопределяет YAML.

Промты для CLI-утилит

8. CLI-утилита с cobra и pflag

Задача: Создать утилиту с командами и флагами.
Промт: "Создай CLI на cobra с командой greet, флагом --name (default "world") и --uppercase. Выведи приветствие, и если --uppercase задан, то в верхнем регистре."
Результат:

var rootCmd = &cobra.Command{Use: "hello", Run: func(cmd *cobra.Command, args []string) {
    name, _ := cmd.Flags().GetString("name")
    upper, _ := cmd.Flags().GetBool("uppercase")
    greeting := fmt.Sprintf("Hello, %s!", name)
    if upper {
        greeting = strings.ToUpper(greeting)
    }
    fmt.Println(greeting)
}}
rootCmd.Flags().String("name", "world", "name to greet")
rootCmd.Flags().Bool("uppercase", false, "uppercase output")

Пояснение: Cobra используется в Kubernetes, Docker и Hugo. Промт даёт шаблон, который легко расширить до многоуровневого CLI.

9. Прогресс-бар для обработки файлов

Задача: Показать прогресс при чтении большого файла.
Промт: "Напиши утилиту на Go, которая читает большой текстовый файл построчно и выводит прогресс в процентах в стиле progress bar. Используй пакет cheggaaa/pb/v3. Обновляй прогресс каждые 100 строк."
Результат:

import "github.com/cheggaaa/pb/v3"

func main() {
    file := os.Args[1]
    fi, _ := os.Stat(file)
    count := countLines(file) // подсчёт строк
    bar := pb.StartNew(count)
    // ... в цикле чтения: bar.Increment()
    bar.Finish()
}

Пояснение: Библиотека pb — одна из самых популярных для прогресс-баров. Промт подходит для утилит миграции, бэкапа или анализа логов.

10. Работа с HTTP-запросами из CLI

Задача: Утилита, которая делает HTTP-запрос и выводит результат.
Промт: "Создай CLI-утилиту curl-like: принимает URL, метод (GET/POST), --data (body), --header (один или несколько). Используй pflag и net/http. Выведи статус код и тело ответа."
Результат:

url, _ := cmd.Flags().GetString("url")
method, _ := cmd.Flags().GetString("method")
data, _ := cmd.Flags().GetString("data")
req, _ := http.NewRequest(method, url, strings.NewReader(data))
resp, _ := http.DefaultClient.Do(req)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Status: %s\nBody: %s", resp.Status, string(body))

Пояснение: Утилита полезна для быстрого тестирования API. В реальности можно добавить таймаут, сохранение в файл и цветной вывод.

Продвинутые промты: производительность и тестирование

11. Benchmark для HTTP-хендлера

Задача: Написать бенчмарк для хендлера, который парсит JSON.
Промт: "Напиши Go-бенчмарк для HTTP-хендлера POST /api/v1/user, который принимает JSON ({name, email}) и возвращает 201. Используй httptest.NewRecorder и testing.B. Запусти бенчмарк с b.ReportAllocs()."
Результат:

func BenchmarkCreateUser(b *testing.B) {
    payload := `{"name":"Alice","email":"alice@example.com"}`
    req := httptest.NewRequest("POST", "/api/v1/user", strings.NewReader(payload))
    w := httptest.NewRecorder()
    for i := 0; i < b.N; i++ {
        createUserHandler(w, req)
    }
}

Пояснение: httptest — стандартный инструмент для тестирования. Промт учит измерять не только скорость, но и количество аллокаций.

12. Конкурентная обработка задач через worker pool

Задача: Обработать список URL параллельно с ограничением.
Промт: "Реализуй worker pool на Go для скачивания 100 URL. Используй каналы, sync.WaitGroup и ограничь число горутин = 10. Выведи результаты (размер ответа)."
Результат:

urls := loadURLs() // list of 100 URLs
numWorkers := 10
jobs := make(chan string, len(urls))
results := make(chan int, len(urls))

for w := 0; w < numWorkers; w++ {
    go worker(jobs, results)
}
for _, u := range urls {
    jobs <- u
}
close(jobs)
// читаем результаты

Пояснение: Пул воркеров — классический паттерн для утилит, которые парсят сайты, конвертируют изображения или шлют уведомления.

13. Unit-тесты с моками через testify

Задача: Протестировать сервис, который зависит от внешнего API.
Промт: "Напиши интерфейс APIClient с методом GetUser(id int) (User, error). Реализуй сервис UserService, который вызывает этот метод. Создай мок с testify/mock и напиши unit-тест, который проверяет, что сервис возвращает ошибку, если клиент вернул ошибку."
Результат:

type MockAPIClient struct {
    mock.Mock
}
func (m *MockAPIClient) GetUser(id int) (User, error) {
    args := m.Called(id)
    return args.Get(0).(User), args.Error(1)
}

func TestUserService_GetUser_Error(t *testing.T) {
    mockClient := new(MockAPIClient)
    mockClient.On("GetUser", 1).Return(User{}, errors.New("not found"))
    svc := NewUserService(mockClient)
    _, err := svc.GetUser(1)
    assert.Error(t, err)
}

Пояснение: testify — must-have библиотека для тестирования. Промт показывает, как изолировать внешние зависимости.

14. Graceful shutdown для HTTPS с TLS

Задача: Микросервис с HTTPS и корректным завершением.
Промт: "Дополни первый промт: добавь TLS сертификаты (самоподписанные) и переключи сервер на https.ListenAndServeTLS. Graceful shutdown должен закрывать и TLS-соединения."
Результат:

tlsConfig := &tls.Config{
    Certificates: []tls.Certificate{cert},
}
srv.TLSConfig = tlsConfig
// в go-рутине: srv.ListenAndServeTLS("cert.pem", "key.pem")
// Shutdown остаётся тем же

Пояснение: В продакшене TLS обязателен. Промт показывает, что graceful shutdown работает одинаково для HTTP и HTTPS.

15. Логирование структурированных логов в JSON

Задача: Настроить логгер slog для вывода JSON в stdout с уровнем debug.
Промт: "Настрой slog в Go так, чтобы логи выводились в формате JSON с полями level, message, time. Установи уровень DEBUG. Добавь несколько логов разного уровня с контекстными атрибутами."
Результат:

logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug}))
slog.SetDefault(logger)
slog.Debug("starting", "module", "api", "port", 8080)
slog.Info("server started")
slog.Error("failed to connect", "err", err)

Пояснение: JSON-логи легко парсятся системами вроде ELK. Промт рекомендуется включать в любой микросервис.

Заключение

15 промтов — это лишь вершина айсберга. Go настолько лаконичен, что хороший промт может сэкономить часы рутинного кодинга. Попробуйте адаптировать эти примеры под свой проект: замените in-memory на реальную БД, добавьте метрики через Prometheus, прикрутите автоматическую документацию через swaggo.

Если вы только начинаете с Go — начните с первых двух промтов. Если уже пишете микросервисы — обратите внимание на бенчмарки и тесты. А для CLI-утилит промты 8-10 дадут готовый каркас.

Сохраните эту статью в закладки — и в следующий раз, когда вам понадобится написать очередной микросервис на Go, просто скопируйте нужный промт в ChatGPT или Claude. Работа пойдёт быстрее.

← Все статьи

Комментарии

Читайте также

Освойте экономику нефтегазовых проектов: почему курс Asibiont по нефтегазовой и энергетической отрасли — ваш путь к лучшим инвестиционным решениям

25 июля 2026

Освойте самостоятельное исследование с Cambridge IPQ (Independent Project Qualification): Ваш путь к успеху в университете

25 июля 2026

Rust — Системное программирование: Почему это навык, необходимый в 2026 году, и как освоить его с помощью ИИ

25 июля 2026

EtherNet/IP + ASI Biont: как AI-агент управляет контроллерами Rockwell без единой строчки кода

25 июля 2026

Sensor Fusion + AI Inference на Edge: как подключить LIDAR, IMU и камеру к AI-агенту ASI Biont

25 июля 2026

Интеграция PLC (Siemens, Allen-Bradley и др.) с AI-агентом ASI Biont: Modbus, OPC-UA и предиктивное обслуживание без кода

25 июля 2026

GM делает ставку на натрий-ионные батареи: новая эра сетевого хранения энергии в США

25 июля 2026

История не пылится на полках: как технологии возвращают прошлое к жизни

25 июля 2026

Освойте налоговое право России с курсом «Налоговое право Российской Федерации» на Asibiont

25 июля 2026