Routage
Le routage de Hono est flexible et intuitif. Voyons comment il fonctionne.
Notions de base
// 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')
)Paramètres de chemin
app.get('/user/:name', async (c) => {
const name = c.req.param('name')
// ...
})Ou tous les paramètres à la fois :
app.get('/posts/:id/comment/:comment_id', async (c) => {
const { id, comment_id } = c.req.param()
// ...
})Paramètres facultatifs
// Will match `/api/animal` and `/api/animal/:type`
app.get('/api/animal/:type?', (c) => c.text('Animal!'))Expressions régulières
app.get('/post/:date{[0-9]+}/:title{[a-z]+}', async (c) => {
const { date, title } = c.req.param()
// ...
})Chemins contenant des barres obliques
app.get('/posts/:filename{.+\\.png}', async (c) => {
//...
})Routes chaînées
app
.get('/endpoint', (c) => {
return c.text('GET /endpoint')
})
.post((c) => {
return c.text('POST /endpoint')
})
.delete((c) => {
return c.text('DELETE /endpoint')
})Regroupement
Vous pouvez regrouper des routes dans une instance de Hono et les ajouter à l’application principale avec la méthode route.
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)Regrouper sans modifier le chemin de base
Vous pouvez également regrouper plusieurs instances en conservant leurs chemins de base.
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 /userChemin de base
Vous pouvez définir un chemin de base.
const api = new Hono().basePath('/api')
api.get('/book', (c) => c.text('List Books')) // GET /api/bookRoutage avec un nom d’hôte
Le routage fonctionne également avec les routes contenant un nom d’hôte.
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'))Routage avec la valeur de l’en-tête host
Hono peut utiliser la valeur de l’en-tête host pour le routage si vous définissez la fonction getPath() dans son constructeur.
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' },
// })En appliquant cette approche, vous pouvez, par exemple, modifier le routage en fonction de l’en-tête User-Agent.
Priorité du routage
Les gestionnaires et les middlewares s’exécutent dans l’ordre de leur enregistrement.
app.get('/book/a', (c) => c.text('a')) // a
app.get('/book/:slug', (c) => c.text('common')) // commonGET /book/a ---> `a`
GET /book/b ---> `common`Lorsqu’un gestionnaire est exécuté, le traitement s’arrête.
app.get('*', (c) => c.text('common')) // common
app.get('/foo', (c) => c.text('foo')) // fooGET /foo ---> `common` // foo will not be dispatchedSi vous souhaitez exécuter un middleware, enregistrez-le avant le gestionnaire.
app.use(logger())
app.get('/foo', (c) => c.text('foo'))Pour définir un gestionnaire de repli, enregistrez-le après les autres gestionnaires.
app.get('/bar', (c) => c.text('bar')) // bar
app.get('*', (c) => c.text('fallback')) // fallbackGET /bar ---> `bar`
GET /foo ---> `fallback`Ordre des regroupements
Attention : il est facile de ne pas remarquer une erreur dans l’ordre des regroupements de routes. La fonction route() prend les routes enregistrées dans son deuxième argument, par exemple three ou two, et les ajoute à ses propres routes, dans two ou app.
three.get('/hi', (c) => c.text('hi'))
two.route('/three', three)
app.route('/two', two)
export default appCela renvoie une réponse avec le code d’état 200.
GET /two/three/hi ---> `hi`En revanche, si l’ordre est incorrect, une réponse avec le code d’état 404 est renvoyée.
three.get('/hi', (c) => c.text('hi'))
app.route('/two', two) // `two` does not have routes
two.route('/three', three)
export default appGET /two/three/hi ---> 404 Not Found