コンテキスト
リクエストとレスポンスを処理するために、Context
オブジェクトを使用できます。
req
req
はHonoRequestのインスタンスです。
app.get('/hello', (c) => {
const userAgent = c.req.header('User-Agent')
// ...
})
body()
HTTPレスポンスを返します。
c.header()
でヘッダーを設定し、c.status
でHTTPステータスコードを設定できます。これはc.text()
、c.json()
などでも設定できます。
情報
注意: テキストまたはHTMLを返す場合は、c.text()
またはc.html()
を使用することをお勧めします。
app.get('/welcome', (c) => {
// Set headers
c.header('X-Message', 'Hello!')
c.header('Content-Type', 'text/plain')
// Set HTTP status code
c.status(201)
// Return the response body
return c.body('Thank you for coming')
})
次のように書くこともできます。
app.get('/welcome', (c) => {
return c.body('Thank you for coming', 201, {
'X-Message': 'Hello!',
'Content-Type': 'text/plain',
})
})
レスポンスは以下と同じです。
new Response('Thank you for coming', {
status: 201,
headers: {
'X-Message': 'Hello!',
'Content-Type': 'text/plain',
},
})
text()
テキストをContent-Type:text/plain
としてレンダリングします。
app.get('/say', (c) => {
return c.text('Hello!')
})
json()
JSONをContent-Type:application/json
としてレンダリングします。
app.get('/api', (c) => {
return c.json({ message: 'Hello!' })
})
html()
HTMLをContent-Type:text/html
としてレンダリングします。
app.get('/', (c) => {
return c.html('<h1>Hello! Hono!</h1>')
})
notFound()
Not Found
レスポンスを返します。
app.get('/notfound', (c) => {
return c.notFound()
})
redirect()
リダイレクトします。デフォルトのステータスコードは302
です。
app.get('/redirect', (c) => {
return c.redirect('/')
})
app.get('/redirect-permanently', (c) => {
return c.redirect('/', 301)
})
res
// Response object
app.use('/', async (c, next) => {
await next()
c.res.headers.append('X-Debug', 'Debug message')
})
set() / get()
現在のリクエストの有効期間を持つ任意のキーと値のペアを取得および設定します。これにより、ミドルウェア間、またはミドルウェアからルートハンドラーへの特定の値の受け渡しが可能になります。
app.use(async (c, next) => {
c.set('message', 'Hono is cool!!')
await next()
})
app.get('/', (c) => {
const message = c.get('message')
return c.text(`The message is "${message}"`)
})
Hono
のコンストラクターにVariables
をジェネリクスとして渡して、型安全にすることができます。
type Variables = {
message: string
}
const app = new Hono<{ Variables: Variables }>()
c.set
/c.get
の値は、同じリクエスト内でのみ保持されます。異なるリクエスト間で共有したり、永続化したりすることはできません。
var
c.var
を使用して変数の値にアクセスすることもできます。
const result = c.var.client.oneMethod()
カスタムメソッドを提供するミドルウェアを作成したい場合は、次のように記述します。
type Env = {
Variables: {
echo: (str: string) => string
}
}
const app = new Hono()
const echoMiddleware = createMiddleware<Env>(async (c, next) => {
c.set('echo', (str) => str)
await next()
})
app.get('/echo', echoMiddleware, (c) => {
return c.text(c.var.echo('Hello!'))
})
複数のハンドラーでミドルウェアを使用したい場合は、app.use()
を使用できます。次に、型安全にするために、Env
をジェネリクスとしてHono
のコンストラクターに渡す必要があります。
const app = new Hono<Env>()
app.use(echoMiddleware)
app.get('/echo', (c) => {
return c.text(c.var.echo('Hello!'))
})
render() / setRenderer()
カスタムミドルウェア内でc.setRenderer()
を使用してレイアウトを設定できます。
app.use(async (c, next) => {
c.setRenderer((content) => {
return c.html(
<html>
<body>
<p>{content}</p>
</body>
</html>
)
})
await next()
})
次に、c.render()
を使用してこのレイアウト内でレスポンスを作成できます。
app.get('/', (c) => {
return c.render('Hello!')
})
出力は次のようになります。
<html>
<body>
<p>Hello!</p>
</body>
</html>
さらに、この機能は引数をカスタマイズする柔軟性を提供します。型安全性を確保するために、型は次のように定義できます。
declare module 'hono' {
interface ContextRenderer {
(
content: string | Promise<string>,
head: { title: string }
): Response | Promise<Response>
}
}
以下に、この使用例を示します。
app.use('/pages/*', async (c, next) => {
c.setRenderer((content, head) => {
return c.html(
<html>
<head>
<title>{head.title}</title>
</head>
<body>
<header>{head.title}</header>
<p>{content}</p>
</body>
</html>
)
})
await next()
})
app.get('/pages/my-favorite', (c) => {
return c.render(<p>Ramen and Sushi</p>, {
title: 'My favorite',
})
})
app.get('/pages/my-hobbies', (c) => {
return c.render(<p>Watching baseball</p>, {
title: 'My hobbies',
})
})
executionCtx
// ExecutionContext object
app.get('/foo', async (c) => {
c.executionCtx.waitUntil(c.env.KV.put(key, data))
// ...
})
event
// Type definition to make type inference
type Bindings = {
MY_KV: KVNamespace
}
const app = new Hono<{ Bindings: Bindings }>()
// FetchEvent object (only set when using Service Worker syntax)
app.get('/foo', async (c) => {
c.event.waitUntil(c.env.MY_KV.put(key, data))
// ...
})
env
Cloudflare Workers環境では、ワーカーにバインドされた環境変数、シークレット、KV名前空間、D1データベース、R2バケットなどはバインディングとして知られています。型に関係なく、バインディングは常にグローバル変数として利用可能であり、コンテキストc.env.BINDING_KEY
を介してアクセスできます。
// Type definition to make type inference
type Bindings = {
MY_KV: KVNamespace
}
const app = new Hono<{ Bindings: Bindings }>()
// Environment object for Cloudflare Workers
app.get('/', async (c) => {
c.env.MY_KV.get('my-key')
// ...
})
error
ハンドラーがエラーをスローすると、エラーオブジェクトがc.error
に配置されます。ミドルウェアでアクセスできます。
app.use(async (c, next) => {
await next()
if (c.error) {
// do something...
}
})
ContextVariableMap
たとえば、特定のミドルウェアが使用されている場合に変数に型定義を追加したい場合は、ContextVariableMap
を拡張できます。例:
declare module 'hono' {
interface ContextVariableMap {
result: string
}
}
これをミドルウェアで使用できます。
const mw = createMiddleware(async (c, next) => {
c.set('result', 'some values') // result is a string
await next()
})
ハンドラーでは、変数は適切な型として推論されます。
app.get('/', (c) => {
const val = c.get('result') // val is a string
// ...
return c.json({ result: val })
})