← ClaudeAtlas

padosoft-hono-api-conventionslisted

Use this skill when writing or reviewing code in a Hono API on Bun — a new endpoint, a middleware, a repository or a SQL query — and whenever the user works on a controller/repository/query layer, types a Hono context, adds a paginated or localized list, or hits a symptom like "the type of c.get is any", "it returns null instead of an empty list", "page 1 skips records", "sometimes the translation is missing" or "the middleware types don't line up": it applies the three-layer architecture, the typed-context and middleware-factory patterns, and the recurring mistakes that cost the most. Do not use it for the security review of an endpoint (padosoft-api-security-review) nor for OpenAPI spec changes.
padosoft/skills · ★ 1 · API & Backend · score 80
Install: claude install-skill padosoft/skills
# Hono API conventions The conventions that a Hono/Bun API needs applied consistently, and the mistakes that keep coming back. The goal: an endpoint that goes through review without the same five comments every time. --- ## 1. Three layers, one direction **Controller → Repository → Query.** Each layer has exactly one job, and the dependency only ever points downwards. | Layer | Does | Never does | |---|---|---| | **Controller** (`src/controllers/`) | Reads the validated input (`c.req.valid("query"\|"json"\|"param")`), calls the repository, maps relations, returns `c.json(data, status)`, throws `ApiError` | SQL, business transformations | | **Repository** (`src/repositories/`) | Calls the query, executes it, **transforms** the data, handles caching and transactions | Builds SQL strings, touches the HTTP context | | **Query** (`src/query/`) | **Only** SQL building. Returns `[sql, params] as const` | Business logic, execution, transformation | ```ts // src/query/loyalty/query.ts — returns the tuple, executes nothing export function queryGetLevels(lang: string) { const sql = `SELECT id, COALESCE(t.descr, b.descr) AS descr FROM levels b LEFT JOIN languages l ON l.code = :lang LEFT JOIN level_languages t ON t.level_ID = b.id AND t.languages_ID = l.id ORDER BY b.id`; return [sql, { lang }] as const; } // src/repositories/loyalty/repository.ts — executes and transforms export async function getLevelsRe