本文へ移動

ルーティング ​

Hono のルーティングは柔軟で直感的です。 使い方を見てみましょう。

基本 ​

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 /'))
app
.
query
('/', (
c
) =>
c
.
text
('QUERY /'))
// 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')
)

パスパラメーター ​

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

すべてのパラメーターを一度に取得することもできます。

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

任意のパラメーター ​

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

正規表現 ​

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

スラッシュを含むパス ​

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

メソッドチェーンによるルート定義 ​

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

グループ化 ​

Hono インスタンスでルートをグループ化し、route メソッドでメインアプリに追加できます。

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
)

ベースパスを変更しないグループ化 ​

ベースパスを維持しながら、複数のインスタンスをグループ化することもできます。

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

ベースパス ​

ベースパスを指定できます。

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

ホスト名によるルーティング ​

ホスト名を含むルーティングにも対応しています。

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 ヘッダーの値によるルーティング ​

Hono のコンストラクターで getPath() 関数を設定すると、host ヘッダーの値を使ってルーティングできます。

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 ヘッダーに応じてルーティングを変更できます。

ルーティングの優先順位 ​

ハンドラーやミドルウェアは登録順に実行されます。

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`

ハンドラーが実行されると、処理は停止します。

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

実行したいミドルウェアがある場合は、そのコードをハンドラーより前に記述してください。

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

「フォールバック」ハンドラーを用意する場合は、ほかのハンドラーより後に記述してください。

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

グループ化の順序 ​

ルートのグループ化における順序の誤りは気づきにくいため、注意してください。 route() 関数は、第二引数(three や two など)に登録済みのルートを取り出し、自身(two や app)のルートに追加します。

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

export default app

この場合は、ステータスコード 200 のレスポンスを返します。

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

しかし、順序が間違っていると 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

MIT ライセンスで公開されています。