Hono
إطار عمل ويب فائق السرعة للحافة، يدعم Cloudflare Workers وDeno وBun وVercel وAWS Lambda وNode.js بدون أي تبعيات.
التثبيت
Section titled “التثبيت”إنشاء مشروع جديد
Section titled “إنشاء مشروع جديد”| أمر | وصف |
|---|---|
npm create hono@latest my-app | إنشاء مشروع Hono جديد باستخدام npm |
yarn create hono my-app | الإنشاء باستخدام Yarn |
pnpm create hono my-app | الإنشاء باستخدام pnpm |
bun create hono my-app | الإنشاء باستخدام Bun |
deno init --lib hono | الإنشاء باستخدام Deno |
الإضافة إلى مشروع موجود
Section titled “الإضافة إلى مشروع موجود”| أمر | وصف |
|---|---|
npm install hono | تثبيت Hono في مشروع موجود |
yarn add hono | التثبيت باستخدام Yarn |
pnpm add hono | التثبيت باستخدام pnpm |
bun add hono | التثبيت باستخدام Bun |
قوالب البداية
Section titled “قوالب البداية”# Create project with specific runtime template
npm create hono@latest my-app -- --template cloudflare-workers
npm create hono@latest my-app -- --template bun
npm create hono@latest my-app -- --template deno
npm create hono@latest my-app -- --template nodejs
npm create hono@latest my-app -- --template vercel
npm create hono@latest my-app -- --template aws-lambda
npm create hono@latest my-app -- --template cloudflare-pages
npm create hono@latest my-app -- --template fastly
التوجيه الأساسي
Section titled “التوجيه الأساسي”طرق HTTP
Section titled “طرق HTTP”| أمر | وصف |
|---|---|
app.get('/path', handler) | معالجة طلبات GET |
app.post('/path', handler) | معالجة طلبات POST |
app.put('/path', handler) | معالجة طلبات PUT |
app.delete('/path', handler) | معالجة طلبات DELETE |
app.patch('/path', handler) | معالجة طلبات PATCH |
app.options('/path', handler) | معالجة طلبات OPTIONS |
app.all('/path', handler) | معالجة جميع طرق HTTP |
app.on('PURGE', '/path', handler) | معالجة طرق مخصصة |
مثال Hello World
Section titled “مثال Hello World”import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.text('Hello Hono!')
})
app.get('/json', (c) => {
return c.json({ message: 'Hello', status: 'ok' })
})
app.get('/html', (c) => {
return c.html('<h1>Hello Hono!</h1>')
})
export default app
معاملات المسار
Section titled “معاملات المسار”// Path parameters
app.get('/users/:id', (c) => {
const id = c.req.param('id')
return c.json({ id })
})
// Multiple parameters
app.get('/posts/:postId/comments/:commentId', (c) => {
const { postId, commentId } = c.req.param()
return c.json({ postId, commentId })
})
// Optional parameter
app.get('/api/:version?/users', (c) => {
const version = c.req.param('version') || 'v1'
return c.json({ version })
})
// Wildcard
app.get('/files/*', (c) => {
const path = c.req.path
return c.text(`File path: ${path}`)
})
// Regex-like patterns
app.get('/user/:id{[0-9]+}', (c) => {
const id = c.req.param('id')
return c.json({ id: Number(id) })
})
معالجة الطلبات
Section titled “معالجة الطلبات”معاملات الاستعلام
Section titled “معاملات الاستعلام”| أمر | وصف |
|---|---|
c.req.query('key') | الحصول على معامل استعلام واحد |
c.req.query() | الحصول على جميع معاملات الاستعلام |
c.req.queries('tags') | الحصول على مصفوفة قيم لمفتاح معين |
جسم الطلب
Section titled “جسم الطلب”| أمر | وصف |
|---|---|
c.req.json() | تحليل جسم JSON |
c.req.text() | الحصول على الجسم كنص |
c.req.formData() | تحليل بيانات النموذج |
c.req.blob() | الحصول على الجسم كـ Blob |
c.req.arrayBuffer() | الحصول على الجسم كـ ArrayBuffer |
c.req.parseBody() | تحليل تلقائي للجسم حسب نوع المحتوى |
الترويسات والبيانات الوصفية
Section titled “الترويسات والبيانات الوصفية”| أمر | وصف |
|---|---|
c.req.header('Content-Type') | الحصول على ترويسة الطلب |
c.req.header() | الحصول على جميع الترويسات |
c.req.method | الحصول على طريقة HTTP |
c.req.url | الحصول على عنوان URL الكامل للطلب |
c.req.path | الحصول على مسار الطلب |
c.req.raw | الحصول على كائن Request الخام |
c.req.valid('json') | الحصول على البيانات المُتحقق منها |
مثال على الطلب
Section titled “مثال على الطلب”app.post('/users', async (c) => {
const body = await c.req.json()
const page = c.req.query('page') || '1'
const auth = c.req.header('Authorization')
return c.json({
user: body,
page: Number(page),
authenticated: !!auth
}, 201)
})
مساعدات الاستجابة
Section titled “مساعدات الاستجابة”أنواع الاستجابة
Section titled “أنواع الاستجابة”| أمر | وصف |
|---|---|
c.text('Hello') | استجابة نص عادي |
c.json({ key: 'value' }) | استجابة JSON |
c.html('<h1>Hi</h1>') | استجابة HTML |
c.redirect('/new-url') | إعادة توجيه 302 |
c.redirect('/new-url', 301) | إعادة توجيه دائمة 301 |
c.notFound() | استجابة 404 |
c.body(data) | استجابة جسم خام |
c.newResponse(body, status, headers) | استجابة مخصصة كاملة |
ترويسات الاستجابة والبث
Section titled “ترويسات الاستجابة والبث”// Set headers
app.get('/api/data', (c) => {
c.header('X-Custom-Header', 'value')
c.header('Cache-Control', 'max-age=3600')
return c.json({ data: 'example' })
})
// Set status code
app.post('/items', async (c) => {
const item = await c.req.json()
return c.json(item, 201)
})
// Stream response
app.get('/stream', (c) => {
return c.streamText(async (stream) => {
await stream.write('Hello ')
await stream.sleep(1000)
await stream.write('World!')
})
})
البرمجيات الوسيطة
Section titled “البرمجيات الوسيطة”البرمجيات الوسيطة المدمجة
Section titled “البرمجيات الوسيطة المدمجة”| أمر | وصف |
|---|---|
import { cors } from 'hono/cors' | برمجية وسيطة لـ CORS |
import { logger } from 'hono/logger' | تسجيل الطلبات |
import { prettyJSON } from 'hono/pretty-json' | تنسيق استجابات JSON |
import { basicAuth } from 'hono/basic-auth' | المصادقة الأساسية |
import { bearerAuth } from 'hono/bearer-auth' | مصادقة رمز Bearer |
import { jwt } from 'hono/jwt' | مصادقة JWT |
import { compress } from 'hono/compress' | ضغط Gzip/Brotli |
import { etag } from 'hono/etag' | تخزين ETag المؤقت |
import { secureHeaders } from 'hono/secure-headers' | ترويسات الأمان |
import { csrf } from 'hono/csrf' | حماية CSRF |
import { timing } from 'hono/timing' | ترويسة Server-Timing |
import { cache } from 'hono/cache' | التحكم بالتخزين المؤقت |
import { bodyLimit } from 'hono/body-limit' | تحديد حجم جسم الطلب |
استخدام البرمجيات الوسيطة
Section titled “استخدام البرمجيات الوسيطة”import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'
import { secureHeaders } from 'hono/secure-headers'
import { bearerAuth } from 'hono/bearer-auth'
const app = new Hono()
// Global middleware
app.use('*', logger())
app.use('*', secureHeaders())
app.use('*', cors({
origin: ['https://example.com'],
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
allowHeaders: ['Content-Type', 'Authorization'],
maxAge: 86400,
}))
// Route-specific middleware
app.use('/api/*', bearerAuth({ token: 'my-secret-token' }))
// Custom middleware
app.use('*', async (c, next) => {
const start = Date.now()
await next()
const duration = Date.now() - start
c.header('X-Response-Time', `${duration}ms`)
})
مصادقة JWT
Section titled “مصادقة JWT”import { jwt, sign } from 'hono/jwt'
const app = new Hono()
const SECRET = 'my-secret-key'
app.use('/api/*', jwt({ secret: SECRET }))
app.post('/login', async (c) => {
const { email, password } = await c.req.json()
const token = await sign(
{ email, exp: Math.floor(Date.now() / 1000) + 3600 },
SECRET
)
return c.json({ token })
})
app.get('/api/profile', (c) => {
const payload = c.get('jwtPayload')
return c.json({ email: payload.email })
})
التحقق من الصحة
Section titled “التحقق من الصحة”مُتحقق Zod
Section titled “مُتحقق Zod”import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const userSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
age: z.number().int().positive().optional(),
})
app.post(
'/users',
zValidator('json', userSchema),
(c) => {
const user = c.req.valid('json')
return c.json(user, 201)
}
)
// Validate query parameters
const querySchema = z.object({
page: z.string().optional().default('1'),
limit: z.string().optional().default('10'),
})
app.get(
'/users',
zValidator('query', querySchema),
(c) => {
const { page, limit } = c.req.valid('query')
return c.json({ page, limit })
}
)
مجموعات التوجيه
Section titled “مجموعات التوجيه”const app = new Hono()
// Group routes with basePath
const api = new Hono().basePath('/api')
api.get('/users', (c) => c.json({ users: [] }))
api.post('/users', (c) => c.json({ created: true }))
app.route('/', api)
// Versioned APIs
const v1 = new Hono()
v1.get('/health', (c) => c.json({ status: 'ok' }))
const v2 = new Hono()
v2.get('/health', (c) => c.json({ status: 'ok', version: 2 }))
app.route('/api/v1', v1)
app.route('/api/v2', v2)
معالجة الأخطاء
Section titled “معالجة الأخطاء”import { HTTPException } from 'hono/http-exception'
// Custom 404
app.notFound((c) => {
return c.json({ error: 'Not Found' }, 404)
})
// Global error handler
app.onError((err, c) => {
if (err instanceof HTTPException) {
return err.getResponse()
}
console.error(err)
return c.json({ error: 'Internal Server Error' }, 500)
})
// Throw HTTP exceptions
app.get('/admin', (c) => {
if (!c.req.header('Authorization')) {
throw new HTTPException(401, { message: 'Unauthorized' })
}
return c.json({ admin: true })
})
الإعداد حسب بيئة التشغيل
Section titled “الإعداد حسب بيئة التشغيل”Cloudflare Workers
Section titled “Cloudflare Workers”import { Hono } from 'hono'
type Bindings = {
MY_KV: KVNamespace
MY_DB: D1Database
}
const app = new Hono<{ Bindings: Bindings }>()
app.get('/kv/:key', async (c) => {
const value = await c.env.MY_KV.get(c.req.param('key'))
return c.json({ value })
})
export default app
Node.js
Section titled “Node.js”import { Hono } from 'hono'
import { serve } from '@hono/node-server'
const app = new Hono()
app.get('/', (c) => c.text('Hello Node.js!'))
serve({ fetch: app.fetch, port: 3000 })
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Bun!'))
export default { port: 3000, fetch: app.fetch }
import { Hono } from 'npm:hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Deno!'))
Deno.serve(app.fetch)
RPC والعميل
Section titled “RPC والعميل”عميل RPC آمن النوع
Section titled “عميل RPC آمن النوع”// server.ts
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const app = new Hono()
.get('/api/users', (c) => {
return c.json({ users: [{ id: 1, name: 'Alice' }] })
})
.post(
'/api/users',
zValidator('json', z.object({ name: z.string() })),
(c) => {
const { name } = c.req.valid('json')
return c.json({ id: 2, name }, 201)
}
)
export type AppType = typeof app
export default app
// client.ts — fully typed
import { hc } from 'hono/client'
import type { AppType } from './server'
const client = hc<AppType>('http://localhost:3000')
// Fully typed — autocomplete for routes + responses
const res = await client.api.users.$get()
const data = await res.json()
// data: { users: { id: number, name: string }[] }
الاختبار
Section titled “الاختبار”import { testClient } from 'hono/testing'
const app = new Hono()
.get('/hello', (c) => c.json({ message: 'Hello!' }))
// Using testClient (type-safe)
const client = testClient(app)
const res = await client.hello.$get()
const body = await res.json()
// body.message === 'Hello!'
// Using app.request() directly
const res2 = await app.request('/hello')
// res2.status === 200
أفضل الممارسات
Section titled “أفضل الممارسات”-
استخدم TypeScript generics لربط البيئة — عرّف
Hono<{ Bindings: MyBindings }>للحصول على أمان النوع لمتغيرات البيئة وفضاءات أسماء KV وقواعد بيانات D1. -
تحقق من جميع المدخلات باستخدام Zod — استخدم
@hono/zod-validatorللتحقق من جسم الطلب والاستعلام والمعاملات. هذا يوفر أمان وقت التشغيل وأنواع TypeScript في خطوة واحدة. -
استخدم عميل RPC للواجهة الأمامية والخلفية — صدّر
AppTypeمن خادمك واستخدمhc<AppType>()في العميل لأمان نوع شامل بدون توليد كود. -
طبّق البرمجيات الوسيطة بأنماط المسارات — استخدم
app.use('/api/*', middleware)لتحديد نطاق البرمجيات الوسيطة لمسارات محددة بدلاً من تطبيق كل شيء عالمياً. -
جمّع المسارات باستخدام
new Hono().basePath()— نظّم نقاط النهاية المرتبطة في نسخ Hono منفصلة وركّبها بـapp.route()لفصل نظيف. -
عالج الأخطاء عالمياً — استخدم
app.onError()وapp.notFound()لضمان أن كل خطأ يُرجع استجابة JSON منظمة بدلاً من تتبع المكدس. -
استخدم
c.executionCtx.waitUntil()— للعمل في الخلفية على Cloudflare Workers (التحليلات، التسجيل)، استخدمwaitUntil()لتجنب حجب الاستجابة. -
اجعل المعالجات خفيفة — استخرج منطق الأعمال إلى دوال/وحدات منفصلة. معالجات المسارات يجب أن تحلل المدخلات وتستدعي المنطق وتُرجع الاستجابات.
-
اختبر باستخدام
testClient— عميل اختبار Hono المدمج آمن النوع ولا يحتاج خادماً يعمل، مما يجعل اختبارات الوحدة سريعة وموثوقة. -
انشر حيث يتواجد مستخدموك — يعمل Hono على كل بيئة تشغيل حافة رئيسية. اختر Cloudflare Workers للحافة العالمية، أو Bun للسرعة القصوى، أو Node.js لتوافق النظام البيئي.