К основному содержанию
скилл CX Codex

go-api-design — скилл для Claude Code: HTTP/REST API на Go

Скилл ведёт агента по проектированию HTTP-обработчиков на Go: маршруты, middleware, валидация, пагинация, graceful shutdown. Пригодится, когда пишете REST-сервис с нуля или переделываете существующий.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add eduardo-sl/go-agent-skills --skill go-api-design -a claude-code
Открыть на GitHub

Что делает go-api-design

Скилл задаёт агенту правила для Go-сервисов на стандартной библиотеке. Маршрутизация через http.ServeMux (Go 1.22+): шаблоны вида "GET /users/{id}" различают метод, r.PathValue("id") читает параметр, а неверный метод получает 405 с заголовком Allow. Обработчики — методы на структуре с зависимостями (хранилище, логгер), а не глобальные переменные пакета. Ошибки маппятся в статусы на границе обработчика, наружу внутренние детали не уходят.

Middleware описывается как func(http.Handler) http.Handler с жёстким порядком: Recoverer снаружи, дальше RequestID, Logger, Auth, RateLimit. Тело запроса перед декодированием ограничивается http.MaxBytesReader, а успешный декод ещё не значит валидное значение — проверка идёт тем же шагом, ответ 400 с устойчивым текстом, без эха ошибки декодера.

Есть разделы про именование URL (множественное число, kebab-case, версия в пути, никаких глаголов), курсорную пагинацию вместо offset/limit, проверки живости и готовности, формат ошибок и корректное завершение по SIGTERM. Внутри лежит файл references/handlers-and-middleware.md, который агент подгружает по необходимости. Нужен тулчейн Go: без него команды go и gofmt в разрешённых инструментах не сработают.

Какие задачи решает

  • разложить REST-эндпоинты по обработчикам и маршрутам
  • собрать цепочку middleware в правильном порядке
  • ограничить размер тела и провалидировать запрос
  • сделать курсорную пагинацию для больших выборок
  • завершить сервис по SIGTERM без обрыва живых запросов

Примеры запросов агенту

  • Спроектируй REST API для сервиса заказов на Go: маршруты, обработчики, middleware
  • Добавь в main.go graceful shutdown по SIGTERM и эндпоинты /healthz и /readyz
  • Переделай список пользователей на курсорную пагинацию с nextCursor

Как установить go-api-design

1Через Skills CLI (Vercel)

npx skills add eduardo-sl/go-agent-skills --skill go-api-design -a claude-code

2Вручную: положить файлы

~/.claude/skills/go-api-design/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/go-api-design/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о go-api-design

Как установить go-api-design в Claude Code?

Выполните npx skills add eduardo-sl/go-agent-skills --skill go-api-design -a claude-code. Скилл окажется в ~/.claude/skills/go-api-design/SKILL.md.

Что делает go-api-design?

Даёт агенту правила проектирования HTTP/REST API на Go: структура обработчиков, порядок middleware, валидация запросов, пагинация, health-эндпоинты, формат ошибок и graceful shutdown.

Чем он отличается от go-grpc и go-openapi?

Этот скилл про HTTP/REST. Для gRPC-сервисов есть go-grpc, для работы от спецификации OpenAPI — go-openapi.

Исходный текст

SKILL.md · MIT
---
name: go-api-design
description: >
  HTTP/REST API design for Go services: handlers, ServeMux routing,
  middleware, request validation, pagination, idempotency, health checks,
  error responses, and graceful shutdown. Use when designing APIs, writing
  HTTP handlers, implementing middleware, or structuring REST endpoints.
  Trigger examples: "design API", "REST endpoints", "HTTP handler",
  "middleware pattern", "graceful shutdown", "API versioning".
  Not for: gRPC services (go-grpc), spec-first OpenAPI work (go-openapi),
  general architecture (go-architecture-review), concurrency in handlers
  (go-concurrency-review).
user-invocable: true
license: MIT
compatibility: Designed for Claude Code or similar AI coding agents working on Go projects. Requires the Go toolchain.
allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(gofmt:*)
metadata:
  author: eduardo-sl
  version: "2.0.1"
---

# Go API Design

APIs are contracts. Once published, they're promises. Design them as if
you'll maintain them for a decade — because you probably will.

> Community default. A project skill or agent-config rule that explicitly
> supersedes `go-api-design` takes precedence over this one.

Detailed reference material, loaded on demand:

- `references/handlers-and-middleware.md` — handler structs, JSON response
  helpers, request ID and recoverer middleware, decode-and-validate.

Read a reference file only when the summary below is not enough.

## 1. HTTP Handler Structure

- Route with the standard `http.ServeMux` (Go 1.22+): `"GET /users/{id}"`
  patterns match the method, `r.PathValue("id")` reads the wildcard, and a
  wrong method gets a 405 with `Allow`. A router dependency earns its place
  for middleware groups and sub-routers, not for path parameters.
- Handlers are methods on a struct that holds their dependencies (store,
  logger) — never package globals.
- Handler methods return nothing: they write the response and handle the
  error themselves, mapping domain errors (`errors.Is(err, ErrNotFound)`)
  to status codes and logging only the unexpected ones.
- Route through one JSON helper that sets `Content-Type`, writes the status
  once, and logs encode failures.

## 2. Middleware Pattern

Middleware is `func(http.Handler) http.Handler`. Order, outside → inside:

```text
Recoverer → RequestID → Logger → Auth → RateLimit → Handler
```

Recover MUST be outermost. Auth before business logic. Logger captures timing.

## 3. Request Validation

- Cap the body before decoding: `r.Body = http.MaxBytesReader(w, r.Body, 1<<20)`.
- Decode into a typed request struct, then validate it in the same step —
  a successful decode is not a valid value.
- Reply `400` with a stable message; never echo the decoder's error text.

## 4. URL and Naming Conventions

```text
GET    /api/v1/users          → list users
POST   /api/v1/users          → create user
GET    /api/v1/users/{id}     → get user
PUT    /api/v1/users/{id}     → replace user
PATCH  /api/v1/users/{id}     → partial update
DELETE /api/v1/users/{id}     → delete user

GET    /api/v1/users/{id}/orders → list user orders (nested resource)
```

Rules:
- Plural nouns for resources: `/users`, not `/user`
- Kebab-case for multi-word paths: `/order-items`
- One JSON field convention per API, never mixed — camelCase
  (`"createdAt"`) is the default here; match an existing API if one exists
- Version in URL path: `/api/v1/...`
- No verbs in URLs: `/users/search?q=alice`, NOT `/searchUsers`

## 5. Pagination

```go
type PageRequest struct {
    Cursor string `json:"cursor"`
    Limit  int    `json:"limit"`
}

type PageResponse[T any] struct {
    Items      []T    `json:"items"`
    NextCursor string `json:"nextCursor,omitempty"`
    HasMore    bool   `json:"hasMore"`
}
```

Prefer cursor-based pagination over offset/limit for large datasets.
Offset pagination breaks under concurrent writes.

## 6. Graceful Shutdown

```go
func main() {
    if err := run(context.Background()); err != nil {
        slog.Error("server stopped", slog.Any("error", err))
        os.Exit(1)
    }
}

func run(ctx context.Context) error {
    ctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
    defer stop()

    srv := &http.Server{
        Addr:              ":8080",
        Handler:           router,
        ReadHeaderTimeout: 5 * time.Second, // Slowloris guard
        ReadTimeout:       10 * time.Second,
        WriteTimeout:      15 * time.Second,
        IdleTimeout:       120 * time.Second,
    }

    errc := make(chan error, 1)
    go func() { errc <- srv.ListenAndServe() }()

    select {
    case err := <-errc:
        return fmt.Errorf("listen: %w", err) // e.g. port already in use
    case <-ctx.Done():
    }

    // ctx is already cancelled; shutdown needs its own deadline.
    shutdownCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), 30*time.Second)
    defer cancel()
    if err := srv.Shutdown(shutdownCtx); err != nil {
        return fmt.Errorf("shutdown: %w", err)
    }
    if err := <-errc; !errors.Is(err, http.ErrServerClosed) {
        return err
    }
    return nil
}
```

- `ReadHeaderTimeout` is the Slowloris defence: without it a client can
  hold a connection open by trickling header bytes. `gosec` G112 flags a
  server that lacks it.
- Compare `http.ErrServerClosed` with `errors.Is`, never `==`.
- Exit only from `main`. A `log.Fatal` inside the serving goroutine skips
  every deferred cleanup, including the shutdown itself.

## 7. Health Check Endpoints

```go
// Liveness: is the process alive? GET /healthz → 200, no dependency checks
// Readiness: should it receive traffic? GET /readyz → 200 or 503
func (h *HealthHandler) handleReady(w http.ResponseWriter, r *http.Request) {
    if h.draining.Load() { // atomic.Bool, set when shutdown starts
        h.respondError(w, http.StatusServiceUnavailable, "shutting down")
        return
    }
    if err := h.db.PingContext(r.Context()); err != nil {
        h.respondError(w, http.StatusServiceUnavailable, "database unavailable")
        return
    }
    h.respondJSON(w, http.StatusOK, map[string]string{"status": "ready"})
}
```

On SIGTERM behind a load balancer: set `draining`, wait one readiness
period so the balancer stops routing, *then* call `srv.Shutdown`.
Shutting down first rejects requests the balancer is still sending. Keep
liveness free of dependency checks — a database outage should not make the
orchestrator restart every replica.

## 8. Error Response Format

Consistent error responses across the entire API:

```json
{
    "error": {
        "code": "VALIDATION_ERROR",
        "message": "invalid request parameters",
        "details": [
            {"field": "email", "message": "must be a valid email"}
        ]
    }
}
```

Map internal errors to HTTP status codes at the handler boundary.
Internal errors should NEVER leak to clients. For a standard shape, use
RFC 9457 problem details (`application/problem+json`) — the go-openapi
skill has the type.

## 9. Idempotency and Browser Clients

- `POST` endpoints that create or charge accept an `Idempotency-Key`
  header: store key → response for a bounded time, replay the stored
  response for a repeated key, and reject a concurrent duplicate with 409.
  Clients and proxies retry; without this, a retry is a double charge.
- APIs called from browsers with cookies need CSRF protection —
  `http.CrossOriginProtection` (Go 1.25+); the go-security-audit skill
  owns the details.

© eduardo-sl · MIT · eduardo-sl/go-agent-skills

Похожие скиллы

Все скиллы по теме «Бэкенд и API» →
mcp-builder официальный anthropics Скилл проводит через создание MCP-сервера на TypeScript или Python: от изучения протокола до тестов и оценки качества. 130 949установок claude-api официальный anthropics Справочник по Anthropic SDK и API Claude для генерации кода без устаревших параметров и выдуманных методов. 74 198установок lark-im larksuite Скилл подключает Lark IM к агенту: он отправляет сообщения, ищет историю, управляет чатами и файлами. Подойдёт для задач вокруг командных коммуникаций. CX Codex +1 472 900установок lark-event larksuite Слушает события Lark/Feishu и отдаёт их потоком NDJSON. Подходит для ботов, обработчиков сообщений и долгих подписчиков. CX Codex +1 466 800установок caveman-discover JuliusBrussee Находит точки вызова LLM в репозитории и размечает их воркфлоу для Caveman Cloud, чтобы расходы на токены не сливались в одну общую кучу. CX Codex +1 104 400установок migration JuliusBrussee Скилл задаёт правила безопасных миграций схем, данных и API с обязательным откатом. Пригодится при изменениях, где нельзя терять данные или ломать совместимость. CX Codex +1 103 900установок

Из того же набора11

git-commit Скилл учит агента писать коммиты по Conventional Commits: тип, область, императив в заголовке. Пригодится, когда история коммитов в проекте превратилась в кашу. CX Codex +1 ★ 82звёзд репо go-troubleshooting Скилл ведёт агента по диагностике рантайм-проблем в Go: паники, дедлоки, утечки горутин и памяти, отчёты race detector. Пригодится, когда программа падает или висит, а причина неясна. CX Codex +1 ★ 82звёзд репо go-observability Скилл для Go-сервисов: помогает настроить структурные логи на log/slog, трейсы и метрики через OpenTelemetry, а также алерты по SLO. Пригодится, когда сервис уже в проде и нужно видеть, что в нём происходит. CX Codex +1 ★ 82звёзд репо go-error-handling Скилл задаёт агенту правила работы с ошибками в Go: обёртка через %w, sentinel-ошибки, свои типы и errors.Is/errors.As. CX Codex +1 ★ 82звёзд репо go-context Скилл для ИИ-агента, который проверяет и правит работу с context.Context в Go: отмена, таймауты, значения, типичные ошибки. CX Codex +1 ★ 82звёзд репо go-project-layout Подсказывает, как разложить новый Go-проект по папкам: cmd/, internal/, плоская раскладка для мелких утилит. Пригодится в самом начале, когда структура ещё не сложилась. CX Codex +1 ★ 82звёзд репо go-grpc Скилл для ИИ-агента, который ведёт разработку gRPC-сервисов на Go: proto-контракты, коды ошибок, дедлайны, интерцепторы и стриминг. CX Codex +1 ★ 82звёзд репо go-dependency-injection Скилл учит агента внедрять зависимости в Go через конструкторы и собирать всё в main. Пригодится, когда в проекте завёлся глобальный синглтон или код тяжело тестировать. CX Codex +1 ★ 82звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой