Skip to content

App - Hono

Hono는 주요 객체이다. 이 객체를 가장 먼저 불러와서 끝까지 사용한다.

ts
import { Hono } from 'hono'

const app = new Hono()
//...

export default app // Cloudflare Workers나 Bun에서 사용

메서드

Hono 인스턴스는 다음과 같은 메서드를 제공한다.

  • app.HTTP_METHOD([path,]handler|middleware...)
  • app.all([path,]handler|middleware...)
  • app.on(method|method[], path|path[], handler|middleware...)
  • app.use([path,]middleware)
  • app.route(path, [app])
  • app.basePath(path)
  • app.notFound(handler)
  • app.onError(err, handler)
  • app.mount(path, anotherApp)
  • app.fire()
  • app.fetch(request, env, event)
  • app.request(path, options)

이 중 첫 번째 부분은 라우팅에 사용된다. 자세한 내용은 라우팅 섹션을 참고한다.

404 페이지 커스터마이징

app.notFound를 사용하면 404 응답을 커스터마이징할 수 있다.

ts
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.notFound((c) => {
  return c.text('Custom 404 Message', 404)
})

오류 처리

app.onError는 오류를 처리하고 커스텀 응답을 반환한다.

ts
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.onError((err, c) => {
  console.error(`${err}`)
  return c.text('Custom Error Message', 500)
})

fire()

app.fire()는 전역 fetch 이벤트 리스너를 자동으로 추가한다.

이 기능은 Service Worker API를 따르는 환경, 예를 들어 ES 모듈이 아닌 Cloudflare Workers에서 유용하게 사용할 수 있다.

app.fire()는 다음과 같은 작업을 자동으로 수행한다:

ts
addEventListener('fetch', (event: FetchEventLike): void => {
  event.respondWith(this.dispatch(...))
})

fetch()

app.fetch는 애플리케이션의 진입점이 된다.

Cloudflare Workers에서는 다음과 같이 사용할 수 있다:

ts
import { Hono } from 'hono'
const app = new Hono()
type Env = any
type ExecutionContext = any
// ---cut---
export default {
  fetch(request: Request, env: Env, ctx: ExecutionContext) {
    return app.fetch(request, env, ctx)
  },
}

또는 간단히 다음과 같이 작성할 수도 있다:

ts
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
export default app

Bun의 경우:

ts
export default app 
export default {  
  port: 3000, 
  fetch: app.fetch, 
} 

request()

request 메서드는 테스트에 유용하게 사용할 수 있다.

URL이나 경로명을 전달해 GET 요청을 보낼 수 있다. appResponse 객체를 반환한다.

ts
import { Hono } from 'hono'
const app = new Hono()
declare const test: (name: string, fn: () => void) => void
declare const expect: (value: any) => any
// ---cut---
test('GET /hello is ok', async () => {
  const res = await app.request('/hello')
  expect(res.status).toBe(200)
})

Request 객체를 전달할 수도 있다:

ts
import { Hono } from 'hono'
const app = new Hono()
declare const test: (name: string, fn: () => void) => void
declare const expect: (value: any) => any
// ---cut---
test('POST /message is ok', async () => {
  const req = new Request('Hello!', {
    method: 'POST',
  })
  const res = await app.request(req)
  expect(res.status).toBe(201)
})

mount()

mount()를 사용하면 다른 프레임워크로 만든 애플리케이션을 Hono 애플리케이션에 연결할 수 있다.

ts
import { Router as IttyRouter } from 'itty-router'
import { Hono } from 'hono'

// itty-router 애플리케이션 생성
const ittyRouter = IttyRouter()

// `GET /itty-router/hello` 요청 처리
ittyRouter.get('/hello', () => new Response('Hello from itty-router'))

// Hono 애플리케이션
const app = new Hono()

// 연결!
app.mount('/itty-router', ittyRouter.handle)

strict 모드

strict 모드는 기본값이 true이며, 다음 라우트를 구분한다.

  • /hello
  • /hello/

app.get('/hello')GET /hello/와 매치되지 않는다.

strict 모드를 false로 설정하면 두 경로를 동일하게 처리한다.

ts
import { Hono } from 'hono'
// ---cut---
const app = new Hono({ strict: false })

라우터 옵션

router 옵션은 사용할 라우터를 지정한다. 기본 라우터는 SmartRouter이다. RegExpRouter를 사용하려면 새로운 Hono 인스턴스에 전달한다:

ts
import { Hono } from 'hono'
// ---cut---
import { RegExpRouter } from 'hono/router/reg-exp-router'

const app = new Hono({ router: new RegExpRouter() })

제네릭

c.set/c.get에서 사용하는 Cloudflare Workers 바인딩과 변수의 타입을 지정하기 위해 제네릭을 전달할 수 있다.

ts
import { Hono } from 'hono'
type User = any
declare const user: User
// ---cut---
type Bindings = {
  TOKEN: string
}

type Variables = {
  user: User
}

const app = new Hono<{
  Bindings: Bindings
  Variables: Variables
}>()

app.use('/auth/*', async (c, next) => {
  const token = c.env.TOKEN // token은 `string` 타입
  // ...
  c.set('user', user) // user는 `User` 타입이어야 함
  await next()
})

Released under the MIT License.