Tüm Yazılar
KategoriBackend
Okuma Süresi
14 dk okuma
Yayın Tarihi
...
Kelime Sayısı
3.093kelime

Kahveni hazırla - bu içerikli bir makale!

Hono.js ultra-hızlı web framework, multi-runtime desteği (Workers, Deno, Bun, Node), middleware sistemi, RPC mode ve production deployment deneyimi.

Hono.js: Serverless Web Framework Production Rehberi 2026

# Hono.js: Serverless Web Framework Production Rehberi 2026

Cloudflare Workers ekosistemi büyüdükçe, edge-first bir web framework ihtiyacı da giderek daha kritik hale geldi. Hono.js tam da bu noktada ortaya çıktı: sub-12KB bundle size, ~150K req/sec throughput ve tek kod tabanından Cloudflare Workers, Deno, Bun, Node.js, AWS Lambda ve Vercel Edge üzerinde çalışabilme kapasitesiyle 2024-2026 döneminin en hızlı büyüyen backend framework"i oldu.

Bu rehberde Hono"nun mimarisini, router sistemini, middleware ekosistemini, RPC modunu ve gerçek production deployment senaryolarını ele alacağız.

Pro Tip: Hono"da en sık yapılan hata, middleware sırasını yanlış kurmak. app.use() çağrıları route tanımlarından önce gelmelidir; sonra tanımlanan middleware yalnızca sonraki route"lara uygulanır. Bu Node.js/Express davranışından farklıdır.

İçindekiler

  1. Neden Hono? Rekabet Avantajı
  2. Router Mimarisi: RegExpRouter, TrieRouter, SmartRouter
  3. Multi-Runtime Compatibility
  4. Middleware Ekosistemi
  5. JSX Renderer ve SSR
  6. RPC Mode ile Type-Safe Client
  7. Validator ve OpenAPI Entegrasyonu
  8. Test Stratejileri
  9. Production Deployment Patterns
  10. Fastify ve Express Karşılaştırması

1. Neden Hono? Rekabet Avantajı

Hono, Japonca"da "flame" (alev) anlamına gelir ve bu isim framework"ün performans felsefesini yansıtır. Yoshi Wada tarafından başlatılan projenin temel hedefi şuydu: Web Standards API (Request, Response, Headers) üzerinde çalışan, sıfır bağımlılıklı, her JavaScript runtime"ında koşan minimal bir framework.

Rakiplerle temel fark:

  • Fastify: Node.js-only, ~250KB bundle, güçlü ama edge"e taşınmaz
  • Express: 30 yaşında, Web Standards değil Node.js http modülü üstünde
  • Itty Router: çok minimal, middleware ekosistemi yok
  • Hono: Web Standards üstünde, multi-runtime, tam-featured

Cloudflare Workers ortamında Hono yaklaşık 150.000 req/sec throughput sağlar. Bu sayı, benzer özellikteki framework"lerin 3-5 katıdır. Bunun nedeni Hono"nun router algoritmalarının özellikle path matching için optimize edilmesi ve allocasyon sayısının minimize edilmesidir.


2. Router Mimarisi: RegExpRouter, TrieRouter, SmartRouter

Hono"nun performans sırrı büyük ölçüde router seçiminde yatıyor. Framework üç farklı router sunar:

RegExpRouter

Tüm route pattern"larını tek bir dev regex"e derler. Routing işlemi O(1) karmaşıklığındadır çünkü tüm pattern"lar tek seferde test edilir. Route sayısı arttıkça avantajı büyür.

typescript
1import { Hono } from 'hono';
2import { RegExpRouter } from 'hono/router/reg-exp-router';
3 
4// RegExpRouter açıkça belirtme (SmartRouter zaten seçer)
5const app = new Hono({ router: new RegExpRouter() });
6 
7app.get('/users/:id', (c) => {
8 const id = c.req.param('id');
9 return c.json({ userId: id });
10});
11 
12app.get('/posts/:slug/comments/:commentId', (c) => {
13 const { slug, commentId } = c.req.param();
14 return c.json({ slug, commentId });
15});
16 
17export default app;

TrieRouter

Trie (prefix tree) veri yapısını kullanır. Dinamik segment sayısı çok fazlaysa RegExpRouter"dan daha hızlı olabilir. Wildcard pattern"lar için tercih edilir.

SmartRouter (Varsayılan)

Hono 4.x"ten itibaren varsayılan router. Route"ları analiz ederek RegExpRouter veya TrieRouter arasında otomatik seçim yapar. Geliştiricinin router konusunda düşünmesine gerek kalmaz.

typescript
1// SmartRouter varsayılan — özel bir şey belirtmeye gerek yok
2const app = new Hono();
3 
4// Tüm route"lara erişim (debug için):
5// app.routes.forEach(r => console.log(r.method, r.path));

3. Multi-Runtime Compatibility

Hono"nun en stratejik özelliği, aynı kodun birden fazla runtime"da çalışmasıdır. Bu, Web Standards API"ye (Fetch API, Request, Response, Headers, URL, URLSearchParams) bağlı kalınarak sağlanır.

Desteklenen runtime"lar:

Runtime
Entry Point
Not
Cloudflare Workers
`export default app`
Wrangler ile deploy
Deno
`Deno.serve(app.fetch)`
Native HTTP
Bun
`Bun.serve({ fetch: app.fetch })`
Hızlı startup
Node.js
`serve(app)` (@hono/node-server)
Adapter gerekli
Vercel Edge
`export const GET = handle(app)`
Edge runtime
AWS Lambda
`handle(app)` (@hono/aws-lambda)
Adapter gerekli
Fastly Compute
`app.fire()`
WASM runtime
typescript
1// src/index.ts — runtime-agnostic core
2import { Hono } from 'hono';
3import { cors } from 'hono/cors';
4import { logger } from 'hono/logger';
5import { prettyJSON } from 'hono/pretty-json';
6 
7type Env = {
8 Variables: {
9 userId: string;
10 };
11 Bindings: {
12 DATABASE_URL: string;
13 JWT_SECRET: string;
14 };
15};
16 
17const app = new Hono<Env>();
18 
19app.use('*', logger());
20app.use('/api/*', cors({ origin: ['https://muhittincamdali.com'] }));
21app.use('/api/*', prettyJSON());
22 
23app.get('/api/health', (c) => {
24 return c.json({
25 status: 'ok',
26 runtime: c.env?.DATABASE_URL ? 'cf-workers' : 'local',
27 timestamp: new Date().toISOString(),
28 });
29});
30 
31export default app;
32 
33// Cloudflare Workers: bu dosya yeterli (export default app)
34// Deno: Deno.serve(app.fetch) ekle
35// Bun: Bun.serve({ fetch: app.fetch }) ekle
36// Node: import { serve } from "@hono/node-server"; serve(app);

4. Middleware Ekosistemi

Hono"nun built-in middleware"leri hono/ prefix"i altında gelir. Üçüncü taraf middleware"ler ise @hono/ scope"undadır.

Kritik built-in middleware"ler:

typescript
1import { Hono } from 'hono';
2import { cors } from 'hono/cors';
3import { compress } from 'hono/compress';
4import { cache } from 'hono/cache';
5import { bearerAuth } from 'hono/bearer-auth';
6import { rateLimiter } from 'hono/rate-limiter';
7import { secureHeaders } from 'hono/secure-headers';
8import { timing } from 'hono/timing';
9import { etag } from 'hono/etag';
10 
11const app = new Hono();
12 
13// Güvenlik header"ları (tüm route"lara)
14app.use('*', secureHeaders());
15 
16// Response timing (Server-Timing header)
17app.use('*', timing());
18 
19// Gzip/Brotli sıkıştırma
20app.use('/api/*', compress());
21 
22// ETag cache kontrolü
23app.use('/static/*', etag());
24 
25// CDN-level cache (Cloudflare Cache API)
26app.use(
27 '/api/public/*',
28 cache({
29 cacheName: 'hono-public-api',
30 cacheControl: 'public, max-age=3600',
31 })
32);
33 
34// CORS — fine-grained ayar
35app.use(
36 '/api/*',
37 cors({
38 origin: (origin) => {
39 const allowed = ['https://muhittincamdali.com', 'https://app.muhittincamdali.com'];
40 return allowed.includes(origin) ? origin : 'https://muhittincamdali.com';
41 },
42 allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
43 allowHeaders: ['Content-Type', 'Authorization'],
44 credentials: true,
45 maxAge: 86400,
46 })
47);
48 
49// Rate limiting (IP tabanlı)
50app.use(
51 '/api/auth/*',
52 rateLimiter({
53 windowMs: 15 * 60 * 1000, // 15 dakika
54 limit: 10,
55 keyGenerator: (c) => c.req.header('CF-Connecting-IP') ?? 'unknown',
56 handler: (c) => c.json({ error: 'Too many requests' }, 429),
57 })
58);
59 
60// Custom middleware — JWT verification
61app.use('/api/protected/*', async (c, next) => {
62 const token = c.req.header('Authorization')?.replace('Bearer ', '');
63 if (!token) return c.json({ error: 'Unauthorized' }, 401);
64 
65 try {
66 const { verify } = await import('hono/jwt');
67 const payload = await verify(token, c.env.JWT_SECRET);
68 c.set('userId', payload.sub as string);
69 await next();
70 } catch {
71 return c.json({ error: 'Invalid token' }, 401);
72 }
73});
74 
75export default app;

5. JSX Renderer ve SSR

Hono, built-in JSX renderer ile sunucu taraflı rendering yapabilir. React gerektirmez — Hono"nun kendi hono/jsx modülü TSX/JSX"i HTML"e çevirir.

typescript
1/** @jsxImportSource hono/jsx */
2import { Hono } from 'hono';
3import { jsxRenderer } from 'hono/jsx-renderer';
4 
5const app = new Hono();
6 
7// Layout renderer
8app.use(
9 '*',
10 jsxRenderer(({ children, title }) => {
11 return (
12 <html lang="tr">
13 <head>
14 <meta charset="UTF-8" />
15 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
16 <title>{title ?? 'Hono App'}</title>
17 <link rel="stylesheet" href="/static/styles.css" />
18 </head>
19 <body>
20 <main>{children}</main>
21 </body>
22 </html>
23 );
24 })
25);
26 
27// SSR page
28app.get('/blog/:slug', async (c) => {
29 const slug = c.req.param('slug');
30 const post = await fetchBlogPost(slug);
31 
32 if (!post) return c.notFound();
33 
34 return c.render(
35 <article>
36 <h1>{post.title}</h1>
37 <time dateTime={post.publishedAt}>{formatDate(post.publishedAt)}</time>
38 <p>{post.summary}</p>
39 </article>,
40 { title: post.title }
41 );
42});
43 
44// Streaming SSR
45app.get('/stream', (c) => {
46 return c.streamText(async (stream) => {
47 await stream.writeln('# Streaming Response');
48 await stream.sleep(100);
49 await stream.writeln('Data chunk 1...');
50 await stream.sleep(100);
51 await stream.writeln('Data chunk 2...');
52 });
53});
54 
55async function fetchBlogPost(slug: string) {
56 // KV veya D1 sorgusu
57 return slug ? { title: 'Test Post', publishedAt: new Date().toISOString(), summary: 'İçerik...' } : null;
58}
59 
60function formatDate(iso: string) {
61 return new Date(iso).toLocaleDateString('tr-TR', {
62 year: 'numeric', month: 'long', day: 'numeric',
63 });
64}
65 
66export default app;
Pro Tip: Hono JSX"de tüm ifadeler otomatik olarak escape edilir. String"i ham HTML olarak render etmeniz gerekiyorsa, içeriği önce bir sanitizer library (örn. sanitize-html) ile temizleyip ardından Hono"nun html tagged template literal"ını kullanın. Güvenilmeyen girdileri hiçbir zaman doğrudan render etmeyin.

6. RPC Mode ile Type-Safe Client

Hono"nun en güçlü özelliklerinden biri RPC mode"dur. Server tarafında tanımlanan route"ların tip bilgisi otomatik olarak client"a aktarılır. Bu, tRPC"ye benzer bir developer experience sağlar ancak ek bir schema tanımı gerektirmez.

typescript
1// server/routes/users.ts
2import { Hono } from 'hono';
3import { zValidator } from '@hono/zod-validator';
4import { z } from 'zod';
5 
6const createUserSchema = z.object({
7 name: z.string().min(2).max(100),
8 email: z.string().email(),
9 role: z.enum(['admin', 'user', 'editor']),
10});
11 
12const usersRoute = new Hono()
13 .get('/', async (c) => {
14 const users = await getUsersFromDB();
15 return c.json({ users, count: users.length });
16 })
17 .get('/:id', async (c) => {
18 const id = c.req.param('id');
19 const user = await getUserById(id);
20 if (!user) return c.json({ error: 'User not found' }, 404);
21 return c.json({ user });
22 })
23 .post('/', zValidator('json', createUserSchema), async (c) => {
24 const data = c.req.valid('json');
25 const user = await createUser(data);
26 return c.json({ user }, 201);
27 })
28 .delete('/:id', async (c) => {
29 await deleteUser(c.req.param('id'));
30 return c.json({ success: true });
31 });
32 
33export type UsersRouteType = typeof usersRoute;
34export default usersRoute;
35 
36// server/index.ts
37import { Hono } from 'hono';
38import usersRoute from './routes/users';
39 
40const app = new Hono().route('/api/users', usersRoute);
41 
42export type AppType = typeof app;
43export default app;
44 
45// client/api.ts — RPC client (browser veya başka bir service)
46import { hc } from 'hono/client';
47import type { AppType } from '../server/index';
48 
49const client = hc<AppType>('https://api.muhittincamdali.com');
50 
51// Tam type-safe çağrılar — autocomplete çalışır, tip hatası derleme zamanında yakalanır
52async function example() {
53 // GET /api/users
54 const listRes = await client.api.users.$get();
55 const { users } = await listRes.json(); // users: User[] — otomatik tip
56 
57 // POST /api/users
58 const createRes = await client.api.users.$post({
59 json: {
60 name: 'Muhittin Çamdali',
61 email: '[email protected]',
62 role: 'admin', // "admin" | "user" | "editor" — literal union
63 },
64 });
65 
66 const { user } = await createRes.json(); // user: User — tam tip
67 
68 // DELETE /api/users/:id
69 await client.api.users[':id'].$delete({ param: { id: user.id } });
70}
71 
72// Stub fonksiyonlar (gerçek implementasyon DB katmanında)
73async function getUsersFromDB() { return [] as Array<{ id: string; name: string; email: string; role: string }>; }
74async function getUserById(_id: string) { return null; }
75async function createUser(data: { name: string; email: string; role: string }) { return { id: crypto.randomUUID(), ...data }; }
76async function deleteUser(_id: string) {}

7. Validator ve OpenAPI Entegrasyonu

Hono, Zod dışında da validator seçenekleri sunar: @hono/valibot-validator, @hono/typebox-validator, @hono/arktype-validator. OpenAPI entegrasyonu ise @hono/zod-openapi ile sağlanır.

typescript
1import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
2import { swaggerUI } from '@hono/swagger-ui';
3 
4const app = new OpenAPIHono();
5 
6// Route şeması — OpenAPI spec"i otomatik üretir
7const getUserRoute = createRoute({
8 method: 'get',
9 path: '/users/{id}',
10 tags: ['Users'],
11 summary: 'Kullanıcı getir',
12 description: 'ID ile tek kullanıcı bilgisi döner',
13 request: {
14 params: z.object({
15 }),
16 },
17 responses: {
18 200: {
19 content: {
20 'application/json': {
21 schema: z.object({
22 user: z.object({
23 name: z.string(),
24 email: z.string().email(),
25 createdAt: z.string().datetime(),
26 }),
27 }),
28 },
29 },
30 description: 'Kullanıcı başarıyla getirildi',
31 },
32 404: {
33 content: {
34 'application/json': {
35 schema: z.object({ error: z.string() }),
36 },
37 },
38 description: 'Kullanıcı bulunamadı',
39 },
40 },
41});
42 
43app.openapi(getUserRoute, async (c) => {
44 const { id } = c.req.valid('param'); // id: string (uuid) — tip güvenli
45 return c.json({
46 user: {
47 id,
48 name: 'Test Kullanıcı',
49 email: '[email protected]',
50 createdAt: new Date().toISOString(),
51 },
52 });
53});
54 
55// Swagger UI endpoint
56app.get('/docs', swaggerUI({ url: '/openapi.json' }));
57 
58// OpenAPI JSON spec
59app.doc('/openapi.json', {
60 openapi: '3.0.0',
61 info: {
62 title: 'Portfolio API',
63 version: '1.0.0',
64 description: 'Muhittin Çamdali Portfolio API',
65 },
66 servers: [{ url: 'https://api.muhittincamdali.com', description: 'Production' }],
67});
68 
69export default app;
Pro Tip: @hono/zod-openapi kullanırken schema tanımlarını ayrı bir schemas/ klasöründe tutun ve hem route validation hem de OpenAPI doc üretimi için aynı schema"yı paylaşın. Bu yaklaşım kod tekrarını ortadan kaldırır, dokümanın her zaman güncel kalmasını garantiler.

8. Test Stratejileri

Hono uygulamaları test etmek son derece kolaydır çünkü framework Web Standards üzerinde çalışır. Node.js HTTP sunucusu başlatmaya gerek yoktur.

typescript
1// src/routes/posts.test.ts
2import { describe, it, expect, beforeEach } from 'vitest';
3import { Hono } from 'hono';
4import postsRoute from './posts';
5 
6describe('Posts API', () => {
7 let app: Hono;
8 
9 beforeEach(() => {
10 app = new Hono().route('/api/posts', postsRoute);
11 });
12 
13 it('GET /api/posts — liste döner', async () => {
14 const res = await app.request('/api/posts');
15 expect(res.status).toBe(200);
16 
17 const body = await res.json();
18 expect(body).toHaveProperty('posts');
19 expect(Array.isArray(body.posts)).toBe(true);
20 });
21 
22 it('POST /api/posts — validation hatası', async () => {
23 const res = await app.request('/api/posts', {
24 method: 'POST',
25 headers: { 'Content-Type': 'application/json' },
26 body: JSON.stringify({ title: '' }), // Geçersiz — min length 1
27 });
28 
29 expect(res.status).toBe(400);
30 const body = await res.json();
31 expect(body).toHaveProperty('error');
32 });
33 
34 it('POST /api/posts — başarılı oluşturma', async () => {
35 const res = await app.request('/api/posts', {
36 method: 'POST',
37 headers: {
38 'Content-Type': 'application/json',
39 Authorization: 'Bearer valid-test-token',
40 },
41 body: JSON.stringify({
42 title: 'Test Post',
43 content: 'Test content...',
44 published: false,
45 }),
46 });
47 
48 expect(res.status).toBe(201);
49 const { post } = await res.json();
50 expect(post.title).toBe('Test Post');
51 expect(post.id).toBeDefined();
52 });
53 
54 it('Middleware — JWT olmadan 401', async () => {
55 const res = await app.request('/api/posts', { method: 'POST' });
56 expect(res.status).toBe(401);
57 });
58 
59 it('Rate limiting — 429 after threshold', async () => {
60 // 10 istek gönder, 11. 429 vermeli
61 for (let i = 0; i < 10; i++) {
62 await app.request('/api/auth/login', {
63 method: 'POST',
64 headers: {
65 'Content-Type': 'application/json',
66 'CF-Connecting-IP': '1.2.3.4',
67 },
68 body: JSON.stringify({ email: '[email protected]', password: 'wrong' }),
69 });
70 }
71 
72 const res = await app.request('/api/auth/login', {
73 method: 'POST',
74 headers: {
75 'Content-Type': 'application/json',
76 'CF-Connecting-IP': '1.2.3.4',
77 },
78 body: JSON.stringify({ email: '[email protected]', password: 'wrong' }),
79 });
80 
81 expect(res.status).toBe(429);
82 });
83});

9. Production Deployment Patterns

Cloudflare Workers (Wrangler)

typescript
1// wrangler.toml — temel yapılandırma
2// name = "portfolio-api"
3// main = "src/index.ts"
4// compatibility_date = "2026-04-01"
5// compatibility_flags = ["nodejs_compat"]
6//
7// [vars]
8// ENVIRONMENT = "production"
9//
10// [[kv_namespaces]]
11// binding = "CACHE_KV"
12// id = "xxx"
13//
14// [[d1_databases]]
15// binding = "DB"
16// database_name = "portfolio-db"
17// database_id = "yyy"
18 
19// src/index.ts — Cloudflare Workers entry point
20import { Hono } from 'hono';
21 
22interface CloudflareEnv {
23 CACHE_KV: KVNamespace;
24 DB: D1Database;
25 JWT_SECRET: string;
26 ENVIRONMENT: string;
27}
28 
29const app = new Hono<{ Bindings: CloudflareEnv }>();
30 
31app.get('/api/status', (c) => {
32 return c.json({
33 env: c.env.ENVIRONMENT,
34 timestamp: new Date().toISOString(),
35 });
36});
37 
38// D1 ile veritabanı sorgusu
39app.get('/api/posts/:id', async (c) => {
40 const id = c.req.param('id');
41 const result = await c.env.DB
42 .prepare('SELECT id, title, slug, published_at FROM posts WHERE id = ? AND published = 1')
43 .bind(id)
44 .first();
45 
46 if (!result) return c.json({ error: 'Not found' }, 404);
47 return c.json({ post: result });
48});
49 
50// KV cache pattern
51app.get('/api/config', async (c) => {
52 const cached = await c.env.CACHE_KV.get('site-config', 'json');
53 if (cached) return c.json(cached);
54 
55 const config = { theme: 'dark', version: '2.0.0' };
56 await c.env.CACHE_KV.put('site-config', JSON.stringify(config), { expirationTtl: 3600 });
57 return c.json(config);
58});
59 
60export default app;
61// Deploy: wrangler deploy
62// Staging: wrangler deploy --env staging

Deno Deploy

typescript
1// main.ts — Deno Deploy entry point
2import { Hono } from 'npm:hono';
3import { cors } from 'npm:hono/cors';
4import { logger } from 'npm:hono/logger';
5 
6const app = new Hono();
7 
8app.use('*', logger());
9app.use('/api/*', cors());
10 
11app.get('/', (c) => c.text('Hono on Deno Deploy!'));
12app.get('/api/ping', (c) => c.json({ pong: true, runtime: 'deno', ts: Date.now() }));
13 
14Deno.serve(app.fetch);
15// Deploy: deno deploy --project=my-project main.ts

Bun Runtime

typescript
1// server.ts — Bun runtime entry point
2import { Hono } from 'hono';
3 
4const app = new Hono();
5app.get('/', (c) => c.text('Hono on Bun!'));
6app.get('/api/ping', (c) => c.json({ pong: true, runtime: 'bun' }));
7 
8const server = Bun.serve({
9 fetch: app.fetch,
10 port: Number(process.env.PORT) || 3000,
11 development: process.env.NODE_ENV !== 'production',
12});
13 
14console.log(`Bun server running on port ${server.port}`);
15// Run: bun run server.ts
16// Compile: bun build server.ts --compile --outfile server

10. Fastify ve Express Karşılaştırması

Özellik
Hono
Fastify
Express
Bundle size
~12KB
~250KB
~200KB
Runtime
Multi (Workers, Deno, Bun, Node)
Node.js only
Node.js only
Req/sec (CF Workers)
~150K
N/A
N/A
Req/sec (Node.js)
~80K
~75K
~35K
TypeScript
Native, zero-config
Plugin gerekli
@types gerekli
Web Standards
Tam uyumlu
Kısmi
Hayır
RPC mode
Var (hono/client)
Yok
Yok
OpenAPI
@hono/zod-openapi
@fastify/swagger
express-openapi
Edge deployment
Birincil hedef
Zor
Çok zor
Ekosistem olgunluğu
Büyüyor (~2022)
Olgun (~2016)
Çok olgun (~2010)

Ne zaman Hono seç:

  • Cloudflare Workers, Deno Deploy, Bun veya Vercel Edge hedefliyorsanız
  • Multi-runtime strategy izliyorsanız
  • RPC mode ile type-safe fullstack isteyip tRPC karmaşıklığından kaçınmak istiyorsanız
  • Bundle size kritikse

Ne zaman Fastify seç:

  • Node.js monoliti, edge migration planı yoksa
  • Fastify plugin ekosistemini (PostgreSQL, Redis, auth) aktif kullanıyorsanız
  • Ekibin deneyimi Express/Fastify tarafındaysa

ALTIN İPUCU

Bu yazının en değerli bilgisi

Bu ipucu, yazının en önemli çıkarımını içeriyor.

typescript
1app.get('/debug/routes', (c) => {
2 const debugKey = c.req.header('X-Debug-Key');
3 const isDev = c.env?.ENVIRONMENT === 'development';
4 
5 // 401 değil 404 — endpoint"in varlığını gizle
6 if (!isDev || debugKey !== c.env?.DEBUG_SECRET) {
7 return c.json({ error: 'Not found' }, 404);
8 }
9 
10 const routes = app.routes.map((r) => ({
11 method: r.method,
12 path: r.path,
13 }));
14 
15 return c.json({ routes, totalRoutes: routes.length, timestamp: Date.now() });
16});

Easter Egg

Gizli bir bilgi buldun!

Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?

swift
1src/routes/
2 index.ts → GET /
3 api/
4 users/
5 index.ts → GET /api/users, POST /api/users
6 [id].ts → GET /api/users/:id, PUT /api/users/:id
7 posts/
8 index.ts → GET /api/posts
9 [slug]/
10 comments.ts → GET /api/posts/:slug/comments
typescript
1// src/app.ts — glob import ile dinamik routing (Bun / Vite)
2import { Hono } from 'hono';
3 
4const app = new Hono();
5 
6// Bun veya Vite build tool"u ile glob import
7const routeModules = import.meta.glob('./routes/**/*.ts', { eager: true });
8 
9for (const [filePath, module] of Object.entries(routeModules)) {
10 const routePath = filePath
11 .replace('./routes', '')
12 .replace('/index.ts', '')
13 .replace('.ts', '')
14 .replace(/\[([^\]]+)\]/g, ':$1'); // [id] → :id dönüşümü
15 
16 const mod = module as { default?: Hono };
17 if (mod.default instanceof Hono) {
18 app.route(routePath || '/', mod.default);
19 }
20}
21 
22export default app;

Okuyucu Ödülü

Hono 4.4+ ile file-based routing desteği aktif. Klasör yapısı otomatik route"a dönüşür:

Sonuç

Hono.js, 2026 itibarıyla serverless ve edge computing dünyasının fiilen standardı haline gelmiştir. Sub-12KB bundle size, ~150K req/sec throughput, native TypeScript desteği, multi-runtime uyumluluğu ve tRPC benzeri RPC mode, Hono"yu hem greenfield projeler hem de Cloudflare Workers"a migrasyon yapan mevcut uygulamalar için ideal kılar.

SmartRouter ile sıfır-config yüksek performans, @hono/zod-openapi ile otomatik API dokümantasyonu, hono/client ile type-safe frontend entegrasyonu — bu üçlü, Hono"yu 2026"nın en verimli backend geliştirme deneyimini sunan framework"lerden biri yapmaktadır.


İlgili Yazılar


Kaynaklar

Etiketler

#Hono#Serverless#Cloudflare Workers#Deno#Bun#Web Framework#2026
Muhittin Çamdalı

Muhittin Çamdalı

Senior iOS Developer

12+ yıllık deneyime sahip iOS Developer. Swift, SwiftUI ve modern iOS mimarileri konusunda uzman. Apple platformlarında performanslı ve kullanıcı dostu uygulamalar geliştiriyorum.

iOS Geliştirme Haberleri

Haftalık Swift tips, SwiftUI tricks ve iOS best practices. Spam yok, sadece değerli içerik.

Gizliliğinize saygı duyuyoruz. İstediğiniz zaman abonelikten çıkabilirsiniz.

Paylaş

İlgili İçerik