Skip to content
Back to skills

Fiber Rest Api

ASecurity

Use when adding or changing a Go HTTP endpoint — Fiber v2 or v3 (detect which), thin handlers, central error mapping, boundary validation; the same rules apply to net/http, chi, echo or gin

  • 109 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 19, 2026
ai-agentsgosqlapibackendsecurity

Works with

  • api

Security analysis

A100/100

Scanned October 2, 2026

npx -y skills add makifbaysal/tasktrooper --skill fiber-rest-api --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Fiber Rest Api?

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

Security grade badge for Fiber Rest Api
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/makifbaysal-fiber-rest-api/badge)](https://www.skillsdirectory.com/skills/makifbaysal-fiber-rest-api)

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: fiber-rest-api
category: api
description: Use when adding or changing a Go HTTP endpoint — Fiber v2 or v3 (detect which), thin handlers, central error mapping, boundary validation; the same rules apply to net/http, chi, echo or gin
tech_stack: Go
source: Fiber docs (MIT), adapted
---
# Go HTTP Endpoint Patterns

## Overview

A handler is a translator: HTTP in → service call → HTTP out. Business logic never lives there. The recurring defects are fat handlers, per-handler error mapping that drifts, endpoints that quietly drop the auth middleware their neighbors have, and copying a value Fiber is about to reuse.

**Core principle:** handlers parse, validate, delegate, and map. Nothing else.

## Detect the repo's router and framework version first

```
grep -E 'gofiber/fiber/v[23]|go-chi/chi|labstack/echo|gin-gonic/gin' go.mod
```

Never change the router or the Fiber major version in a feature task; a repo on Fiber v2 stays v2 (security-fix branch only). A brand-new repo with no router yet gets Fiber v3 (needs Go ≥1.25) unless the task says otherwise.

## Fiber v2 → v3

| | v2 | v3 |
|---|---|---|
| Handler signature | `func(c *fiber.Ctx) error` | `func(c fiber.Ctx) error` |
| Body | `c.BodyParser(&req)` | `c.Bind().Body(&req)` |
| Query / params | `c.QueryParser` / `c.ParamsParser` | `c.Bind().Query` / `c.Bind().URI` |
| Struct tag for path params | `params:` | `uri:` |
| Typed query helper | `c.QueryInt("limit", 20)` | `fiber.Query[int](c, "limit", 20)` |
| Go-standard request context | `c.UserContext()` | `c.Context()` |
| Raw fasthttp context | `c.Context()` (returns `*fasthttp.RequestCtx`) | `c.RequestCtx()` |
| Request id from context | `c.Locals("requestid")` | `requestid.FromContext(c)` |
| Static files / sub-app mount | `app.Static(...)` / `app.Mount(...)` | `static.New(...)` / `app.Use(...)` |

`fiber migrate --to v3` exists for a dedicated upgrade task; never fold a framework-major bump into a feature task.

**The v2 bug this corrects:** on Fiber v2, `c.Context()` returns the pooled `*fasthttp.RequestCtx`, not the request-scoped `context.Context` — passing it where a `context.Context` is expected either fails to compile or silently drops whatever middleware put into the real context (auth claims, request id, trace span). Use `c.UserContext()` on v2.

## Rules

- **Thin handlers:** parse/validate input → call the application service → map result to response DTO. No business logic, no SQL, no cross-entity rules in the handler.
- **Explicit DTO structs** aligned with domain types — never `map[string]any`.
- **Validate and bound all input at the boundary:** lengths, ranges, enum values, UUID parsing (`go-playground/validator` v10 if the repo already uses it; v3 has a `StructValidator` hook). Reject early with 4xx and a field-specific message in the repo's one error shape (see api-design-conventions).
- **Map domain errors to status in ONE place** (a shared `ErrorHandler` / mapper), not per handler, so the mapping can't drift. Show it mapping `errors.Is`/`errors.As` against domain sentinel errors to status + the error body.
- **New endpoints get the SAME middleware chain** (auth, logging, request-id) as their neighbors — copy the adjacent route's wiring, don't invent one.
- **Zero-allocation rule (Fiber-specific):** values Fiber hands you from `c.Params`/`c.Query`/`c.Body`/`c.Get` are only valid for the lifetime of the handler call — Fiber reuses the underlying buffer across requests. `strings.Clone` (or otherwise copy) anything you store in a struct that outlives the request, send to a goroutine, or put in a cache, unless the app is configured with `Immutable: true`.
- **Bound the request body:** `fiber.Config{BodyLimit: ...}` (v2/v3 default 4 MB) or `http.MaxBytesReader` on net/http — don't rely on the default alone for upload endpoints.

## net/http (Go ≥1.22, when the repo has no router)

```go
mux.HandleFunc("POST /tasks/{id}/children", h.CreateChild)
id := r.PathValue("id")
r.Body = http.MaxBytesReader(w, r.Body, maxBody)
```

## Worked Example

```go
func (h *TaskHandler) Create(c fiber.Ctx) error {
    var req createTaskRequest
    if err := c.Bind().Body(&req); err != nil {
        return fiber.NewError(fiber.StatusBadRequest, "invalid body")
    }
    if err := req.validate(); err != nil {
        return fiber.NewError(fiber.StatusBadRequest, err.Error())
    }
    task, err := h.svc.Create(c.Context(), req.Title)
    if err != nil {
        return err
    }
    return c.Status(fiber.StatusCreated).JSON(taskResponseFrom(task))
}
```

The title-length rule lives in the service/domain, not the handler. The central error middleware maps `domain.ErrInvalidTitle → 400`, `domain.ErrConflict → 409` — every handler benefits.

## Handler test in-process (no network)

```go
req := httptest.NewRequest(http.MethodPost, "/tasks", strings.NewReader(body))
req.Header.Set("Content-Type", "application/json")
resp, err := app.Test(req)       // v2: app.Test(req, -1)
// v3:  app.Test(req, fiber.TestConfig{Timeout: 0})
```
Assert status code and decoded body — this is still a unit test; it does not replace running the real service once (backend-runtime-check).

## Common Mistakes

- Business logic or SQL in the handler.
- `map[string]any` request/response instead of DTOs.
- Each handler mapping its own errors to codes → drift.
- A new route missing the auth middleware its neighbors have.
- 500 for a validation failure.
- Storing a value read from `c.Params`/`c.Query`/`c.Body` past the handler without copying it first.
- Passing v2's `c.Context()` where the request's `context.Context` is needed.

## Red Flags

- A handler longer than ~30 lines.
- `pgx`/repository calls inside a handler.
- A route registered without the neighbor's middleware chain.
- A struct field or goroutine capturing a byte slice straight from `c.Body()`/`c.Params()`.

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…