HonoRequest
HonoRequest는 Request 객체를 감싸는 객체로, c.req에서 가져올 수 있다.
param()
경로 파라미터의 값을 가져온다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
// 캡처된 파라미터
app.get('/entry/:id', async (c) => {
const id = c.req.param('id')
// ^?
// ...
})
// 모든 파라미터를 한 번에 가져오기
app.get('/entry/:id/comment/:commentId', async (c) => {
const { id, commentId } = c.req.param()
// ^?
})query()
쿼리스트링 파라미터를 가져온다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
// 쿼리 파라미터
app.get('/search', async (c) => {
const query = c.req.query('q')
// ^?
})
// 모든 파라미터를 한 번에 가져오기
app.get('/search', async (c) => {
const { q, limit, offset } = c.req.query()
// ^?
})쿼리 파라미터 다중 값 가져오기
여러 개의 쿼리스트링 파라미터 값을 가져오는 방법을 알아본다. 예를 들어 /search?tags=A&tags=B와 같은 URL에서 tags 파라미터의 값을 모두 추출할 수 있다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.get('/search', async (c) => {
// tags는 string[] 타입으로 반환된다
const tags = c.req.queries('tags')
// ^?
// ...
})header()
요청 헤더 값을 가져온다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.get('/', (c) => {
const userAgent = c.req.header('User-Agent')
// ^?
return c.text(`Your user agent is ${userAgent}`)
})WARNING
c.req.header()를 인자 없이 호출하면 반환된 레코드의 모든 키는 소문자로 표시된다.
대문자로 된 헤더 이름의 값을 가져오려면 c.req.header("X-Foo")를 사용한다.
// ❌ 동작하지 않음
const headerRecord = c.req.header()
const foo = headerRecord['X-Foo']
// ✅ 정상 동작
const foo = c.req.header('X-Foo')parseBody()
multipart/form-data 또는 application/x-www-form-urlencoded 타입의 요청 본문을 파싱한다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.post('/entry', async (c) => {
const body = await c.req.parseBody()
// ...
})parseBody()는 다음과 같은 동작을 지원한다.
단일 파일
import { Context } from 'hono'
declare const c: Context
// ---cut---
const body = await c.req.parseBody()
const data = body['foo']
// ^?body['foo']는 (string | File) 타입이다.
여러 파일이 업로드되면 마지막 파일이 사용된다.
여러 파일
import { Context } from 'hono'
declare const c: Context
// ---cut---
const body = await c.req.parseBody()
body['foo[]']body['foo[]']는 항상 (string | File)[] 타입이다.
[] 접미사가 필요하다.
동일한 이름의 여러 파일 처리
import { Context } from 'hono'
declare const c: Context
// ---cut---
const body = await c.req.parseBody({ all: true })
body['foo']all 옵션은 기본적으로 비활성화되어 있다.
body['foo']가 여러 파일인 경우,(string | File)[]타입으로 파싱된다.body['foo']가 단일 파일인 경우,(string | File)타입으로 파싱된다.
점 표기법
dot 옵션을 true로 설정하면 반환값이 점 표기법에 따라 구조화된다.
다음과 같은 데이터를 받는 상황을 가정해 보자:
const data = new FormData()
data.append('obj.key1', 'value1')
data.append('obj.key2', 'value2')dot 옵션을 true로 설정하면 구조화된 값을 얻을 수 있다:
import { Context } from 'hono'
declare const c: Context
// ---cut---
const body = await c.req.parseBody({ dot: true })
// body는 `{ obj: { key1: 'value1', key2: 'value2' } }`가 된다json()
application/json 타입의 요청 본문을 파싱한다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.post('/entry', async (c) => {
const body = await c.req.json()
// ...
})text()
text/plain 타입의 요청 본문을 파싱한다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.post('/entry', async (c) => {
const body = await c.req.text()
// ...
})arrayBuffer()
요청 본문을 ArrayBuffer로 파싱한다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.post('/entry', async (c) => {
const body = await c.req.arrayBuffer()
// ...
})blob()
요청 본문을 Blob으로 파싱한다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.post('/entry', async (c) => {
const body = await c.req.blob()
// ...
})formData()
요청 본문을 FormData로 파싱한다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.post('/entry', async (c) => {
const body = await c.req.formData()
// ...
})valid()
검증된 데이터를 가져온다.
app.post('/posts', async (c) => {
const { title, body } = c.req.valid('form')
// ...
})사용 가능한 대상은 다음과 같다.
formjsonqueryheadercookieparam
사용 예제는 검증 섹션을 참고한다.
routePath()
핸들러 내부에서 등록된 경로를 다음과 같이 가져올 수 있다:
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.get('/posts/:id', (c) => {
return c.json({ path: c.req.routePath })
})/posts/123에 접근하면 /posts/:id를 반환한다:
{ "path": "/posts/:id" }matchedRoutes()
이 함수는 핸들러 내에서 매칭된 라우트를 반환한다. 디버깅에 유용하게 사용할 수 있다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.use(async function logger(c, next) {
await next()
c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
const name =
handler.name ||
(handler.length < 2 ? '[handler]' : '[middleware]')
console.log(
method,
' ',
path,
' '.repeat(Math.max(10 - path.length, 0)),
name,
i === c.req.routeIndex ? '<- respond from here' : ''
)
})
})경로
요청 경로명을 나타낸다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.get('/about/me', async (c) => {
const pathname = c.req.path // `/about/me`
// ...
})url
요청 URL 문자열을 다룬다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.get('/about/me', async (c) => {
const url = c.req.url // `http://localhost:8787/about/me`
// ...
})메서드
요청의 메서드 이름을 나타낸다.
import { Hono } from 'hono'
const app = new Hono()
// ---cut---
app.get('/about/me', async (c) => {
const method = c.req.method // `GET`
// ...
})raw
Request 객체의 원본(raw) 데이터.
// Cloudflare Workers용
app.post('/', async (c) => {
const metadata = c.req.raw.cf?.hostMetadata?
// ...
})