Context と Request/Response
ハンドラに渡される c(Context)が Hono の操作の中心。
リクエストの読み取り、レスポンスの構築、ミドルウェア間の値共有、環境変数アクセスをここで行う。
Context の中身
| プロパティ | 役割 |
|---|---|
c.req | リクエスト(Hono の HonoRequest ラッパ) |
c.res | レスポンス |
c.env | 環境変数(Cloudflare Bindings 等) |
c.executionCtx | 実行コンテキスト(Cloudflare の waitUntil 等) |
c.event | イベント情報(環境による) |
c.var | middleware 間の値共有 |
c.set(k, v) / c.get(k) | middleware 間で値の受け渡し |
c.text/json/html/body/redirect | レスポンスヘルパー |
c.status(n) / c.header(k, v) | レスポンス調整 |
Request の読み取り(c.req)
パス・メソッド・URL
c.req.path // /users/123
c.req.method // "GET"
c.req.url // フル URL
c.req.routePath // "/users/:id"
c.req.matchedRoutes // マッチしたルート情報
パラメータ・クエリ
c.req.param("id") // パスパラメータ
c.req.param() // 全パラメータ object
c.req.query("q") // 単一クエリ
c.req.queries("tag") // 複数クエリ(配列)
c.req.query() // 全クエリ object
ヘッダー
c.req.header("user-agent") // 単一
c.req.header() // 全ヘッダー object(小文字キー)
// Web 標準の Headers が欲しい時
c.req.raw.headers
ボディの読み取り
// JSON
const data = await c.req.json<{ name: string }>()
// テキスト
const text = await c.req.text()
// FormData
const form = await c.req.formData()
const file = form.get("file") as File | null
// parseBody(URLエンコード or multipart 自動判定)
const body = await c.req.parseBody()
// body.field, body.file 等
// 生 ArrayBuffer
const buf = await c.req.arrayBuffer()
// Blob
const blob = await c.req.blob()
Cookie
import { getCookie, setCookie, deleteCookie } from "hono/cookie"
const sid = getCookie(c, "session_id")
setCookie(c, "session_id", "abc123", {
httpOnly: true,
secure: true,
sameSite: "Lax",
maxAge: 3600,
path: "/",
})
deleteCookie(c, "session_id")
低レベル: 生 Request
const raw: Request = c.req.raw
// fetch の Request そのもの
Response の構築
ヘルパー
return c.text("Hello", 200)
return c.json({ ok: true }, 201)
return c.html("<h1>Hi</h1>")
return c.redirect("/login", 302)
return c.notFound()
return c.body(null, 204) // No Content
ヘッダーの追加
c.header("X-Custom", "value")
c.header("Cache-Control", "max-age=60")
return c.json({ ok: true })
// または直接渡す
return c.json({ ok: true }, 200, {
"X-Custom": "value",
"Cache-Control": "max-age=60",
})
低レベル: Response 直接
return new Response("Raw", { status: 200, headers: { "Content-Type": "text/plain" } })
// または c.newResponse
return c.newResponse("Raw", 200, { "Content-Type": "text/plain" })
環境変数(c.env)
Cloudflare Workers のBindings(KV, Durable Objects, R2, D1, Secrets)はここから。
type Bindings = {
DB: D1Database
KV: KVNamespace
AI: Ai
SECRET_KEY: string
}
const app = new Hono<{ Bindings: Bindings }>()
app.get("/", async (c) => {
const result = await c.env.DB.prepare("SELECT 1").first()
const cached = await c.env.KV.get("key")
return c.json({ result, cached })
})
Node.js / Bun では process.env ベースで自分で型を作る。
Variables(middleware 間の値共有)
ある middleware で計算した値を、後続のハンドラで使う。request-scoped。
type Variables = {
user: { id: string, name: string }
requestId: string
}
const app = new Hono<{ Variables: Variables }>()
app.use(async (c, next) => {
c.set("requestId", crypto.randomUUID())
await next()
})
app.use("/api/*", async (c, next) => {
const token = c.req.header("authorization")
if (!token) return c.text("Unauthorized", 401)
const user = await verifyToken(token)
c.set("user", user)
await next()
})
app.get("/api/me", (c) => {
const user = c.get("user") // 型推論される
const id = c.var.requestId // c.var でも OK
return c.json({ user, id })
})
executionCtx と waitUntil
Cloudflare Workers では「レスポンスを返した後でも実行を続ける」ことが executionCtx.waitUntil でできる。
解析・ロギング・キャッシュ更新の定石。
app.get("/api/data", (c) => {
c.executionCtx.waitUntil(
logToAnalytics({ path: c.req.path, ts: Date.now() })
)
return c.json({ data: ... })
})
型を全体で共有
Bindings / Variables をモジュール全体で使うため、型を1か所に集めてアプリ全体に伝播させる。
export type AppEnv = {
Bindings: { DB: D1Database }
Variables: { user?: User }
}
export const app = new Hono<AppEnv>()
import { Hono } from "hono"
import type { AppEnv } from "../app"
const users = new Hono<AppEnv>()
users.get("/", (c) => {
// c.env.DB が型付きで使える
})
export default users
req.valid(バリデータ連携)
@hono/zod-validator 等を通すと、検証済みの値が c.req.valid("json") 等で取れる。
詳細は バリデーション。
標準 fetch との互換
Hono のハンドラの引数は Context だが、内部で扱っているのは Web 標準の Request/Response。
どこでも fetch の世界観で書ける。
c.req は HonoRequest クラス。便利メソッドが乗っている。
素の Request が欲しい時は c.req.raw。