AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Go Conventions

skill-jonathan0823-opencode-config-go-conventions · by Jonathan0823

Go conventions, best practices, and idiomatic patterns for production code

No reviews yet
0 installs
30 views
0.0% view→install

Install

$ agentstack add skill-jonathan0823-opencode-config-go-conventions

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-jonathan0823-opencode-config-go-conventions)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
4mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Go Conventions? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Go Conventions Skill

Overview

This skill provides guidelines for writing idiomatic, production-ready Go code following Go conventions, best practices, and patterns optimized for backend development with Gin and standard library.

Core Principles

1. Idiomatic Go

  • Follow Go's philosophy: "Simple is better"
  • Prefer composition over inheritance
  • Use small interfaces
  • Write self-documenting code with clear variable names
  • Keep functions short and focused

2. Error Handling

// DO: Explicit error handling with context
result, err := processData(input)
if err != nil {
    return fmt.Errorf("failed to process data: %w", err)
}

// DON'T: Ignore errors
result, _ := processData(input) // Never do this

// DO: Wrap errors for context
return fmt.Errorf("database operation failed: %w", err)

// DO: Use custom error types for domain-specific errors
type ValidationError struct {
    Field   string
    Message string
}

func (e ValidationError) Error() string {
    return fmt.Sprintf("validation failed for %s: %s", e.Field, e.Message)
}

3. Concurrency Patterns

// DO: Use context for cancellation
func fetchData(ctx context.Context, url string) ([]byte, error) {
    req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
    if err != nil {
        return nil, err
    }
    // ...
}

// DO: Use channels with select for timeouts
select {
case result := <-ch:
    return result, nil
case <-time.After(timeout):
    return nil, errors.New("timeout")
case <-ctx.Done():
    return nil, ctx.Err()
}

// DO: Use sync.WaitGroup for goroutine coordination
var wg sync.WaitGroup
for _, task := range tasks {
    wg.Add(1)
    go func(t Task) {
        defer wg.Done()
        process(t)
    }(task)
}
wg.Wait()

4. Struct and Interface Design

// DO: Small interfaces (Interface Segregation)
type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

// DO: Constructor patterns for complex structs
func NewService(db *sql.DB, cache *redis.Client, logger *zap.Logger) *Service {
    return &Service{
        db:     db,
        cache:  cache,
        logger: logger,
    }
}

// DO: Method receivers - pointer vs value
func (s *Service) Update(data Data) error  // Pointer for mutation
func (c Config) Validate() error            // Value for read-only

5. Package Organization

myproject/
├── cmd/
│   └── api/              # Main application entry point
│       └── main.go
├── internal/
│   ├── domain/           # Business logic (entities, use cases)
│   ├── repository/       # Data access layer
│   ├── service/          # Business services
│   └── handler/          # HTTP handlers
├── pkg/
│   ├── middleware/       # Shared middleware
│   └── utils/           # Shared utilities
└── go.mod

Gin-Specific Patterns

1. Handler Structure

// DO: Use dependency injection
func (h *UserHandler) CreateUser(c *gin.Context) {
    var req CreateUserRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    
    user, err := h.service.CreateUser(c.Request.Context(), req)
    if err != nil {
        handleError(c, err)
        return
    }
    
    c.JSON(http.StatusCreated, user)
}

// DO: Centralized error handling
func handleError(c *gin.Context, err error) {
    switch e := err.(type) {
    case *ValidationError:
        c.JSON(http.StatusBadRequest, gin.H{"error": e.Error()})
    case *NotFoundError:
        c.JSON(http.StatusNotFound, gin.H{"error": e.Error()})
    default:
        c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"})
    }
}

2. Middleware Patterns

// DO: Authentication middleware
func AuthMiddleware(secret string) gin.HandlerFunc {
    return func(c *gin.Context) {
        token := c.GetHeader("Authorization")
        if token == "" {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "missing token"})
            return
        }
        
        claims, err := validateToken(token, secret)
        if err != nil {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "invalid token"})
            return
        }
        
        c.Set("user", claims)
        c.Next()
    }
}

// DO: Logging middleware
func LoggerMiddleware(logger *zap.Logger) gin.HandlerFunc {
    return func(c *gin.Context) {
        start := time.Now()
        path := c.Request.URL.Path
        
        c.Next()
        
        logger.Info("request",
            zap.String("method", c.Request.Method),
            zap.String("path", path),
            zap.Int("status", c.Writer.Status()),
            zap.Duration("duration", time.Since(start)),
        )
    }
}

Database Patterns (PostgreSQL)

// DO: Repository pattern
type UserRepository interface {
    Create(ctx context.Context, user *User) error
    GetByID(ctx context.Context, id int64) (*User, error)
    Update(ctx context.Context, user *User) error
    Delete(ctx context.Context, id int64) error
    List(ctx context.Context, opts ListOptions) ([]User, error)
}

// DO: Transaction handling
func (r *userRepo) CreateWithProfile(ctx context.Context, user *User, profile *Profile) error {
    tx, err := r.db.BeginTx(ctx, nil)
    if err != nil {
        return err
    }
    defer tx.Rollback()
    
    if err := r.createUserTx(ctx, tx, user); err != nil {
        return err
    }
    
    if err := r.createProfileTx(ctx, tx, profile); err != nil {
        return err
    }
    
    return tx.Commit()
}

Testing Patterns

// DO: Table-driven tests
func TestCalculateTotal(t *testing.T) {
    tests := []struct {
        name     string
        items    []Item
        expected float64
    }{
        {
            name:     "empty cart",
            items:    []Item{},
            expected: 0,
        },
        {
            name: "single item",
            items: []Item{{Price: 10, Quantity: 2}},
            expected: 20,
        },
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := calculateTotal(tt.items)
            assert.Equal(t, tt.expected, result)
        })
    }
}

// DO: Mock interfaces for testing
type MockUserService struct {
    mock.Mock
}

func (m *MockUserService) GetUser(ctx context.Context, id int64) (*User, error) {
    args := m.Called(ctx, id)
    return args.Get(0).(*User), args.Error(1)
}

When to Use

Use this skill when:

  • Writing or reviewing Go code
  • Designing Go architecture
  • Refactoring Go projects
  • Implementing Go backend services with Gin
  • Writing Go tests
  • Setting up Go project structure

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.