spinny:~/writing $ less hono-framework-guide.md
12برسوں تک JavaScript ویب فریم ورک منتخب کرنا مطلب ٹریڈ آف قبول کرنا تھا: Express عالمگیر مگر سست اور Node سے بندھا، Fastify تیز مگر صرف Node کے لیے، Next.js مکمل مگر بھاری۔ جب ایج رن ٹائم — Cloudflare Workers، Deno Deploy، Bun، Vercel Edge — آئے، ان فریم ورکس کی حدود ظاہر ہوئیں۔34[Hono](https://hono.dev) (جاپانی میں "شعلہ" 🔥) جدید جواب ہے۔ 14KB سے کم کا فریم ورک، مکمل طور پر ویب اسٹینڈرڈز (`Request`، `Response`، `fetch`) پر بنا ہوا، ہر JavaScript رن ٹائم پر چلتا ہے۔ ایک ہی کوڈ Cloudflare Workers، Bun، Deno، Node.js، Vercel، Netlify اور AWS Lambda پر بغیر تبدیلی کے ڈپلائے ہوتا ہے۔56## Hono کیوں781. **پرفارمنس۔** `RegExpRouter` تمام روٹ پیٹرن کو ایک regex میں کمپائل کرتا ہے، روایتی روٹرز کے لینیئر لوپس سے بچتا ہے۔ بینچ مارکس 4 لاکھ ops/s سے زیادہ ہیں۔92. **پورٹیبلٹی۔** ویب اسٹینڈرڈز یعنی Node پر صفر انحصار۔ ایک ہی `app.fetch` Cloudflare Worker میں default export، `Bun.serve` کو پاس، Deno سرور پر ماؤنٹ یا `@hono/node-server` کے ساتھ اڈیپٹ ہوتا ہے۔103. **TypeScript فرسٹ DX۔** لٹرل ٹائپس کے طور پر اخذ شدہ پاتھ پیرامیٹرز، اینڈ ٹو اینڈ ٹائپ سیف RPC کلائنٹ۔1112```mermaid13graph LR14 Client[Client] -->|Request| App[app.fetch]15 App --> MW1[Middleware 1]16 MW1 --> MW2[Middleware 2]17 MW2 --> Router[RegExpRouter]18 Router --> Handler[Route Handler]19 Handler --> Context[c.json / c.text]20 Context -->|Response| Client21 App -.->|deploy| CF[Cloudflare Workers]22 App -.->|deploy| Bun[Bun]23 App -.->|deploy| Deno[Deno]24 App -.->|deploy| Node[Node.js]25 App -.->|deploy| Vercel[Vercel]26```2728## شروع کرنا2930```bash31npm create hono@latest my-api32cd my-api33npm install34npm run dev35```3637اسٹارٹر پوچھتا ہے کونسا ٹیمپلیٹ: `cloudflare-workers`، `bun`، `deno`، `nodejs`، `vercel`، `aws-lambda`، `nextjs` وغیرہ۔ تیز آزمائش کے لیے ایک فائل سے بھی شروع کر سکتے ہیں:3839```typescript40// src/index.ts41import { Hono } from 'hono'4243const app = new Hono()4445app.get('/', (c) => c.text('Hello Hono!'))4647export default app48```4950Cloudflare Workers پر یہ کافی ہے۔ Bun پر: `Bun.serve({ fetch: app.fetch, port: 3000 })`۔ Node پر: `@hono/node-server` سے `serve({ fetch: app.fetch })`۔5152## روٹنگ5354```typescript55import { Hono } from 'hono'5657const app = new Hono()5859app.get('/', (c) => c.text('Home'))60app.get('/posts/:id', (c) => {61 const id = c.req.param('id')62 return c.json({ id })63})64app.get('/posts/:id/comments/:commentId', (c) => {65 const { id, commentId } = c.req.param()66 return c.json({ id, commentId })67})68app.get('/files/*', (c) => c.text('Wildcard'))69app.post('/posts', async (c) => {70 const body = await c.req.json()71 return c.json({ created: body }, 201)72})73```7475### روٹس گروپ کرنا7677```typescript78// routes/posts.ts79import { Hono } from 'hono'8081const posts = new Hono()82posts.get('/', (c) => c.json({ posts: [] }))83posts.get('/:id', (c) => c.json({ id: c.req.param('id') }))84export default posts8586// src/index.ts87import { Hono } from 'hono'88import posts from './routes/posts'8990const app = new Hono()91app.route('/posts', posts)92```9394## Context آبجیکٹ9596```typescript97app.post('/echo', async (c) => {98 const userAgent = c.req.header('User-Agent')99 const page = c.req.query('page')100 const body = await c.req.json()101 const env = c.env102103 c.set('requestId', crypto.randomUUID())104 const id = c.get('requestId')105106 c.header('X-Request-Id', id)107 c.status(200)108 return c.json({ userAgent, page, body, id })109})110```111112## مڈل ویئر: اونیئن ماڈل113114```typescript115import { Hono } from 'hono'116import { logger } from 'hono/logger'117import { cors } from 'hono/cors'118import { secureHeaders } from 'hono/secure-headers'119120const app = new Hono()121122app.use('*', logger())123app.use('*', secureHeaders())124app.use('/api/*', cors({ origin: 'https://spinny.dev' }))125126app.use('*', async (c, next) => {127 const start = performance.now()128 await next()129 c.header('X-Response-Time', `${performance.now() - start}ms`)130})131```132133### بلٹ ان مڈل ویئر134135| مڈل ویئر | کام |136|-----------|---------|137| `logger` | میتھڈ، پاتھ، اسٹیٹس، دورانیہ کی منظم لاگ |138| `cors` | origin، میتھڈز، ہیڈرز کے مطابق قابلِ ترتیب CORS |139| `csrf` | origin پر مبنی CSRF تحفظ |140| `secureHeaders` | CSP، HSTS، X-Frame-Options سیٹ کرتا ہے |141| `bearerAuth` / `basicAuth` | فوری Bearer/Basic auth |142| `jwt` | `jose` سے JWT تصدیق/دستخط |143| `etag` | ETag پیدا کرتا ہے، 304 ہینڈل کرتا ہے |144| `cache` | Web Cache API کیشنگ |145| `compress` | جواب پر gzip/deflate |146| `bodyLimit` | حد سے اوپر باڈی مسترد |147| `timing` | پروفائلنگ کے لیے Server-Timing ہیڈر |148149### ٹائپ سیف کسٹم مڈل ویئر150151```typescript152import { createMiddleware } from 'hono/factory'153154type AuthVars = { userId: string; role: 'user' | 'admin' }155156export const requireAuth = createMiddleware<{ Variables: AuthVars }>(157 async (c, next) => {158 const token = c.req.header('Authorization')?.replace('Bearer ', '')159 if (!token) return c.json({ error: 'Unauthorized' }, 401)160161 const payload = await verifyJwt(token)162 c.set('userId', payload.sub)163 c.set('role', payload.role)164 await next()165 }166)167168app.get('/me', requireAuth, (c) => {169 const userId = c.var.userId170 return c.json({ userId })171})172```173174## Zod کے ساتھ ویلیڈیشن175176```typescript177import { Hono } from 'hono'178import { zValidator } from '@hono/zod-validator'179import { z } from 'zod'180181const createPost = z.object({182 title: z.string().min(1).max(200),183 body: z.string().min(1),184 tags: z.array(z.string()).default([]),185})186187app.post(188 '/posts',189 zValidator('json', createPost),190 (c) => {191 const data = c.req.valid('json')192 return c.json({ ok: true, post: data }, 201)193 }194)195```196197## RPC: اینڈ ٹو اینڈ ٹائپ سیف کلائنٹ198199```typescript200// server.ts201import { Hono } from 'hono'202import { zValidator } from '@hono/zod-validator'203import { z } from 'zod'204205const app = new Hono()206 .get('/posts/:id', (c) =>207 c.json({ id: c.req.param('id'), title: 'Hello' })208 )209 .post(210 '/posts',211 zValidator('json', z.object({ title: z.string(), body: z.string() })),212 (c) => c.json({ ok: true }, 201)213 )214215export type AppType = typeof app216export default app217```218219```typescript220// client.ts221import { hc } from 'hono/client'222import type { AppType } from './server'223224const client = hc<AppType>('https://api.spinny.dev')225226const res = await client.posts[':id'].$get({ param: { id: '42' } })227if (res.ok) {228 const data = await res.json()229 console.log(data.title)230}231232const created = await client.posts.$post({233 json: { title: 'سلام', body: 'Hono ایک شعلہ ہے' },234})235```236237### اسٹیٹس کوڈ تفریق238239```typescript240.get('/posts/:id', (c) => {241 const post = findPost(c.req.param('id'))242 if (!post) return c.json({ error: 'not found' }, 404)243 return c.json({ post }, 200)244})245```246247```typescript248const res = await client.posts[':id'].$get({ param: { id } })249if (res.status === 404) {250 const { error } = await res.json()251}252if (res.status === 200) {253 const { post } = await res.json()254}255```256257## روٹرز اور پرفارمنس258259| روٹر | طاقتیں | کب استعمال کریں |260|--------|-----------|-------------|261| `RegExpRouter` | اعلی ترین رفتار، کمپائلڈ regex | زیادہ تر APIs کے لیے ڈیفالٹ |262| `TrieRouter` | ہر پیٹرن سپورٹ | پیچیدہ پیٹرن جنہیں RegExp ہینڈل نہیں کرتا |263| `SmartRouter` | بہترین خود کار طریقے سے منتخب | تجویز کردہ ڈیفالٹ |264| `LinearRouter` | الٹرا فاسٹ رجسٹریشن | ون شاٹ ورکر، اہم کولڈ سٹارٹ |265| `PatternRouter` | کم سے کم بنڈل (<15KB) | انتہائی سائز پابندیاں |266267```typescript268import { Hono } from 'hono'269import { LinearRouter } from 'hono/router/linear-router'270271const app = new Hono({ router: new LinearRouter() })272```273274## ملٹی رن ٹائم ڈپلائے275276### Cloudflare Workers277278```typescript279import { Hono } from 'hono'280281type Bindings = { MY_KV: KVNamespace; DB: D1Database }282const app = new Hono<{ Bindings: Bindings }>()283284app.get('/cache/:key', async (c) => {285 const value = await c.env.MY_KV.get(c.req.param('key'))286 return c.json({ value })287})288289export default app290```291292ڈپلائے: `npx wrangler deploy`۔293294### Bun295296```typescript297import { Hono } from 'hono'298const app = new Hono()299app.get('/', (c) => c.text('Bun + Hono'))300301Bun.serve({ fetch: app.fetch, port: 3000 })302```303304### Node.js305306```typescript307import { serve } from '@hono/node-server'308import { Hono } from 'hono'309310const app = new Hono()311app.get('/', (c) => c.text('Node + Hono'))312313serve({ fetch: app.fetch, port: 3000 })314```315316### Deno317318```typescript319import { Hono } from 'jsr:@hono/hono'320const app = new Hono()321app.get('/', (c) => c.text('Deno + Hono'))322Deno.serve(app.fetch)323```324325### Vercel326327```typescript328// api/[[...route]].ts329import { Hono } from 'hono'330import { handle } from 'hono/vercel'331332const app = new Hono().basePath('/api')333app.get('/hello', (c) => c.json({ msg: 'Hello from Vercel' }))334335export const GET = handle(app)336export const POST = handle(app)337```338339## عملی مثال: auth اور DB کے ساتھ REST API340341```typescript342import { Hono } from 'hono'343import { jwt } from 'hono/jwt'344import { logger } from 'hono/logger'345import { cors } from 'hono/cors'346import { zValidator } from '@hono/zod-validator'347import { z } from 'zod'348349type Bindings = { DB: D1Database; JWT_SECRET: string }350type Variables = { jwtPayload: { sub: string } }351352const app = new Hono<{ Bindings: Bindings; Variables: Variables }>()353354app.use('*', logger())355app.use('/api/*', cors({ origin: 'https://spinny.dev', credentials: true }))356357const auth = (c: any, next: any) =>358 jwt({ secret: c.env.JWT_SECRET })(c, next)359360const api = app.basePath('/api')361362api.get('/posts', async (c) => {363 const { results } = await c.env.DB364 .prepare('SELECT id, title, created_at FROM posts ORDER BY created_at DESC LIMIT 50')365 .all()366 return c.json({ posts: results })367})368369api.post(370 '/posts',371 auth,372 zValidator('json', z.object({373 title: z.string().min(1).max(200),374 body: z.string().min(1),375 })),376 async (c) => {377 const { title, body } = c.req.valid('json')378 const userId = c.var.jwtPayload.sub379 const result = await c.env.DB380 .prepare('INSERT INTO posts (title, body, author_id) VALUES (?, ?, ?) RETURNING id')381 .bind(title, body, userId)382 .first<{ id: number }>()383 return c.json({ id: result?.id }, 201)384 }385)386387api.onError((err, c) => {388 console.error(err)389 return c.json({ error: 'Internal error' }, 500)390})391392export type AppType = typeof api393export default app394```395396## ٹیسٹنگ397398```typescript399import { describe, it, expect } from 'vitest'400import app from '../src/index'401402describe('GET /api/posts', () => {403 it('پوسٹس کی فہرست واپس کرتا ہے', async () => {404 const res = await app.request('/api/posts')405 expect(res.status).toBe(200)406 const body = await res.json()407 expect(body.posts).toBeInstanceOf(Array)408 })409})410```411412## بہترین مشقیں413414### 1. روٹ ڈیفینیشنز کو چین کریں415416```typescript417const app = new Hono()418 .get('/posts', handler1)419 .post('/posts', handler2)420 .get('/posts/:id', handler3)421```422423### 2. عمل درآمد نہیں، ٹائپ ایکسپورٹ کریں424425کلائنٹ کو `AppType` امپورٹ کرنا چاہیے۔426427### 3. ہر ڈومین فی روٹر428429`posts`، `users`، `webhooks` کے لیے سب ایپ۔430431### 4. سرحد پر ہمیشہ ویلیڈیٹ کریں432433ہر بیرونی ان پٹ `zValidator` سے گزرے۔434435### 5. گلوبل کلائنٹس نہیں، بائنڈنگز پر انحصار کریں436437Cloudflare پر `c.env` کے ذریعے KV/D1/R2 رسائی۔438439### 6. روٹر کو بہتر بنانے سے پہلے پیمائش کریں440441ڈیفالٹ `SmartRouter` 95٪ کیسز میں ٹھیک ہے۔442443## نتیجہ444445Hono 2026 میں TypeScript میں ایج ریڈی APIs بنانے کا ڈی فیکٹو معیار بن گیا ہے۔446447> **شروع کرنے کی چیک لسٹ:**448>449> - [x] `npm create hono@latest` اور اپنا رن ٹائم ٹیمپلیٹ منتخب کریں450> - [x] چینگ سے روٹس ڈیفائن کریں (`.get(...).post(...)`)451> - [x] `logger`، `cors`، `secureHeaders` کو گلوبل مڈل ویئر کے طور پر شامل کریں452> - [x] ہر ان پٹ کو `@hono/zod-validator` سے ویلیڈیٹ کریں453> - [x] `AppType` ایکسپورٹ کریں اور ٹائپ سیف `hc` کلائنٹ سے API استعمال کریں454> - [x] `app.request()` سے ٹیسٹ لکھیں — HTTP سرور کی ضرورت نہیں455> - [x] `wrangler deploy` (CF)، `vercel deploy` یا اپنے رن ٹائم کے بنڈلر سے ڈپلائے کریں456
:Hono: ویب اسٹینڈرڈز پر بنا الٹرافاسٹ ویب فریم ورکlines 1-456 (END) — press q to close