Mengenal API RSC: Arsitektur React Server Components dan Kodenya

API RSC (React Server Components API) adalah arsitektur rendering modern pada ekosistem React (React 19 dan Next.js App Router) yang mengeksekusi komponen secara eksklusif di sisi server dan mentransmisikannya ke peramban dalam format serialisasi biner/teks terstruktur yang disebut RSC Flight Payload. Berbeda dari REST API tradisional yang mengirimkan objek JSON murni mentah, API RSC mentransmisikan representasi pohon virtual DOM komponen yang sudah terisi data tanpa menyertakan dependensi JavaScript server ke dalam bundle klien.

Catatan Kontekstual: Jika pencarian Anda berkaitan dengan industri perminyakan dan pemboran mekanikal, istilah API RSC merujuk pada API Rotary Shouldered Connection (standar ulir pipa bor sesuai API Spec 7-1 / 7-2). Namun, dalam lanskap pemrograman dan rekayasa perangkat lunak web modern, kueri ini merujuk langsung ke React Server Components.

Mekanisme Kerja dan Struktur RSC Wire Payload

Saat peramban meminta halaman atau navigasi transisi pada arsitektur berbasis RSC, alur pemrosesan data berlangsung dalam tiga fase utama:

  1. Server Execution: Server mengeksekusi fungsi komponen secara langsung (asinkron). Komponen ini memiliki akses langsung ke basis data, sistem berkas (file system), atau microservice internal tanpa mengekspos kredensial ke publik.
  2. Serialization (Flight Protocol): React mengubah pohon elemen server menjadi representasi serializable. Komponen klien (yang ditandai dengan direktif "use client") direferensikan sebagai client reference berupa tautan berkas skrip dan properti props pendukung.
  3. Client Reconciliation: Klien mengunduh stream payload tersebut lalu menyisipkannya langsung ke dalam DOM tanpa menghancurkan state klien yang sedang berjalan (zero root re-render).

Format payload RSC yang dikirimkan melalui HTTP header stream biasanya berbentuk baris-baris instruksi serial seperti contoh berikut:

M1:{"id":"./src/components/UserCard.client.js","chunks":["client-chunk"],"name":"UserCard"}
J0:["$","div",null,{"className":"container","children":["$","@1",null,{"userId":"usr_9981","name":"Budi Pratama"}]}]

Matriks Komparasi: RSC vs Client Component vs Route Handler (REST)

Memahami batasan fungsional setiap komponen penting untuk menentukan arsitektur penulisan kode yang efisien dan hemat bandwidth klien.

Parameter Evaluasi React Server Component (RSC) Client Component ("use client") Route Handler / REST API
Lingkungan Eksekusi Server murni (Node.js / Edge Runtime) Klien & Server (Pre-render SSR + Hydrate) Server murni (HTTP Endpoint)
Dampak Ukuran JS Bundle 0 KB (Nol dependensi dikirim ke klien) Sesuai ukuran library/dependensi komponen 0 KB (Hanya mengembalikan raw response)
Format Output RSC Flight Payload (Serialized UI Tree) HTML interaktif + Virtual DOM Hydration JSON, Blob, Buffer, atau Plain Text
Akses Database / Secrets Ya, langsung dan aman tanpa perantara Dilarang keras (berisiko kebocoran data) Ya, melalui query handler
Reaktivitas Browser (State/Effect) Tidak didukung (tanpa useState / useEffect) Didukung penuh (interaksi, event listener) Tidak ada komponen UI

Pola Implementasi Kode Menggunakan API RSC

Berikut adalah pola baku arsitektur RSC pada Next.js App Router (React 19). Server Component bertindak sebagai pengambil data langsung dan mendistribusikan data serializable ke Client Component.

1. Server Component Pengambil Data (app/dashboard/page.tsx)

// Komponen ini berjalan 100% di Server tanpa direktif "use client"
import { Suspense } from 'react';
import AnalyticsChart from './AnalyticsChart'; // Client Component

interface MetricData {
  id: string;
  metricName: string;
  value: number;
}

async function fetchMetrics(): Promise<MetricData[]> {
  // Akses direct DB atau internal endpoint dengan fetch ter-cache otomatis
  const res = await fetch('https://api.internal.local/v1/metrics', {
    headers: {
      Authorization: `Bearer ${process.env.INTERNAL_SERVICE_TOKEN}`,
    },
    next: { revalidate: 60 } // Revalidasi ISR setiap 60 detik
  });

  if (!res.ok) {
    throw new Error('Gagal memuat data telemetri.');
  }

  return res.json();
}

export default async function DashboardPage() {
  const metrics = await fetchMetrics();

  return (
    <main style={{ padding: '24px', fontFamily: 'sans-serif' }}>
      <h1>Panel Analitik Sistem</h1>
      <p>Data dirender secara statis di server via RSC.</p>
      
      <Suspense fallback={<p>Memuat grafik interaktif...</p>}>
        <AnalyticsChart initialData={metrics} />
      </Suspense>
    </main>
  );
}

2. Client Component Interaktif (app/dashboard/AnalyticsChart.tsx)

'use client';

import { useState } from 'react';

interface MetricData {
  id: string;
  metricName: string;
  value: number;
}

export default function AnalyticsChart({ initialData }: { initialData: MetricData[] }) {
  const [data, setData] = useState<MetricData[]>(initialData);
  const [filter, setFilter] = useState<string>('');

  const filteredData = data.filter((item) =>
    item.metricName.toLowerCase().includes(filter.toLowerCase())
  );

  return (
    <div style={{ border: '1px solid #ccc', padding: '16px', borderRadius: '8px' }}>
      <input
        type="text"
        placeholder="Filter metrik..."
        value={filter}
        onChange={(e) => setFilter(e.target.value)}
        style={{ padding: '8px', marginBottom: '12px', width: '100%', boxSizing: 'border-box' }}
      />
      <ul>
        {filteredData.map((item) => (
          <li key={item.id}>
            <strong>{item.metricName}:</strong> {item.value}
          </li>
        ))}
      </ul>
    </div>
  );
}

Aturan Batasan Serialisasi Data (Data Serialization Boundaries)

Komunikasi antara Server Component ke Client Component melalui API RSC memiliki aturan ketat terkait tipe data yang diizinkan melintasi batas jaringan (wire boundary):

  • Tipe Data Valid: Primitive (string, number, boolean, null, undefined), Array, Plain Object, Date (terkonversi otomatis pada versi modern), Map, Set, TypedArray, dan Promise serializable.
  • Tipe Data Dilarang: Functions, Class instances (metode proto akan hilang), Symbol non-global, dan rekursi objek melingkar (circular references).
  • Solusi Mutasi Data: Jika membutuhkan interaksi pemanggilan fungsi dari klien ke server, gunakan paradigma Server Actions (fungsi bertanda "use server"), bukan mempassing fungsi referensi biasa sebagai props.