Apidog

Platform Pengembangan API Kolaboratif All-in-one

Desain API

Dokumentasi API

Debug API

Mocking API

Pengujian Otomatis API

Panduan Pemula: Memulai dengan Hono.js

Mark Ponomarev

Mark Ponomarev

Updated on May 11, 2025

Dalam dunia pengembangan web yang cepat berkembang, menemukan framework yang tepat bisa menjadi tantangan. Anda menginginkan sesuatu yang cepat, ringan, dan cukup fleksibel untuk bekerja di berbagai lingkungan. Hadirlah Hono – sebuah framework web yang dengan cepat mendapatkan daya tarik di kalangan developer karena kecepatannya yang mengesankan, jejak minimal, dan desain yang ramah developer.

Hono (yang berarti "api" 🔥 dalam bahasa Jepang) diberi nama dengan tepat – framework ini sangat cepat dan menerangi pengalaman pengembangan Anda dengan kesederhanaannya yang elegan. Baik Anda membangun API, layanan mikro, atau aplikasi full-stack, Hono menawarkan alternatif yang menarik dibandingkan framework yang lebih berat.

Panduan ini akan memandu Anda melalui semua yang perlu Anda ketahui untuk memulai dengan Hono.js, mulai dari instalasi hingga membangun aplikasi pertama Anda dan memahami konsep intinya.

💡
Ingin alat Uji API yang hebat yang menghasilkan Dokumentasi API yang indah?

Ingin platform All-in-One yang terintegrasi agar Tim Developer Anda dapat bekerja sama dengan produktivitas maksimum?

Apidog memenuhi semua permintaan Anda, dan menggantikan Postman dengan harga yang jauh lebih terjangkau!
button

Apa itu Hono?

image-132.png

Hono adalah framework web kecil, sederhana, dan sangat cepat yang dibangun di atas Standar Web. Framework ini bekerja di hampir semua runtime JavaScript: Cloudflare Workers, Fastly Compute, Deno, Bun, Vercel, Netlify, AWS Lambda, Lambda@Edge, dan Node.js.

Pada intinya, Hono merangkul API Standar Web (seperti Request, Response, dan Fetch), yang memberikannya portabilitas luar biasa di berbagai platform. Ini berarti Anda dapat menulis kode Anda sekali dan menyebarkannya hampir di mana saja tanpa modifikasi besar.

import { Hono } from 'hono'
const app = new Hono()

app.get('/', (c) => c.text('Hono!'))

export default app

Contoh sederhana ini menunjukkan sintaks Hono yang bersih, terinspirasi oleh Express tetapi dimodernisasi untuk ekosistem JavaScript saat ini.

Mari kita mulai!

1. Instal Hono.js dengan Bun dan Pengaturan Proyek

Bun adalah runtime JavaScript modern yang dikenal karena kecepatan dan toolkit all-in-one-nya, termasuk manajer paket, bundler, dan test runner. Menyiapkan Hono dengan Bun sangat mudah.

Prasyarat

Pastikan Anda telah menginstal Bun. Jika belum, Anda dapat menginstalnya dengan mengikuti petunjuk di situs web resmi Bun.

Membuat Proyek Hono Baru dengan Bun

Cara tercepat untuk memulai proyek Hono baru dengan Bun adalah dengan menggunakan alat scaffolding create-hono:

bun create hono@latest my-hono-app

Perintah ini akan meminta Anda untuk memilih template. Untuk panduan ini, pilih template bun.

? Which template do you want to use? › - Use arrow keys. Return to submit.
❯   bun
    cloudflare-workers
    cloudflare-pages
    deno
    fastly
    netlify
    nodejs
    vercel

Setelah memilih template, masuk ke direktori proyek baru Anda dan instal dependensi:

cd my-hono-app
bun install

Menambahkan Hono ke Proyek Bun yang Sudah Ada

Jika Anda memiliki proyek Bun yang sudah ada, Anda dapat menambahkan Hono sebagai dependensi:

bun add hono

2. Membangun Aplikasi Dasar dengan Hono.js: "Hello Hono!"

Mari kita buat aplikasi sederhana "Hello World" (atau lebih tepatnya, "Hello Hono!").

Di dalam proyek Anda, seharusnya ada direktori src. Buat atau buka src/index.ts (atau index.js jika Anda lebih suka JavaScript biasa, meskipun TypeScript direkomendasikan untuk mendapatkan manfaat penuh dari Hono).

// src/index.ts
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => {
  return c.text('Hello Hono!')
})

export default app

Mari kita uraikan ini:

  1. Kita mengimpor kelas Hono dari paket hono.
  2. Kita membuat instance baru dari Hono, biasanya dinamai app.
  3. Kita mendefinisikan rute untuk permintaan GET ke path root (/).
  4. Handler rute adalah fungsi yang mengambil objek Context (secara konvensional c) sebagai argumen.
  5. c.text('Hello Hono!') membuat objek Response dengan teks biasa "Hello Hono!".
  6. Terakhir, kita mengekspor instance app. Untuk Bun, ekspor default ini cukup untuk server pengembangan untuk mengambilnya.

Menjalankan Aplikasi Anda

Untuk menjalankan aplikasi Anda dalam mode pengembangan, gunakan script dev yang didefinisikan dalam package.json Anda (yang disiapkan oleh create-hono untuk Anda):

bun run dev

Ini biasanya akan memulai server di http://localhost:3000. Buka URL ini di browser web Anda, dan Anda akan melihat "Hello Hono!".

Mengubah Port

Jika Anda perlu menjalankan aplikasi Anda di port yang berbeda, Anda dapat memodifikasi ekspor di src/index.ts:

// src/index.ts
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => {
  return c.text('Hello Hono on port 8080!')
})

export default {
  port: 8080, // Tentukan port yang Anda inginkan
  fetch: app.fetch,
}

Sekarang, saat Anda menjalankan bun run dev, aplikasi akan disajikan di http://localhost:8080.

3. Membangun API Dasar dengan Hono.js

Hono unggul dalam membangun API. Mari kita jelajahi routing, dan cara menangani permintaan serta membuat respons.

Routing

Routing di Hono sangat intuitif. Instance app memiliki metode yang sesuai dengan kata kerja HTTP (.get(), .post(), .put(), .delete(), dll.).

Rute GET Dasar

Kita sudah melihat rute GET dasar:

app.get('/hello', (c) => {
  return c.text('Hello, world!')
})

Parameter Path

Anda dapat mendefinisikan rute dengan parameter path menggunakan sintaks :paramName. Parameter ini dapat diakses melalui c.req.param('paramName').

// Contoh: /users/123
app.get('/users/:id', (c) => {
  const userId = c.req.param('id')
  return c.text(`User ID: ${userId}`)
})

Parameter Query

Parameter query dari URL (misalnya, /search?q=hono) dapat diakses menggunakan c.req.query('queryName').

// Contoh: /search?category=frameworks&limit=10
app.get('/search', (c) => {
  const category = c.req.query('category')
  const limit = c.req.query('limit')
  return c.text(`Mencari di kategori: ${category}, Batas: ${limit}`)
})

Anda juga bisa mendapatkan semua parameter query sebagai objek dengan c.req.query().

Menangani Metode HTTP yang Berbeda

Hono memudahkan penanganan berbagai metode HTTP untuk path yang sama:

// src/index.ts
import { Hono } from 'hono'

const app = new Hono()

// GET daftar postingan
app.get('/posts', (c) => {
  // Dalam aplikasi nyata, Anda akan mengambil ini dari database
  const posts = [
    { id: '1', title: 'Memulai dengan Hono' },
    { id: '2', title: 'Teknik Hono Tingkat Lanjut' },
  ];
  return c.json(posts); // Mengembalikan respons JSON
})

// GET satu postingan berdasarkan ID
app.get('/posts/:id', (c) => {
  const id = c.req.param('id')
  // Ambil postingan berdasarkan ID dari database
  const post = { id: id, title: `Postingan ${id}`, content: 'Ini adalah kontennya...' };
  if (!post) {
    return c.notFound() // Helper bawaan untuk 404
  }
  return c.json(post)
})

// MEMBUAT postingan baru
app.post('/posts', async (c) => {
  const body = await c.req.json() // Parse body JSON
  // Dalam aplikasi nyata, Anda akan menyimpan ini ke database
  console.log('Membuat postingan:', body)
  return c.json({ message: 'Postingan berhasil dibuat!', data: body }, 201) // Merespons dengan 201 Created
})

// MEMPERBARUI postingan yang sudah ada
app.put('/posts/:id', async (c) => {
  const id = c.req.param('id')
  const body = await c.req.json()
  // Perbarui postingan di database
  console.log(`Memperbarui postingan ${id}:`, body)
  return c.json({ message: `Postingan ${id} berhasil diperbarui!`, data: body })
})

// MENGHAPUS postingan
app.delete('/posts/:id', (c) => {
  const id = c.req.param('id')
  // Hapus postingan dari database
  console.log(`Menghapus postingan ${id}`)
  return c.json({ message: `Postingan ${id} berhasil dihapus!` })
})


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

Objek Request (c.req)

Objek Context (c) menyediakan akses ke detail permintaan melalui c.req. Properti dan metode utama meliputi:

  • c.req.url: String URL lengkap.
  • c.req.method: Metode HTTP (misalnya, 'GET', 'POST').
  • c.req.headers: Objek Headers. Akses header seperti c.req.header('Content-Type').
  • c.req.param('name'): Mendapatkan parameter path.
  • c.req.query('name'): Mendapatkan parameter query.
  • c.req.queries('name'): Mendapatkan semua nilai untuk parameter query berulang sebagai array.
  • c.req.json(): Mem-parse body permintaan sebagai JSON. (Mengembalikan Promise)
  • c.req.text(): Membaca body permintaan sebagai teks biasa. (Mengembalikan Promise)
  • c.req.arrayBuffer(): Membaca body permintaan sebagai ArrayBuffer. (Mengembalikan Promise)
  • c.req.formData(): Mem-parse body permintaan sebagai FormData. (Mengembalikan Promise)
  • c.req.valid('type'): Mengakses data yang divalidasi (digunakan dengan validator, akan dibahas nanti).

Objek Response (c) dan Helper

Objek Context (c) juga menyediakan helper yang nyaman untuk membuat objek Response:

  • c.text(text, status?, headers?): Mengembalikan respons teks biasa.
  • c.json(object, status?, headers?): Mengembalikan respons JSON. Content-Type secara otomatis diatur ke application/json.
  • c.html(html, status?, headers?): Mengembalikan respons HTML.
  • c.redirect(location, status?): Mengembalikan respons redirect (status default 302).
  • c.notFound(): Mengembalikan respons 404 Not Found.
  • c.newResponse(body, status?, headers?): Membuat objek Response baru. body bisa berupa null, ReadableStream, ArrayBuffer, FormData, URLSearchParams, atau string.
  • c.header(name, value): Mengatur header respons.

Contoh: Mengatur Header Kustom

app.get('/custom-header', (c) => {
  c.header('X-Powered-By', 'HonoJS-Flame')
  c.header('Cache-Control', 'no-cache')
  return c.text('Periksa header responsnya!')
})

4. Bekerja dengan Middleware di Hono.js

Fungsi middleware adalah landasan Hono (dan banyak framework web). Middleware adalah fungsi yang dapat memproses permintaan sebelum mencapai handler rute utama, atau memproses respons setelah handler berjalan. Middleware sangat bagus untuk tugas-tugas seperti logging, otentikasi, validasi data, kompresi, CORS, dan lainnya.

Tanda tangan dasar fungsi middleware adalah async (c, next) => { ... }.

  • c: Objek Context.
  • next: Fungsi untuk dipanggil guna meneruskan kontrol ke middleware berikutnya dalam rantai, atau ke handler rute akhir. Anda harus await next() jika Anda ingin middleware atau handler berikutnya dieksekusi.

Menggunakan Middleware Bawaan

Hono dilengkapi dengan serangkaian middleware bawaan yang kaya. Anda dapat mengimpornya dari hono/middleware-name (misalnya, hono/logger, hono/cors).

Untuk menerapkan middleware ke semua rute, gunakan app.use(middlewareFunction).
Untuk menerapkan middleware ke rute tertentu, berikan pola path sebagai argumen pertama: app.use('/admin/*', authMiddleware).

Contoh: Middleware Logger dan ETag

// src/index.ts
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { etag } from 'hono/etag'
import { prettyJSON } from 'hono/pretty-json' // Untuk respons JSON yang diformat dengan baik

const app = new Hono()

// Terapkan middleware ke semua rute
app.use(logger()) // Mencatat info permintaan dan respons ke konsol
app.use(etag())   // Menambahkan header ETag untuk caching
app.use(prettyJSON()) // Memformat respons JSON dengan indentasi

app.get('/', (c) => {
  return c.text('Halo dengan Logger dan ETag!')
})

app.get('/data', (c) => {
  return c.json({ message: 'Ini adalah beberapa data.', timestamp: Date.now() })
})

export default app

Saat Anda menjalankan ini dan mengakses / atau /data, Anda akan melihat log di konsol Anda, dan respons akan menyertakan header ETag. Respons JSON dari /data akan diformat dengan baik.

Middleware Bawaan Lain yang Berguna:

  • cors: Menangani Cross-Origin Resource Sharing.
  • basicAuth: Mengimplementasikan Basic Authentication.
  • jwt: Otentikasi JWT (JSON Web Token).
  • compress: Mengompresi body respons.
  • cache: Mengimplementasikan caching menggunakan Cache API.
  • secureHeaders: Menambahkan berbagai header HTTP terkait keamanan.
  • bodyLimit: Membatasi ukuran body permintaan.

Anda dapat menemukan daftar lengkap dan dokumentasi di dokumen Hono di bawah "Middleware".

Membuat Middleware Kustom

Anda dapat dengan mudah menulis middleware Anda sendiri.

Contoh 1: Timer Permintaan Sederhana

// src/index.ts
import { Hono } from 'hono'
import { logger } from 'hono/logger'

const app = new Hono()

app.use(logger())

// Middleware kustom untuk mengukur waktu pemrosesan permintaan
app.use(async (c, next) => {
  const start = Date.now()
  console.log(`Permintaan diterima pada: ${new Date(start).toISOString()}`)
  await next() // Panggil middleware atau handler rute berikutnya
  const ms = Date.now() - start
  c.header('X-Response-Time', `${ms}ms`) // Tambahkan header kustom ke respons
  console.log(`Permintaan diproses dalam ${ms}ms`)
})

app.get('/', (c) => {
  return c.text('Halo dari Hono dengan middleware timing kustom!')
})

app.get('/slow', async (c) => {
  // Simulasikan operasi lambat
  await new Promise(resolve => setTimeout(resolve, 1500))
  return c.text('Ini adalah respons yang lambat.')
})

export default app

Akses / dan /slow untuk melihat log timing dan header X-Response-Time.

Contoh 2: Middleware Otentikasi Kunci API Sederhana

Ini adalah contoh yang sangat dasar untuk demonstrasi. Dalam aplikasi nyata, gunakan metode otentikasi yang lebih kuat seperti JWT atau OAuth, dan simpan kunci API dengan aman.

// src/index.ts
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { HTTPException } from 'hono/http-exception' // Untuk melempar kesalahan HTTP standar

const app = new Hono()

app.use(logger())

const API_KEY = "supersecretapikey"; // Dalam aplikasi nyata, simpan ini dengan aman (misalnya, variabel env)

// Middleware Otentikasi Kunci API Kustom
const apiKeyAuth = async (c, next) => {
  const apiKeyHeader = c.req.header('X-API-KEY')
  if (apiKeyHeader && apiKeyHeader === API_KEY) {
    await next()
  } else {
    // Menggunakan HTTPException untuk mengembalikan respons kesalahan standar
    throw new HTTPException(401, { message: 'Tidak Sah: Kunci API Tidak Valid' })
  }
}

// Terapkan middleware ini ke grup rute tertentu
app.use('/api/v1/*', apiKeyAuth)

app.get('/api/v1/me', (c) => {
  return c.json({ user: 'Pengguna Terotentikasi', email: 'user@example.com' })
})

app.get('/public/info', (c) => {
  return c.text('Ini adalah informasi publik, tidak perlu kunci API.')
})

// Handler kesalahan untuk HTTPException
app.onError((err, c) => {
  if (err instanceof HTTPException) {
    return err.getResponse()
  }
  // Untuk kesalahan lain
  console.error('Kesalahan tak tertangani:', err)
  return c.text('Kesalahan Server Internal', 500)
})


export default app

Untuk menguji ini:

  • curl http://localhost:3000/api/v1/me (seharusnya mengembalikan 401 Unauthorized)
  • curl -H "X-API-KEY: supersecretapikey" http://localhost:3000/api/v1/me (seharusnya mengembalikan data pengguna)
  • curl http://localhost:3000/public/info (seharusnya mengembalikan info publik)

Menggunakan Kembali Middleware Kustom dengan createMiddleware

Untuk middleware yang lebih kompleks atau dapat digunakan kembali, Anda dapat mendefinisikannya secara terpisah menggunakan createMiddleware dari hono/factory. Ini juga membantu dengan inferensi tipe TypeScript.

// src/middlewares/timing.ts
import { createMiddleware } from 'hono/factory'

export const timingMiddleware = createMiddleware(async (c, next) => {
  const start = Date.now()
  await next()
  const ms = Date.now() - start
  c.res.headers.set('X-Response-Time', `${ms}ms`) // Catatan: c.res.headers.set
  console.log(` -> Diproses dalam ${ms}ms`)
})

// src/middlewares/auth.ts
import { createMiddleware } from 'hono/factory'
import { HTTPException } from 'hono/http-exception'

const VALID_API_KEY = "anothersecretkey";

// Tipe untuk variabel lingkungan jika middleware Anda membutuhkannya
type Env = {
  Variables: {
    user?: { id: string } // Contoh: mengatur data pengguna setelah otentikasi
  }
  // Bindings: { MY_KV_NAMESPACE: KVNamespace } // Contoh untuk Cloudflare Workers
}

export const secureApiKeyAuth = createMiddleware<Env>(async (c, next) => {
  const apiKey = c.req.header('Authorization')?.replace('Bearer ', '')
  if (apiKey === VALID_API_KEY) {
    // Secara opsional, Anda dapat mengatur variabel dalam konteks untuk handler downstream
    c.set('user', { id: 'user123' })
    await next()
  } else {
    throw new HTTPException(401, { message: 'Akses Ditolak: Kunci API Aman Diperlukan.'})
  }
})


// src/index.ts
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { timingMiddleware } from './middlewares/timing' // Asumsikan berada di folder middlewares
import { secureApiKeyAuth } from './middlewares/auth'

const app = new Hono()

app.use(logger())
app.use(timingMiddleware) // Terapkan ke semua rute

app.get('/', (c) => {
  return c.text('Halo dari Hono dengan middleware yang difaktorkan!')
})

app.use('/secure/data/*', secureApiKeyAuth) // Terapkan hanya ke /secure/data/*
app.get('/secure/data/profile', (c) => {
  // const user = c.get('user') // Akses variabel yang diatur oleh middleware
  return c.json({ profileData: 'Informasi profil sensitif', /*user: user*/ })
})

app.get('/public/data', (c) => {
  return c.text('Ini adalah data publik, tidak perlu kunci.')
})

// Handler kesalahan umum
app.onError((err, c) => {
  if (err instanceof HTTPException) {
    return err.getResponse();
  }
  console.error('Kesalahan:', err.message);
  return c.json({ error: 'Kesalahan Server Internal', message: err.message }, 500);
});

export default app

Struktur ini membuat middleware Anda lebih modular dan lebih mudah diuji secara independen.

5. Menguji Aplikasi Hono.js Anda

Hono dirancang agar mudah diuji. Bun hadir dengan test runner-nya sendiri, bun:test, yang bekerja dengan baik dengan Hono. Anda juga dapat menggunakan test runner lain seperti Vitest.

Menggunakan bun:test (Dasar)

Dokumentasi bun.md menyediakan contoh dasar pengujian dengan bun:test:

Buat file test, misalnya, src/index.test.ts:

// src/index.test.ts
import { describe, expect, it } from 'bun:test'
import app from '.' // Mengimpor aplikasi Anda dari src/index.ts

describe('Tes Aplikasi Hono', () => {
  it('Seharusnya mengembalikan 200 OK untuk GET /', async () => {
    const req = new Request('http://localhost/') // URL dasar tidak terlalu penting di sini
    const res = await app.fetch(req)
    expect(res.status).toBe(200)
    expect(await res.text()).toBe('Hello Hono!') // Atau apa pun yang dikembalikan rute root Anda
  })

  it('Seharusnya mengembalikan JSON untuk GET /posts', async () => {
    const req = new Request('http://localhost/posts')
    const res = await app.fetch(req)
    expect(res.status).toBe(200)
    const json = await res.json()
    expect(json).toBeArray() // Asumsikan /posts mengembalikan array
    // Tambahkan assertion yang lebih spesifik tentang konten JSON jika diperlukan
  })

  it('Seharusnya membuat postingan untuk POST /posts', async () => {
    const postData = { title: 'Postingan Uji', content: 'Ini adalah uji.' };
    const req = new Request('http://localhost/posts', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(postData),
    });
    const res = await app.fetch(req);
    expect(res.status).toBe(201); // Harapkan 201 Created
    const jsonResponse = await res.json();
    expect(jsonResponse.message).toBe('Postingan berhasil dibuat!');
    expect(jsonResponse.data.title).toBe(postData.title);
  });
})

Untuk menjalankan tes Anda:

bun test

Atau, jika Anda ingin menjalankan file tertentu:

bun test src/index.test.ts

Menggunakan Helper app.request()

Hono menyediakan metode app.request() yang nyaman yang menyederhanakan pengujian dengan memungkinkan Anda langsung meneruskan path dan opsi, alih-alih membuat objek Request lengkap setiap kali. Ini ditunjukkan dalam docs/guides/testing.md.

// src/index.test.ts
import { describe, expect, it } from 'bun:test' // Atau impor dari 'vitest'
import app from '.' // Instance aplikasi Hono Anda

describe('Aplikasi Hono dengan app.request()', () => {
  it('GET / seharusnya mengembalikan "Hello Hono!"', async () => {
    const res = await app.request('/')
    expect(res.status).toBe(200)
    expect(await res.text()).toBe('Hello Hono!') // Sesuaikan dengan respons root Anda yang sebenarnya
  })

  it('GET /posts/:id seharusnya mengembalikan postingan tertentu', async () => {
    // Asumsikan aplikasi Anda memiliki rute seperti app.get('/posts/:id', ...)
    // dan untuk tes ini, mungkin mengembalikan { id: '123', title: 'Postingan Uji 123' }
    const res = await app.request('/posts/123')
    expect(res.status).toBe(200)
    const data = await res.json()
    expect(data.id).toBe('123')
    // expect(data.title).toBe('Postingan 123') // Atau berdasarkan logika aplikasi Anda
  })

  it('POST /posts seharusnya membuat postingan baru', async () => {
    const newPost = { title: 'Postingan Baru Saya', content: 'Konten luar biasa di sini.' }
    const res = await app.request('/posts', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(newPost),
    })
    expect(res.status).toBe(201) // Asumsikan POST /posts Anda mengembalikan 201
    const responseData = await res.json()
    expect(responseData.message).toBe('Postingan berhasil dibuat!')
    expect(responseData.data.title).toBe(newPost.title)
  })

  it('GET /api/v1/me tanpa kunci API seharusnya 401', async () => {
    // Asumsikan middleware kunci API dari contoh sebelumnya aktif di rute ini
    const res = await app.request('/api/v1/me')
    expect(res.status).toBe(401)
  })

  it('GET /api/v1/me dengan kunci API yang benar seharusnya 200', async () => {
    const res = await app.request('/api/v1/me', {
      headers: {
        'X-API-KEY': 'supersecretapikey' // Gunakan kunci dari middleware Anda
      }
    })
    expect(res.status).toBe(200)
    const data = await res.json();
    expect(data.user).toBe('Pengguna Terotentikasi')
  })
})

Menggunakan Helper testClient() untuk Pengujian yang Aman Tipe

Untuk keamanan tipe yang lebih baik, terutama jika Anda menggunakan kemampuan RPC Hono atau memiliki skema rute yang terdefinisi dengan baik, Hono menyediakan helper testClient (dari hono/testing). Klien ini ditikkan berdasarkan rute aplikasi Hono Anda, memberi Anda autocompletion dan pemeriksaan tipe dalam tes Anda.

Catatan Penting untuk Inferensi Tipe testClient:
Agar testClient dapat menginferensi tipe dengan benar, Anda harus mendefinisikan rute Anda menggunakan metode berantai langsung pada instance Hono (misalnya, const app = new Hono().get(...).post(...)) atau mengekspor tipe rute jika menggunakan RPC. Jika Anda mendefinisikan rute secara terpisah (misalnya, const app = new Hono(); app.get(...)), inferensi tipe untuk testClient mungkin terbatas.

// src/app-for-test-client.ts
// Untuk mendemonstrasikan testClient, mari kita definisikan aplikasi dengan rute berantai
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator' // Contoh untuk parameter query bertipe
import { z } from 'zod'

const appWithChainedRoutes = new Hono()
  .get('/search',
    zValidator('query', z.object({ q: z.string(), limit: z.coerce.number().optional() })),
    (c) => {
      const { q, limit } = c.req.valid('query')
      return c.json({ query: q, limit: limit || 10, results: [`hasil untuk ${q} 1`, `hasil untuk ${q} 2`] })
    }
  )
  .post('/submit',
    zValidator('json', z.object({ name: z.string(), email: z.string().email() })),
    async (c) => {
      const data = c.req.valid('json')
      return c.json({ message: `Data diterima untuk ${data.name}`, data }, 201)
    }
  );

export default appWithChainedRoutes;


// src/app-for-test-client.test.ts
import { describe, expect, it } from 'bun:test'
import { testClient } from 'hono/testing'
import appWithChainedRoutes from './app-for-test-client' // Impor aplikasi

describe('Aplikasi Hono dengan testClient', () => {
  const client = testClient(appWithChainedRoutes)

  it('GET /search seharusnya mengembalikan hasil bertipe', async () => {
    const res = await client.search.$get({
      query: { q: 'hono keren' }
    })
    expect(res.status).toBe(200)
    const data = await res.json()
    expect(data.query).toBe('hono keren')
    expect(data.results.length).toBeGreaterThan(0)
  })

  it('GET /search dengan limit seharusnya menghormatinya', async () => {
    const res = await client.search.$get({
      query: { q: 'hono dengan limit', limit: '5' } // Parameter query awalnya adalah string
    })
    expect(res.status).toBe(200)
    const data = await res.json()
    expect(data.limit).toBe(5) // Validator Zod mengubahnya menjadi angka
  })

  it('POST /submit seharusnya menerima data yang valid', async () => {
    const payload = { name: 'Pengguna Uji', email: 'test@example.com' }
    // Untuk POST, PUT, dll. dengan body JSON, gunakan client.path.$post({ json: payload })
    const res = await client.submit.$post({
      json: payload
    })
    expect(res.status).toBe(201)
    const data = await res.json()
    expect(data.message).toBe(`Data diterima untuk ${payload.name}`)
    expect(data.data.email).toBe(payload.email)
  });

  it('POST /submit dengan header', async () => {
    const payload = { name: 'Pengguna Uji Header', email: 'testheaders@example.com' }
    const res = await client.submit.$post({
      json: payload
    }, {
      headers: {
        'X-Custom-Test-Header': 'Testing123'
      }
    })
    expect(res.status).toBe(201)
    // Anda biasanya akan memiliki rute/middleware yang membaca header ini untuk memverifikasi
  });
})

Untuk menjalankan tes ini, asumsikan Anda telah menginstal @hono/zod-validator dan zod (bun add @hono/zod-validator zod):

bun test src/app-for-test-client.test.ts

testClient ini menyediakan pengalaman developer yang jauh lebih baik untuk pengujian, terutama untuk API dengan skema yang terdefinisi.

Kesimpulan

Hono menawarkan pendekatan baru untuk pengembangan web dengan kombinasi kecepatan, desain ringan, dan fitur ramah developer. Panduan ini telah mencakup dasar-dasar untuk memulai, tetapi masih banyak lagi yang bisa dieksplorasi:

  • Teknik routing tingkat lanjut
  • Pola middleware yang lebih kompleks
  • Server-side rendering dengan JSX
  • Integrasi dengan database
  • API gaya RPC dengan keamanan tipe menggunakan Hono Client
  • Deployment ke berbagai platform

Saat Anda melanjutkan perjalanan Anda dengan Hono, rujuk ke dokumentasi resmi dan repositori contoh untuk informasi dan inspirasi yang lebih mendalam.

Lanskap pengembangan web terus berkembang, dan Hono mewakili pendekatan modern yang merangkul Standar Web, memprioritaskan kinerja, dan bekerja di seluruh ekosistem runtime JavaScript yang berkembang. Baik Anda membangun API sederhana atau aplikasi kompleks, Hono menyediakan alat yang Anda butuhkan tanpa overhead yang tidak perlu.

Mulailah dari yang kecil, bereksperimen, dan saksikan aplikasi Anda berkembang dengan Hono – framework web yang ringan, sangat cepat, yang sesuai dengan namanya yang berapi-api. 🔥

💡
Ingin alat Uji API yang hebat yang menghasilkan Dokumentasi API yang indah?

Ingin platform All-in-One yang terintegrasi agar Tim Developer Anda dapat bekerja sama dengan produktivitas maksimum?

Apidog memenuhi semua permintaan Anda, dan menggantikan Postman dengan harga yang jauh lebih terjangkau!
button