コンテンツにスキップ

ベストプラクティス

Honoは非常に柔軟です。好きなようにアプリを書くことができます。ただし、従うべきベストプラクティスがいくつかあります。

可能な場合は「コントローラー」を作成しない

可能であれば、"Ruby on Railsのようなコントローラー"を作成しないでください。

ts
// 🙁
// A RoR-like Controller
const booksList = (c: Context) => {
  return c.json('list books')
}

app.get('/books', booksList)

この問題は型に関連しています。たとえば、パスパラメータは、複雑なジェネリクスを記述しないとコントローラー内で推論できません。

ts
// 🙁
// A RoR-like Controller
const bookPermalink = (c: Context) => {
  const id = c.req.param('id') // Can't infer the path param
  return c.json(`get ${id}`)
}

したがって、RoRのようなコントローラーを作成する必要はなく、パスの定義の直後にハンドラーを直接書く必要があります。

ts
// 😃
app.get('/books/:id', (c) => {
  const id = c.req.param('id') // Can infer the path param
  return c.json(`get ${id}`)
})

factory.createHandlers() in hono/factory

それでもRoRのようなコントローラーを作成したい場合は、hono/factoryfactory.createHandlers()を使用します。これを使用すると、型推論が正常に機能します。

ts
import { createFactory } from 'hono/factory'
import { logger } from 'hono/logger'

// ...

// 😃
const factory = createFactory()

const middleware = factory.createMiddleware(async (c, next) => {
  c.set('foo', 'bar')
  await next()
})

const handlers = factory.createHandlers(logger(), middleware, (c) => {
  return c.json(c.var.foo)
})

app.get('/api', ...handlers)

大規模なアプリケーションの構築

app.route()を使用して、"Ruby on Railsのようなコントローラー"を作成せずに、大規模なアプリケーションを構築します。

アプリケーションに/authors/booksのエンドポイントがあり、index.tsからファイルを分離する場合は、authors.tsbooks.tsを作成します。

ts
// authors.ts
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => c.json('list authors'))
app.post('/', (c) => c.json('create an author', 201))
app.get('/:id', (c) => c.json(`get ${c.req.param('id')}`))

export default app
ts
// books.ts
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => c.json('list books'))
app.post('/', (c) => c.json('create a book', 201))
app.get('/:id', (c) => c.json(`get ${c.req.param('id')}`))

export default app

次に、それらを読み込み、app.route()/authors/booksのパスにマウントします。

ts
// index.ts
import { Hono } from 'hono'
import authors from './authors'
import books from './books'

const app = new Hono()

app.route('/authors', authors)
app.route('/books', books)

export default app

上記のコードは問題なく動作します。ただし、これを実行すると型安全性は失われます。RPC機能を使用する場合は、次のようにメソッドをチェーンする方法がより適切なソリューションです。

ts
// authors.ts
import { Hono } from "hono";

const app = new Hono()
  .get("/", (c) => c.json("list authors"))
  .post("/", (c) => c.json("create an author", 201))
  .get("/:id", (c) => c.json(`get ${c.req.param("id")}`));

export default app;

この方法でこのルートを使用する場合、型を適切に推測できます。

MITライセンスに基づいてリリースされました。