backend-go

Backend Go Conventions

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "backend-go" with this command: npx skills add teodevlor/agent-kit-skill/teodevlor-agent-kit-skill-backend-go

Backend Go Conventions

This skill provides specific conventions for Go backend development.

When to Use

  • Use this skill when working on Go projects

  • Use this skill when creating new handlers, services, or repositories

  • This skill builds upon project-standards skill

Instructions

  1. Project Layout (Standard Go Layout)

project/ ├── cmd/ │ └── api/ │ └── main.go # Entry point ├── internal/ │ ├── handler/ # HTTP handlers (Controllers) │ ├── service/ # Business logic │ ├── repository/ # Database access │ ├── model/ # Domain models │ └── dto/ # Request/Response objects ├── pkg/ # Shared libraries ├── api/ # OpenAPI/Swagger specs ├── config/ # Configuration └── go.mod

  1. Architecture (Clean/Hexagonal)
  • Handler (Controller): Receives requests, validates, calls Service.

  • Service (Usecase): Contains Business Logic.

  • Repository: Interacts with the Database.

Important: Interfaces should be defined where they are USED (Consumer), not where they are provided (Producer).

// In service package (consumer defines interface) type UserRepository interface { FindByID(ctx context.Context, id string) (*model.User, error) Create(ctx context.Context, user *model.User) error }

type UserService struct { repo UserRepository }

func NewUserService(repo UserRepository) *UserService { return &UserService{repo: repo} }

  1. Error Handling

No Panic

Only panic during app setup failure (e.g., db disconnect).

// Bad - panicking in business logic func GetUser(id string) User { user, err := repo.Find(id) if err != nil { panic(err) // Never do this! } return user }

// Good - return errors func GetUser(id string) (User, error) { user, err := repo.Find(id) if err != nil { return User{}, fmt.Errorf("get user %s: %w", id, err) } return user, nil }

Wrap Errors

Use fmt.Errorf with %w to preserve context.

if err != nil { return fmt.Errorf("create user failed: %w", err) }

  1. Naming Convention
  • Package: Short, lowercase, no underscores (e.g., user , auth ).

  • Interface: Ends with er (e.g., Reader , Writer , UserRepository ).

  • Variable: camelCase, acronyms all uppercase (userID , httpClient ).

  • Exported: PascalCase for exported, camelCase for unexported.

// Good package user

type Repository interface { FindByID(ctx context.Context, id string) (*User, error) }

var defaultTimeout = 30 * time.Second // unexported var DefaultClient = &http.Client{} // exported

  1. Context Handling

Always pass context as the first parameter.

func (s *UserService) GetUser(ctx context.Context, id string) (*User, error) { // Check context cancellation select { case <-ctx.Done(): return nil, ctx.Err() default: }

return s.repo.FindByID(ctx, id)

}

  1. HTTP Handler Example

func (h *UserHandler) GetUser(w http.ResponseWriter, r *http.Request) { id := chi.URLParam(r, "id")

user, err := h.service.GetUser(r.Context(), id)
if err != nil {
    if errors.Is(err, ErrNotFound) {
        h.respondError(w, http.StatusNotFound, "user not found")
        return
    }
    h.respondError(w, http.StatusInternalServerError, "internal error")
    return
}

h.respondJSON(w, http.StatusOK, Response{
    Success: true,
    Data:    user,
})

}

  1. Testing

Use table-driven tests.

func TestUserService_GetUser(t *testing.T) { tests := []struct { name string id string want *User wantErr bool }{ { name: "valid user", id: "123", want: &User{ID: "123", Email: "test@example.com"}, }, { name: "not found", id: "999", wantErr: true, }, }

for _, tt := range tests {
    t.Run(tt.name, func(t *testing.T) {
        // Test implementation
    })
}

}

  1. Dependencies
  • Framework: Gin or Echo

  • ORM: GORM or SQLC

  • Config: Viper

  • Logger: Zap or Zerolog

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

frontend-nextjs

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

role-debugger

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

role-architect

No summary provided by upstream source.

Repository SourceNeeds Review