Appearance
上下文
¥Context
要处理请求和响应,可以使用 Context
对象。
¥To handle Request and Response, you can use Context
object.
req
req
是 HonoRequest 的实例。有关更多详细信息,请参阅 HonoRequest。
¥req
is the instance of HonoRequest. For more details, see HonoRequest.
ts
app.get('/hello', (c) => {
const userAgent = c.req.header('User-Agent')
// ...
})
body()
返回 HTTP 响应。
¥Return the HTTP response.
你可以使用 c.header()
设置标头,并使用 c.status
设置 HTTP 状态代码。这也可以在 c.text()
、c.json()
等中设置。
¥You can set headers with c.header()
and set HTTP status code with c.status
. This can also be set in c.text()
, c.json()
and so on.
信息
注意:返回文本或 HTML 时,建议使用 c.text()
或 c.html()
。
¥Note: When returning Text or HTML, it is recommended to use c.text()
or c.html()
.
ts
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')
})
你还可以编写以下内容。
¥You can also write the following.
ts
app.get('/welcome', (c) => {
return c.body('Thank you for coming', 201, {
'X-Message': 'Hello!',
'Content-Type': 'text/plain',
})
})
响应与下面相同。
¥The Response is the same as below.
ts
new Response('Thank you for coming', {
status: 201,
headers: {
'X-Message': 'Hello!',
'Content-Type': 'text/plain',
},
})
text()
将文本渲染为 Content-Type:text/plain
。
¥Render text as Content-Type:text/plain
.
ts
app.get('/say', (c) => {
return c.text('Hello!')
})
json()
将 JSON 渲染为 Content-Type:application/json
。
¥Render JSON as Content-Type:application/json
.
ts
app.get('/api', (c) => {
return c.json({ message: 'Hello!' })
})
html()
将 HTML 渲染为 Content-Type:text/html
。
¥Render HTML as Content-Type:text/html
.
ts
app.get('/', (c) => {
return c.html('<h1>Hello! Hono!</h1>')
})
notFound()
返回 Not Found
响应。
¥Return the Not Found
Response.
ts
app.get('/notfound', (c) => {
return c.notFound()
})
redirect()
重定向,默认状态代码为 302
。
¥Redirect, default status code is 302
.
ts
app.get('/redirect', (c) => {
return c.redirect('/')
})
app.get('/redirect-permanently', (c) => {
return c.redirect('/', 301)
})
res
ts
// Response object
app.use('/', async (c, next) => {
await next()
c.res.headers.append('X-Debug', 'Debug message')
})
set() / get()
获取和设置任意键值对,具有当前请求的生命周期。这允许在中间件之间或从中间件到路由处理程序传递特定值。
¥Get and set arbitrary key-value pairs, with a lifetime of the current request. This allows passing specific values between middleware or from middleware to route handlers.
ts
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}"`)
})
将 Variables
作为泛型传递给 Hono
的构造函数,使其类型安全。
¥Pass the Variables
as Generics to the constructor of Hono
to make it type-safe.
ts
type Variables = {
message: string
}
const app = new Hono<{ Variables: Variables }>()
c.set
/c.get
的值仅在同一请求中保留。它们不能在不同的请求之间共享或持久化。
¥The value of c.set
/ c.get
are retained only within the same request. They cannot be shared or persisted across different requests.
var
你还可以使用 c.var
访问变量的值。
¥You can also access the value of a variable with c.var
.
ts
const result = c.var.client.oneMethod()
如果你想要创建提供自定义方法的中间件,请像下面这样写:
¥If you want to create the middleware which provides a custom method, write like the following:
ts
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
的构造函数以使其类型安全。
¥If you want to use the middleware in multiple handlers, you can use app.use()
. Then, you have to pass the Env
as Generics to the constructor of Hono
to make it type-safe.
ts
const app = new Hono<Env>()
app.use(echoMiddleware)
app.get('/echo', (c) => {
return c.text(c.var.echo('Hello!'))
})
render() / setRenderer()
你可以在自定义中间件中使用 c.setRenderer()
设置布局。
¥You can set a layout using c.setRenderer()
within a custom middleware.
tsx
app.use(async (c, next) => {
c.setRenderer((content) => {
return c.html(
<html>
<body>
<p>{content}</p>
</body>
</html>
)
})
await next()
})
然后,你可以利用 c.render()
在此布局中创建响应。
¥Then, you can utilize c.render()
to create responses within this layout.
ts
app.get('/', (c) => {
return c.render('Hello!')
})
其输出将是:
¥The output of which will be:
html
<html>
<body>
<p>Hello!</p>
</body>
</html>
此外,此功能提供了自定义参数的灵活性。为了确保类型安全,类型可以定义为:
¥Additionally, this feature offers the flexibility to customize arguments. To ensure type safety, types can be defined as:
ts
declare module 'hono' {
interface ContextRenderer {
(
content: string | Promise<string>,
head: { title: string }
): Response | Promise<Response>
}
}
以下是如何使用它的示例:
¥Here's an example of how you can use this:
ts
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
ts
// ExecutionContext object
app.get('/foo', async (c) => {
c.executionCtx.waitUntil(c.env.KV.put(key, data))
// ...
})
event
ts
// 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 中,绑定到 worker 的环境变量、密钥、KV 命名空间、D1 数据库、R2 bucket 等称为绑定。无论类型如何,绑定始终可用作全局变量,并可通过上下文 c.env.BINDING_KEY
访问。
¥In Cloudflare Workers Environment variables, secrets, KV namespaces, D1 database, R2 bucket etc. that are bound to a worker are known as bindings. Regardless of type, bindings are always available as global variables and can be accessed via the context c.env.BINDING_KEY
.
ts
// 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
如果 Handler 抛出错误,则错误对象将放置在 c.error
中。你可以在中间件中访问它。
¥If the Handler throws an error, the error object is placed in c.error
. You can access it in your middleware.
ts
app.use(async (c, next) => {
await next()
if (c.error) {
// do something...
}
})
ContextVariableMap
例如,如果你希望在使用特定中间件时向变量添加类型定义,则可以扩展 ContextVariableMap
。例如:
¥For instance, if you wish to add type definitions to variables when a specific middleware is used, you can extend ContextVariableMap
. For example:
ts
declare module 'hono' {
interface ContextVariableMap {
result: string
}
}
然后,你可以在中间件中使用它:
¥You can then utilize this in your middleware:
ts
const mw = createMiddleware(async (c, next) => {
c.set('result', 'some values') // result is a string
await next()
})
在处理程序中,变量被推断为正确的类型:
¥In a handler, the variable is inferred as the proper type:
ts
app.get('/', (c) => {
const val = c.get('result') // val is a string
// ...
return c.json({ result: val })
})