Lewati ke konten utama
menjadi.dev
Chapter 17.4 Backend Lanjutan

Bun untuk Backend Development

Pattern dan best practices development backend dengan Bun

Tujuan Pembelajaran

  • Mengerti pattern backend dengan Bun
  • Bisa membuat middleware system
  • Mengerti environment dan deployment Bun

Analogi

Diagram

      Backend Pattern:
Request → Middleware (auth, logging) → Handler → Response

Bun + Hono = Backend modern yang ringan dan cepat
    

Bun sebagai fondasi runtime, framework seperti Hono untuk routing dan middleware

Penjelasan Konsep

Bun.serve() yang sudah kita pelajari adalah fondasi yang bagus, tapi untuk aplikasi production, kita butuh lebih dari sekadar routing sederhana.

Kita butuh middleware, error handling, validation, dan struktur yang terorganisir.

Pattern Middleware di Bun

Meskipun Bun.serve() tidak punya middleware built-in seperti Express, kita bisa membuat sistem middleware sendiri:

type Middleware = (req: Request, next: () => Response | Promise<Response>) => Response | Promise<Response>;

function compose(middlewares: Middleware[],

Handler: (req: Request) => Response) {
  return async (req: Request) => {
    let index = 0;
    const next = async (): Promise<Response> => {
      if (index < middlewares.length) {
        return middlewares[index++](req, next);
      }
      return handler(req);
    };
    return next();
  };
}

Tapi sebenarnya, daripada membuat dari nol, lebih baik menggunakan framework yang sudah teruji seperti Hono.

Bun + Hono: Kombinasi Sempurna

Hono adalah framework web ultra-lightweight yang dirancang untuk edge runtime — termasuk Bun.

Dengan kombinasi Bun + Hono, kamu mendapatkan:

  • Bun: runtime cepat dengan built-in tools
  • Hono: routing, middleware, validation,

Dan DX yang bagus

Ini akan kita pelajari detail di chapter Hono berikutnya.

Environment Variables di Bun

Bun membaca .env file secara otomatis — tidak perlu install dotenv:

# .env
DATABASE_URL=sqlite:app.db
JWT_SECRET=super-secret-key
PORT=3000

Akses di kode:

const port = process.env.PORT || 3000;
// atau
const port = Bun.env.PORT || 3000;

Deployment Bun

Pilihan deployment untuk Bun:

  1. VPS/Server: Install Bun di server, jalankan dengan process manager (PM2, systemd)
  2. Docker: Image resmi oven/bun tersedia
  3. Fly.io: Support Bun native
  4. Edge platforms: Cloudflare Workers, Vercel Edge (dengan kompilasi)

Dockerfile untuk Bun

FROM oven/bun:1 AS base
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install --production
COPY . .
EXPOSE 3000
CMD ["bun", "run",

"src/index.ts"]

Monitoring dan Logging

Untuk production, tambahkan:

  • Structured logging (Winston, Pino, atau built-in console)
  • Health check endpoint
  • Graceful shutdown handler
  • Error tracking (Sentry)

Best Practices Bun Backend

  1. Gunakan TypeScript untuk type safety
  2. Validasi input dengan Zod sebelum memproses
  3. Gunakan SQLite untuk prototyping, PostgreSQL untuk production
  4. Implementasikan rate limiting
  5. Gunakan environment variables untuk konfigurasi
  6. Tulis test untuk setiap endpoint

Contoh Kode

typescript
// Structured backend dengan Bun
import { Database } from 'bun:sqlite';

// Environment
const PORT = Number(Bun.env.PORT || 3000);
const DB_PATH = Bun.env.DATABASE_URL || 'app.db';

// Database
const db = new Database(DB_PATH);

// Middleware logger
function logger(req: Request, next: () => Response) {
  const start = Date.now();
  const res = next();
  console.log(`${req.method} ${req.url} - ${Date.now() - start}ms`);
  return res;
}

// Error handler
function errorHandler(handler: (req: Request) => Response) {
  return (req: Request) => {
    try {
      return handler(req);
    } catch (err) {
      console.error(err);
      return Response.json({ error: 'Internal Server Error' }, { status: 500 });
    }
  };
}

// Graceful shutdown
process.on('SIGTERM', () => {
  console.log('Shutting down gracefully...');
  db.close();
  process.exit(0);
});

Bun.serve({
  port: PORT,
  fetch: errorHandler((req) => {
    return logger(req, () => route(req));
  }),
});

function route(req: Request): Response {
  const url = new URL(req.url);
  if (url.pathname === '/health') return Response.json({ status: 'ok' });
  if (url.pathname === '/api/users') return Response.json(db.query('SELECT * FROM users').all());
  return new Response('Not Found', { status: 404 });
}

console.log(`Server running on port ${PORT}`);

Penjelasan Kode

Graceful shutdown memastikan database ditutup dengan benar saat server dimatikan. Error handler middleware menangkap uncaught exceptions.

Prompt AI

Implementasikan rate limiting sederhana dengan Map untuk tracking request per IP. Block IP yang melebihi threshold.

Pertanyaan Reflektif

Bun runtime sangat cepat startup-nya. Coba hitung berapa milidetik dari bun run sampai server siap menerima request.