Skip to content
Back to skills

Add Handler

ASecurity

Scaffold a new HTTP handler with service function, store method (if needed), and table-driven test, following the project's internal/{api,service,store} layout. Invoke when the user asks to add an endpoint, handler, or route.

  • 86 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added June 5, 2026
ai-agentsgobashtestingapi

Works with

  • api

Security analysis

A100/100

Scanned June 5, 2026

npx -y skills add MuhammadUsmanGM/claude-code-best-practices --skill add-handler --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Add Handler?

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

Security grade badge for Add Handler
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/muhammadusmangm-add-handler/badge)](https://www.skillsdirectory.com/skills/muhammadusmangm-add-handler)

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

Download with Pro
SKILL.md
---
name: add-handler
description: Scaffold a new HTTP handler with service function, store method (if needed), and table-driven test, following the project's internal/{api,service,store} layout. Invoke when the user asks to add an endpoint, handler, or route.
allowed-tools: Read, Write, Edit, Glob, Grep, Bash(go build:*), Bash(go test:*)
---

# Add Handler

Add a new HTTP handler across the layers the project already uses. Don't
invent a layer that isn't there.

## Steps

1. **Clarify once** (if not given): method + path, what it does, and the
   response shape.
2. **Read one existing handler** in `internal/api/` and its matching test
   and service function. Mirror the style: error handling, context usage,
   response helpers.
3. **Edit files in this order:**
   - `internal/model/<resource>.go` — domain type, if new.
   - `internal/store/<resource>.go` — store method signature on the
     interface *and* the concrete implementation. Stop here if the
     operation doesn't need storage.
   - `internal/service/<resource>.go` — the service function. Takes a
     context, returns the domain type and an error. No `http` imports.
   - `internal/api/<resource>.go` — the handler. Decodes input, calls the
     service, maps errors to status codes, encodes output.
   - `internal/api/<resource>_test.go` — a table-driven test exercising
     happy path and one input-validation failure.
4. **Wire the route** in the router setup (usually `cmd/<service>/main.go`
   or `internal/api/router.go`) only if adding a new path.
5. Run `go build ./...` then `go test ./internal/api/...` and report the
   outcome.

## Default shape

```go
// internal/api/widgets.go
func (s *Server) createWidget(w http.ResponseWriter, r *http.Request) {
    var in WidgetCreate
    if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
        http.Error(w, "invalid body", http.StatusBadRequest)
        return
    }
    widget, err := s.svc.CreateWidget(r.Context(), in)
    if err != nil {
        s.writeErr(w, err)  // maps domain errors to status codes
        return
    }
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusCreated)
    _ = json.NewEncoder(w).Encode(widget)
}
```

```go
// internal/api/widgets_test.go
func TestCreateWidget(t *testing.T) {
    cases := []struct {
        name       string
        body       string
        wantStatus int
    }{
        {"happy", `{"name":"gizmo"}`, http.StatusCreated},
        {"empty name", `{"name":""}`, http.StatusBadRequest},
    }
    for _, tc := range cases {
        t.Run(tc.name, func(t *testing.T) {
            // ...
        })
    }
}
```

## Rules

- No new dependencies. `go.mod` is reviewed.
- `r.Context()` is passed to every downstream call.
- Exported funcs/types get a doc comment starting with their name.
- If the handler needs a new store method, add the interface method in
  `internal/service/` (where the interface is consumed), not `internal/store/`
  (where it's implemented).
- Don't wrap the router middleware. Follow the project's existing wiring.

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.