Skip to content
Back to skills

1228 Patterns Ef8bbab4

ASecurity

``` cmd/ # Entry points (main.go per binary) internal/ # Private application code ├── domain/ # Business entities and logic ├── service/ # Business operations ├── handler/ # HTTP/gRPC handlers └── repo/ # Data access pkg/ # Public libraries (rarely needed) ```

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
businessgosqlapidatabase

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 1228-patterns_ef8bbab4 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 1228 Patterns Ef8bbab4?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 1228 Patterns Ef8bbab4
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-1228-patterns-ef8bbab4/badge)](https://www.skillsdirectory.com/skills/tools-only-1228-patterns-ef8bbab4)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Go Patterns Reference

## Project Structure

```
cmd/           # Entry points (main.go per binary)
internal/      # Private application code
├── domain/    # Business entities and logic
├── service/   # Business operations
├── handler/   # HTTP/gRPC handlers
└── repo/      # Data access
pkg/           # Public libraries (rarely needed)
```

## Interfaces

### Define at Consumer

Interfaces belong where they're USED, not where they're implemented.

```go
// service/user.go - consumer defines what it needs
type UserStore interface {
    Get(ctx context.Context, id string) (*User, error)
    Save(ctx context.Context, user *User) error
}

type Service struct {
    store UserStore
}
```

```go
// repo/postgres.go - implementation returns concrete type
type PostgresStore struct{ db *sql.DB }

func (s *PostgresStore) Get(ctx context.Context, id string) (*User, error) {
    // ...
}
```

### Keep Interfaces Focused

Small interfaces are better. Prefer composition.

```go
// Good: focused interfaces
type Reader interface { Read(ctx context.Context, id string) (*Entity, error) }
type Writer interface { Write(ctx context.Context, e *Entity) error }
type Deleter interface { Delete(ctx context.Context, id string) error }

// Compose when needed
type ReadWriter interface {
    Reader
    Writer
}
```

```go
// Bad: kitchen sink interface
type Repository interface {
    Get(ctx context.Context, id string) (*Entity, error)
    List(ctx context.Context, filter Filter) ([]*Entity, error)
    Save(ctx context.Context, e *Entity) error
    Delete(ctx context.Context, id string) error
    Archive(ctx context.Context, id string) error
    // ... 10 more methods
}
```

## Type Visibility

Prefer private (lowercase) types unless they need external access.

```go
// internal/service/user.go

// userService is private - exposed via interface or constructor
type userService struct {
    store UserStore
    cache cache
}

// NewUserService exposes a public interface, not the struct
func NewUserService(store UserStore) *userService {
    return &userService{store: store}
}

// config is private, no reason to export
type config struct {
    timeout time.Duration
    retries int
}
```

Public types only when:

- Part of your API contract
- Needed by external packages
- Used in function signatures that must be public

## Comments

Write comments that explain WHY, not WHAT. Avoid obvious comments.

```go
// Bad: obvious
// GetUser gets a user
func GetUser(id string) (*User, error)

// incrementCounter increments the counter by 1
counter++

// Good: explains non-obvious behavior
// GetUser returns ErrNotFound if user doesn't exist, not nil.
func GetUser(id string) (*User, error)

// Batch size tuned for Postgres query planner; larger batches cause seq scans.
const batchSize = 100
```

Package comments are useful:

```go
// Package ratelimit provides token bucket rate limiting with
// automatic backpressure and circuit breaking for HTTP clients.
package ratelimit
```

## Design Patterns

### Functional Options

```go
type Option func(*Config)

func WithTimeout(d time.Duration) Option {
    return func(c *Config) { c.Timeout = d }
}

func New(opts ...Option) *Client {
    cfg := &Config{Timeout: 30 * time.Second}
    for _, opt := range opts {
        opt(cfg)
    }
    return &Client{cfg: cfg}
}
```

### Context Propagation

```go
func (s *service) Process(ctx context.Context, req Request) error {
    ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
    defer cancel()

    data, err := s.fetch(ctx, req.ID)
    if err != nil {
        return fmt.Errorf("fetch: %w", err)
    }
    return s.store(ctx, data)
}
```

### Graceful Shutdown

```go
func main() {
    ctx, stop := signal.NotifyContext(context.Background(),
        syscall.SIGINT, syscall.SIGTERM)
    defer stop()

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

    go func() {
        if err := srv.ListenAndServe(); err != http.ErrServerClosed {
            log.Fatal(err)
        }
    }()

    <-ctx.Done()

    shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    srv.Shutdown(shutdownCtx)
}
```

## Error Handling

### Wrap with Context

```go
if err := db.QueryRow(ctx, query, id).Scan(&user); err != nil {
    if errors.Is(err, sql.ErrNoRows) {
        return nil, ErrNotFound
    }
    return nil, fmt.Errorf("query user %s: %w", id, err)
}
```

### Sentinel Errors

```go
var (
    ErrNotFound     = errors.New("not found")
    ErrUnauthorized = errors.New("unauthorized")
)

if errors.Is(err, ErrNotFound) {
    return http.StatusNotFound
}
```

## Concurrency

### Worker Pool

```go
func ProcessBatch(ctx context.Context, items []Item, workers int) error {
    g, ctx := errgroup.WithContext(ctx)
    ch := make(chan Item)

    for i := 0; i < workers; i++ {
        g.Go(func() error {
            for item := range ch {
                if err := process(ctx, item); err != nil {
                    return err
                }
            }
            return nil
        })
    }

    g.Go(func() error {
        defer close(ch)
        for _, item := range items {
            select {
            case ch <- item:
            case <-ctx.Done():
                return ctx.Err()
            }
        }
        return nil
    })

    return g.Wait()
}
```

## Configuration

```go
type config struct {
    Port        int           `env:"PORT" envDefault:"8080"`
    DatabaseURL string        `env:"DATABASE_URL,required"`
    Timeout     time.Duration `env:"TIMEOUT" envDefault:"30s"`
}

func loadConfig() (*config, error) {
    var cfg config
    if err := env.Parse(&cfg); err != nil {
        return nil, fmt.Errorf("parse config: %w", err)
    }
    return &cfg, nil
}
```

## Style

- Early returns reduce nesting
- Meaningful names: `userID` not `id`, `cfg` not `c`
- Short names in small scopes: `for i, v := range items`
- No stuttering: `user.Name` not `user.UserName`
- Group imports: stdlib, external, internal

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.