Rust + Vue Full Stack: Membangun Aplikasi Web Lengkap • Erlkim

Rust + Vue Full Stack: Membangun Aplikasi Web Lengkap

Rust + Vue Full Stack: Membangun Aplikasi Web Lengkap
Jun 13, 2026 ... views
12 min

Membangun aplikasi web full stack dengan Rust dan Vue adalah kombinasi yang powerful. Rust menawarkan performa tinggi dan keamanan memori di sisi backend, sementara Vue memberikan pengembangan frontend yang cepat dan reaktif. Artikel ini akan membahas cara menghubungkan keduanya menjadi satu aplikasi utuh.

Mengapa Rust + Vue?

Rust dan Vue punya filosofi yang saling melengkapi:

Rust (Backend): Performa C/C++, keamanan memori tanpa garbage collector, type safety yang kuat Vue (Frontend): Reactive UI, ekosistem Vite yang cepat, learning curve yang landai

Kombinasi ini cocok untuk aplikasi yang butuh performa backend tinggi dan UI yang responsif, seperti dashboard, API service, atau aplikasi data-intensive.

Arsitektur Aplikasi

Arsitektur yang kita gunakan terdiri dari tiga layer:

Browser (Vue 3 + Vite)
    |
    | proxy /api/*
    v
Rust Axum Server (localhost:3001)
    |
    | HTTP request
    v
External API / Database

Vite berperan sebagai dev server yang me-proxy request /api/* ke backend Rust. Di production, kamu bisa gunakan reverse proxy seperti Nginx atau Cloudflare.

Membangun Backend dengan Axum

Axum adalah web framework dari ekosistem Tokio yang ringan dan ergonomis. Berikut setup dasarnya.

Cargo.toml:

[package]
name = "my-backend"
version = "0.1.0"
edition = "2021"

[dependencies]
axum = "0.7"
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.12", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tower-http = { version = "0.5", features = ["cors"] }

src/main.rs:

use axum::{routing::get, Json, Router};
use tower_http::cors::CorsLayer;

async fn health() -> Json<serde_json::Value> {
    Json(serde_json::json!({
        "status": "ok"
    }))
}

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/api/health", get(health))
        .layer(CorsLayer::permissive());

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3001")
        .await
        .unwrap();

    println!("Server running on http://localhost:3001");
    axum::serve(listener, app).await.unwrap();
}

Beberapa hal penting di sini:

CorsLayer::permissive() mengizinkan request dari domain lain saat development tokio::net::TcpListener adalah async TCP listener dari Tokio axum::serve mengikat listener ke router

Menambahkan Endpoint API

Kita tambahkan endpoint yang mengambil data dari API eksternal dan meneruskannya ke frontend:

use axum::extract::Query;
use axum::http::StatusCode;
use serde::Deserialize;

#[derive(Deserialize)]
struct FilterParams {
    tag: Option<String>,
}

async fn list_items(
    Query(params): Query<FilterParams>,
) -> Result<Json<serde_json::Value>, StatusCode> {
    let mut url = "https://api.example.com/items".to_string();

    if let Some(tag) = &params.tag {
        url.push_str(&format!("?tag={}", tag));
    }

    match reqwest::get(&url).await {
        Ok(resp) => match resp.json::<serde_json::Value>().await {
            Ok(data) => Ok(Json(data)),
            Err(_) => Err(StatusCode::BAD_GATEWAY),
        },
        Err(_) => Err(StatusCode::BAD_GATEWAY),
    }
}

Pola ini disebut proxy pattern. Backend Rust menjadi perantara antara frontend dan API eksternal. Keuntungannya:

Bisa menambahkan caching di backend Bisa menyimpan API key secara rahasia Bisa melakukan transformasi data sebelum dikirim ke frontend Bisa menambahkan rate limiting

Daftarkan route-nya:

let app = Router::new()
    .route("/api/health", get(health))
    .route("/api/items", get(list_items))
    .layer(CorsLayer::permissive());
    

Membangun Frontend dengan Vue 3 + Vite

Buat project Vue dengan Vite:

npm create vite@latest frontend -- --template vue
cd frontend
npm install axios

Konfigurasi Vite agar mem-proxy request API ke backend Rust:

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  server: {
    port: 5173,
    proxy: {
      '/api': {
        target: 'http://localhost:3001',
        changeOrigin: true,
      }
    }
  }
})

Proxy ini sangat penting. Tanpa proxy, browser akan memblokir request karena CORS policy. Dengan proxy, request dari Vue akan diteruskan ke Rust seolah-olah berasal dari domain yang sama.

Menghubungkan Vue dengan API

Buat komponen Vue yang mengambil data dari backend:

<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'

const items = ref([])
const loading = ref(true)
const error = ref(null)

async function fetchItems() {
  try {
    const { data } = await axios.get('/api/items')
    items.value = data
  } catch (err) {
    error.value = 'Gagal memuat data'
  } finally {
    loading.value = false
  }
}

onMounted(fetchItems)
</script>

<template>
  <div v-if="loading">Memuat...</div>
  <div v-else-if="error">{{ error }}</div>
  <div v-else>
    <div v-for="item in items" :key="item.id">
      {{ item.nama }}
    </div>
  </div>
</template>

Axios secara otomatis mengirim request ke /api/items yang akan di-proxy oleh Vite ke http://localhost:3001/api/items.

Alur Data Lengkap

1. User buka http://localhost:5173
2. Vue mounted, panggil axios.get('/api/items')
3. Vite proxy teruskan ke http://localhost:3001/api/items
4. Axum handler terima request
5. Axum fetch data dari API eksternal
6. API eksternal kembalikan JSON
7. Axum teruskan JSON ke Vue
8. Vue render data ke HTML

Setiap langkah di atas berjalan secara async. Tidak ada thread yang diblokir, baik di backend Rust maupun frontend Vue.

Struktur Project Final

my-app/
├── backend/
│   ├── Cargo.toml
│   └── src/
│       └── main.rs
├── frontend/
│   ├── index.html
│   ├── package.json
│   ├── vite.config.js
│   └── src/
│       ├── main.js
│       ├── App.vue
│       └── components/
│           └── ItemList.vue
└── README.md

Menjalankan Aplikasi

Butuh dua terminal:

# Terminal 1 — Backend
cd backend
cargo run

# Terminal 2 — Frontend
cd frontend
npm install
npm run dev

Buka http://localhost:5173 di browser.

Tips Production

Saat deploy ke production, ada beberapa hal yang perlu diperhatikan.

Build frontend:

cd frontend
npm run build

Hasilnya ada di frontend/dist/. Bisa di-serve oleh Nginx, Cloudflare Pages, atau Vercel.

Build backend:

cd backend
cargo build --release

Binary hasil build ada di backend/target/release/. Ukurannya kecil dan tidak butuh runtime tambahan.

Reverse proxy dengan Nginx:

server {
    listen 80;
    server_name example.com;

    location / {
        root /var/www/frontend/dist;
        try_files $uri /index.html;
    }

    location /api/ {
        proxy_pass http://localhost:3001;
    }
}

Atau gunakan Docker untuk mengemas keduanya dalam satu container.

Kesimpulan

Rust dan Vue adalah kombinasi yang solid untuk full stack development. Rust menangani backend dengan performa tinggi dan keamanan memori, sementara Vue menyediakan frontend yang reaktif dan cepat dikembangkan. Proxy di Vite mempermudah integrasi keduanya selama development.

Project buku-doa adalah contoh nyata dari arsitektur ini. Backend Rust memproxy API publik, frontend Vue menampilkannya dengan UI yang bersih. Kamu bisa mengembangkan pola ini untuk berbagai jenis aplikasi.

Repository contoh: github.com/erlk1m/buku-doa

~Erlkim

Komentar

0/2000