Skip to content

路由

¥Routing

Hono 的路由灵活且直观。让我们看一看。

¥Routing of Hono is flexible and intuitive. Let's take a look.

基本

¥Basic

ts
// HTTP Methods
app
.
get
('/', (
c
) =>
c
.
text
('GET /'))
app
.
post
('/', (
c
) =>
c
.
text
('POST /'))
app
.
put
('/', (
c
) =>
c
.
text
('PUT /'))
app
.
delete
('/', (
c
) =>
c
.
text
('DELETE /'))
// Wildcard
app
.
get
('/wild/*/card', (
c
) => {
return
c
.
text
('GET /wild/*/card')
}) // Any HTTP methods
app
.
all
('/hello', (
c
) =>
c
.
text
('Any Method /hello'))
// Custom HTTP method
app
.
on
('PURGE', '/cache', (
c
) =>
c
.
text
('PURGE Method /cache'))
// Multiple Method
app
.
on
(['PUT', 'DELETE'], '/post', (
c
) =>
c
.
text
('PUT or DELETE /post')
) // Multiple Paths
app
.
on
('GET', ['/hello', '/ja/hello', '/en/hello'], (
c
) =>
c
.
text
('Hello')
)

路径参数

¥Path Parameter

ts
app
.
get
('/user/:name', async (
c
) => {
const
name
=
c
.
req
.
param
('name')
// ... })

或一次所有参数:

¥or all parameters at once:

ts
app
.
get
('/posts/:id/comment/:comment_id', async (
c
) => {
const {
id
,
comment_id
} =
c
.
req
.
param
()
// ... })

可选参数

¥Optional Parameter

ts
// Will match `/api/animal` and `/api/animal/:type`
app
.
get
('/api/animal/:type?', (
c
) =>
c
.
text
('Animal!'))

正则表达式

¥Regexp

ts
app
.
get
('/post/:date{[0-9]+}/:title{[a-z]+}', async (
c
) => {
const {
date
,
title
} =
c
.
req
.
param
()
// ... })

包括斜线

¥Including slashes

ts
app
.
get
('/posts/:filename{.+\\.png}', async (
c
) => {
//... })

链式路由

¥Chained route

ts
app
.
get
('/endpoint', (
c
) => {
return
c
.
text
('GET /endpoint')
}) .
post
((
c
) => {
return
c
.
text
('POST /endpoint')
}) .
delete
((
c
) => {
return
c
.
text
('DELETE /endpoint')
})

分组

¥Grouping

你可以使用 Hono 实例对路由进行分组,并使用路由方法将它们添加到主应用。

¥You can group the routes with the Hono instance and add them to the main app with the route method.

ts
const 
book
= new
Hono
()
book
.
get
('/', (
c
) =>
c
.
text
('List Books')) // GET /book
book
.
get
('/:id', (
c
) => {
// GET /book/:id const
id
=
c
.
req
.
param
('id')
return
c
.
text
('Get Book: ' +
id
)
})
book
.
post
('/', (
c
) =>
c
.
text
('Create Book')) // POST /book
const
app
= new
Hono
()
app
.
route
('/book',
book
)

不改变基础的分组

¥Grouping without changing base

你还可以在保留基础的同时对多个实例进行分组。

¥You can also group multiple instances while keeping base.

ts
const 
book
= new
Hono
()
book
.
get
('/book', (
c
) =>
c
.
text
('List Books')) // GET /book
book
.
post
('/book', (
c
) =>
c
.
text
('Create Book')) // POST /book
const
user
= new
Hono
().
basePath
('/user')
user
.
get
('/', (
c
) =>
c
.
text
('List Users')) // GET /user
user
.
post
('/', (
c
) =>
c
.
text
('Create User')) // POST /user
const
app
= new
Hono
()
app
.
route
('/',
book
) // Handle /book
app
.
route
('/',
user
) // Handle /user

基本路径

¥Base path

你可以指定基本路径。

¥You can specify the base path.

ts
const 
api
= new
Hono
().
basePath
('/api')
api
.
get
('/book', (
c
) =>
c
.
text
('List Books')) // GET /api/book

使用主机名进行路由

¥Routing with hostname

如果它包含主机名,它可以正常工作。

¥It works fine if it includes a hostname.

ts
const 
app
= new
Hono
({
getPath
: (
req
) =>
req
.
url
.
replace
(/^https?:\/([^?]+).*$/, '$1'),
})
app
.
get
('/www1.example.com/hello', (
c
) =>
c
.
text
('hello www1'))
app
.
get
('/www2.example.com/hello', (
c
) =>
c
.
text
('hello www2'))

路由使用 host 标头值

¥Routing with host Header value

如果在 Hono 构造函数中设置 getPath() 函数,Hono 可以处理 host 标头值。

¥Hono can handle the host header value if you set the getPath() function in the Hono constructor.

ts
const 
app
= new
Hono
({
getPath
: (
req
) =>
'/' +
req
.
headers
.
get
('host') +
req
.
url
.
replace
(/^https?:\/\/[^/]+(\/[^?]*)/, '$1'),
})
app
.
get
('/www1.example.com/hello', (
c
) =>
c
.
text
('hello www1'))
// A following request will match the route: // new Request('http://www1.example.com/hello', { // headers: { host: 'www1.example.com' }, // })

例如,通过应用此功能,你可以通过 User-Agent 标头更改路由。

¥By applying this, for example, you can change the routing by User-Agent header.

路由优先级

¥Routing priority

处理程序或中间件将按注册顺序执行。

¥Handlers or middleware will be executed in registration order.

ts
app
.
get
('/book/a', (
c
) =>
c
.
text
('a')) // a
app
.
get
('/book/:slug', (
c
) =>
c
.
text
('common')) // common
GET /book/a ---> `a`
GET /book/b ---> `common`

执行处理程序时,该过程将停止。

¥When a handler is executed, the process will be stopped.

ts
app
.
get
('*', (
c
) =>
c
.
text
('common')) // common
app
.
get
('/foo', (
c
) =>
c
.
text
('foo')) // foo
GET /foo ---> `common` // foo will not be dispatched

如果你有要执行的中间件,请在处理程序上方编写代码。

¥If you have the middleware that you want to execute, write the code above the handler.

ts
app
.
use
(
logger
())
app
.
get
('/foo', (
c
) =>
c
.
text
('foo'))

如果你想要有一个 "fallback" 处理程序,请在另一个处理程序下方编写代码。

¥If you want to have a "fallback" handler, write the code below the other handler.

ts
app
.
get
('/bar', (
c
) =>
c
.
text
('bar')) // bar
app
.
get
('*', (
c
) =>
c
.
text
('fallback')) // fallback
GET /bar ---> `bar`
GET /foo ---> `fallback`

分组顺序

¥Grouping ordering

请注意,分组路由的错误很难注意到。route() 函数从第二个参数(例如 threetwo)获取存储的路由并将其添加到其自己的(twoapp)路由中。

¥Note that the mistake of grouping routings is hard to notice. The route() function takes the stored routing from the second argument (such as three or two) and adds it to its own (two or app) routing.

ts
three.get('/hi', (c) => c.text('hi'))
two.route('/three', three)
app.route('/two', two)

export default app

它将返回 200 个响应。

¥It will return 200 response.

GET /two/three/hi ---> `hi`

但是,如果它们的顺序错误,它将返回 404。

¥However, if they are in the wrong order, it will return a 404.

ts
three
.
get
('/hi', (
c
) =>
c
.
text
('hi'))
app
.
route
('/two',
two
) // `two` does not have routes
two
.
route
('/three',
three
)
export default
app
GET /two/three/hi ---> 404 Not Found

Hono v4.7 中文网 - 粤ICP备13048890号