Notification texts go here Contact Us Get Now!
Postingan

Migrasi dari Express.js ke CanxJS: Panduan Praktis + Perbandingan Kode

Migrasi dari Express.js ke CanxJS: Panduan Praktis + Perbandingan Kode

Express.js sudah jadi standar industri selama bertahun-tahun, tapi kalau kamu mengejar performa lebih tinggi dan developer experience yang lebih modern, CanxJS di atas runtime Bun layak dipertimbangkan. Artikel ini membahas perbandingan kode langsung antara Express dan CanxJS, serta panduan migrasi bertahap supaya project lama kamu tidak perlu ditulis ulang dari nol sekaligus.

Kenapa Pertimbangkan Migrasi?

Berdasarkan benchmark performa:

Metrik Express.js CanxJS
Requests/detik ~15.000 250.000+
Startup time ~200ms < 50ms
Native TypeScript Perlu setup tambahan Native
Native WebSocket Perlu library eksternal Bawaan

Catatan: angka di atas adalah klaim benchmark resmi CanxJS berdasarkan pengujian internal, hasil aktual bisa bervariasi tergantung use case.

Migrasi masuk akal kalau kamu:

  • Butuh throughput tinggi (API dengan traffic besar)
  • Ingin mengurangi jumlah dependency (banyak fitur Express butuh package tambahan: cors, helmet, express-rate-limit, dll — semua ini sudah bawaan di CanxJS)
  • Sudah nyaman dengan Bun sebagai runtime

Perbandingan Kode: Setup Dasar

Express.js

const express = require("express");
const cors = require("cors");
const helmet = require("helmet");
const rateLimit = require("express-rate-limit");

const app = express();

app.use(express.json());
app.use(cors());
app.use(helmet());
app.use(rateLimit({ windowMs: 60000, max: 100 }));

app.get("/", (req, res) => {
  res.json({ message: "Hello Express!" });
});

app.listen(3000, () => console.log("Server berjalan di port 3000"));

Perhatikan bahwa Express butuh 4 package berbeda hanya untuk fitur dasar: parsing JSON, CORS, security header, dan rate limiting.

CanxJS (Setara)

import { createApp, logger, cors } from "canxjs";

const app = createApp({ port: 3000 });

app.use(logger());
app.use(cors());
// Rate limiting & security header sudah aktif secara default

app.get("/", (req, res) => {
  res.json({ message: "Hello CanxJS!" });
});

app.listen();

Tidak ada helmet atau express-rate-limit terpisah — keduanya sudah termasuk dalam Built-in Security CanxJS.

Perbandingan Kode: Routing dengan Parameter

Express.js

app.get("/users/:id", async (req, res) => {
  const { id } = req.params;
  try {
    const user = await User.findById(id);
    if (!user) return res.status(404).json({ message: "User tidak ditemukan" });
    res.json(user);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
});

CanxJS

app.get("/users/:id", async (req, res) => {
  const { id } = req.params;
  try {
    const user = await User.findById(id);
    if (!user) return res.status(404).json({ message: "User tidak ditemukan" });
    res.json(user);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
});

Sengaja saya tampilkan sama persis untuk menunjukkan bahwa sintaks routing CanxJS mirip Express, sehingga kurva belajarnya rendah — modal utamanya cuma paham konsep dasar Express, sisanya tinggal menyesuaikan bagian middleware dan ORM.

Perbandingan Kode: Middleware Custom

Express.js

function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.split(" ")[1];
  if (!token) return res.status(401).json({ message: "Token tidak ditemukan" });

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (err) {
    return res.status(401).json({ message: "Token tidak valid" });
  }
}

app.use("/protected", authMiddleware);

CanxJS

async function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.split(" ")[1];
  if (!token) return res.status(401).json({ message: "Token tidak ditemukan" });

  try {
    const decoded = await verifyJWT(token, process.env.JWT_SECRET);
    req.user = decoded;
    await next();
  } catch (err) {
    return res.status(401).json({ message: "Token tidak valid" });
  }
}

app.use("/protected", authMiddleware);

Perbedaan kunci: Karena CanxJS async-first, pemanggilan next() juga di-await. Ini penting supaya middleware chain berjalan sesuai urutan tanpa race condition — kalau lupa await, response bisa terkirim sebelum proses berikutnya selesai.

Langkah-Langkah Migrasi Bertahap

Daripada rewrite total, ikuti pendekatan bertahap ini:

Langkah 1: Setup CanxJS Berdampingan

Buat project CanxJS baru terpisah dari project Express lama:

bunx create-canx new-api

Langkah 2: Migrasi Model/Schema Terlebih Dahulu

Kalau project Express lama kamu pakai Sequelize/Mongoose, konversi ke model CanxJS satu per satu:

// Sebelum (Sequelize)
const User = sequelize.define("User", {
  name: DataTypes.STRING,
  email: DataTypes.STRING,
});

// Sesudah (CanxJS ORM)
import { Model, Column, Table } from "canxjs/orm";

@Table("users")
export class User extends Model {
  @Column({ primary: true, autoIncrement: true })
  id!: number;

  @Column({ type: "string", required: true })
  name!: string;

  @Column({ type: "string", required: true, unique: true })
  email!: string;
}

Langkah 3: Migrasi Route per Modul

Pindahkan route satu modul dulu (misal modul auth), test menyeluruh, baru lanjut modul berikutnya. Jangan migrasi semua endpoint sekaligus — ini mengurangi risiko downtime produksi.

Langkah 4: Jalankan Kedua Server Sementara (Strangler Pattern)

Gunakan reverse proxy (Nginx) untuk mengarahkan sebagian traffic ke CanxJS (modul yang sudah dimigrasi) dan sisanya tetap ke Express (modul yang belum), sampai migrasi 100% selesai:

location /api/v2/ {
    proxy_pass http://localhost:3000; # CanxJS
}

location /api/ {
    proxy_pass http://localhost:4000; # Express lama
}

Langkah 5: Matikan Server Express Setelah Semua Modul Beres

Setelah semua endpoint sudah pindah dan lolos testing, baru matikan server Express lama sepenuhnya.

Troubleshooting Saat Migrasi

1. Cannot find module 'canxjs/orm'

Penyebab: Dependency belum lengkap terinstall, atau versi CanxJS yang dipakai belum menyertakan module ORM.

Solusi:

bun add canxjs@latest
bun install

2. Middleware Express lama tidak jalan di CanxJS

Penyebab: Middleware Express klasik ((req, res, next) => {}) umumnya sinkron, sedangkan CanxJS mengharapkan pola async (async (req, res, next) => {}).

Solusi: Bungkus middleware lama dengan wrapper async:

function toAsyncMiddleware(fn) {
  return async (req, res, next) => {
    fn(req, res, next);
  };
}

app.use(toAsyncMiddleware(oldExpressMiddleware));

3. Environment variable tidak terbaca setelah migrasi

Penyebab: Bun memiliki cara load .env yang sedikit berbeda dari Node.js.

Solusi: Pastikan file .env ada di root project, dan Bun otomatis membacanya — tidak perlu install dotenv secara manual di kebanyakan kasus. Kalau tetap tidak terbaca, verifikasi dengan:

bun run -e "console.log(process.env.DB_HOST)"

4. Query database lama (raw SQL) tidak kompatibel dengan ORM baru

Penyebab: ORM CanxJS punya konvensi penamaan dan struktur query builder sendiri.

Solusi: CanxJS biasanya tetap menyediakan raw query fallback untuk kasus kompleks:

import { db } from "canxjs/orm";

const results = await db.raw("SELECT * FROM users WHERE age > ?", [18]);

Gunakan ini sebagai jembatan sementara sambil pelan-pelan mengonversi ke sintaks ORM native.

Kesimpulan

Migrasi dari Express.js ke CanxJS tidak harus dilakukan sekaligus. Dengan pendekatan bertahap — mulai dari model, lalu route per modul, dan strangler pattern lewat reverse proxy — kamu bisa memindahkan project produksi tanpa downtime signifikan, sambil menikmati peningkatan performa dan fitur bawaan yang lebih lengkap.

Kalau kamu sedang proses migrasi dan menemui error yang belum dibahas di sini, tulis di kolom komentar — saya bantu cek!

Getting Info...

Posting Komentar

Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.