Action Cable dan WebSockets di Rails: Panduan Lengkap untuk Wawancara Teknis
Panduan lengkap Action Cable dan WebSockets di Rails untuk persiapan wawancara teknis. Mencakup arsitektur, Solid Cable, Turbo Streams, dan pola scaling.

Komunikasi real-time telah menjadi fitur yang sangat penting dalam aplikasi web modern. Mulai dari fitur chat, notifikasi langsung, hingga pembaruan dashboard secara otomatis, pengguna mengharapkan pengalaman yang responsif tanpa perlu memuat ulang halaman. Action Cable, yang merupakan framework bawaan Rails untuk WebSockets, menyediakan solusi terintegrasi yang memungkinkan pengembang membangun fitur-fitur tersebut dengan mengikuti konvensi Rails yang sudah familiar.
Action Cable menjembatani komunikasi WebSocket dengan arsitektur Rails yang sudah ada, sehingga memungkinkan pengembangan fitur real-time menggunakan pola yang konsisten dengan bagian aplikasi Rails lainnya. Rails 8 memperkenalkan Solid Cable, adapter berbasis database yang mengeliminasi kebutuhan akan Redis untuk pub/sub messaging.
Dasar-Dasar Protokol WebSocket
Protokol WebSocket menyediakan saluran komunikasi full-duplex melalui koneksi TCP tunggal. Berbeda dengan model request-response tradisional HTTP, WebSocket mempertahankan koneksi persisten yang memungkinkan server dan klien untuk saling mengirim data kapan saja. Proses ini dimulai dengan HTTP handshake yang kemudian di-upgrade menjadi koneksi WebSocket.
Perbedaan mendasar antara HTTP dan WebSocket terletak pada sifat koneksinya. HTTP bersifat stateless dan unidirectional, di mana klien harus selalu menginisiasi request. Sebaliknya, WebSocket bersifat stateful dan bidirectional, memungkinkan komunikasi dua arah secara simultan. Karakteristik ini membuat WebSocket sangat cocok untuk aplikasi yang membutuhkan pembaruan data secara real-time.
Dalam konteks Rails, Action Cable mengabstraksi kompleksitas manajemen koneksi WebSocket, sehingga pengembang dapat fokus pada logika bisnis aplikasi tanpa harus menangani detail teknis protokol secara langsung.
Arsitektur Action Cable
Action Cable terdiri dari tiga komponen utama: connections, channels, dan subscriptions. Pemahaman mendalam tentang ketiga komponen ini sangat penting untuk membangun fitur real-time yang robust dan scalable.
Connections
Connection merepresentasikan koneksi WebSocket individual antara klien dan server. Setiap connection dapat diidentifikasi berdasarkan pengguna yang terautentikasi, memungkinkan pengiriman pesan yang ditargetkan kepada pengguna tertentu.
# app/channels/application_cable/connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
private
def find_verified_user
# Cookies are available in WebSocket handshake
if verified_user = User.find_by(id: cookies.encrypted[:user_id])
verified_user
else
reject_unauthorized_connection
end
end
end
endKode di atas mendemonstrasikan bagaimana autentikasi ditangani pada level connection. Method find_verified_user mengakses cookies yang tersedia selama WebSocket handshake untuk memverifikasi identitas pengguna. Jika pengguna tidak terautentikasi, koneksi akan ditolak dengan reject_unauthorized_connection.
Channels
Channel berfungsi sebagai unit logis untuk mengorganisasi fitur real-time. Setiap channel menangani jenis komunikasi tertentu, seperti chat, notifikasi, atau pembaruan dashboard. Pendekatan ini mengikuti prinsip separation of concerns yang menjadi fondasi arsitektur Rails.
# app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
def subscribed
room = ChatRoom.find(params[:room_id])
# Authorization: verify user belongs to this room
if room.members.include?(current_user)
stream_for room
else
reject
end
end
def receive(data)
message = ChatMessage.create!(
room_id: params[:room_id],
user: current_user,
body: data["body"]
)
ChatChannel.broadcast_to(
message.room,
{ id: message.id, body: message.body, user: current_user.name }
)
end
def unsubscribed
# Cleanup: mark user as offline
AppearanceTracker.mark_offline(current_user)
end
endImplementasi ChatChannel di atas menunjukkan beberapa konsep penting. Method subscribed menangani otorisasi dengan memverifikasi bahwa pengguna merupakan anggota chat room. Method receive memproses pesan masuk dari klien dan melakukan broadcast ke semua subscriber. Method unsubscribed menjalankan cleanup logic ketika koneksi terputus.
Penggunaan stream_for dengan model object memungkinkan Action Cable untuk secara otomatis mengelola nama stream berdasarkan class dan ID model. Pola ini menyederhanakan manajemen stream dan mengurangi kemungkinan kesalahan dalam penamaan.
Subscriptions di Sisi Klien
Integrasi sisi klien menggunakan JavaScript untuk membuat dan mengelola subscriptions ke channels. Rails menyediakan consumer object yang menangani koneksi WebSocket dan menyediakan API untuk berinteraksi dengan server.
import consumer from "./consumer"
const chatChannel = consumer.subscriptions.create(
{ channel: "ChatChannel", room_id: roomId },
{
connected() {
// Called when the subscription is ready
console.log("Connected to chat room", roomId)
},
disconnected() {
// Called when the subscription is closed
console.log("Disconnected from chat room")
},
received(data) {
// Called when data is broadcast to the channel
const messageList = document.getElementById("messages")
messageList.insertAdjacentHTML("beforeend",
`<div class="message"><strong>${data.user}</strong>: ${data.body}</div>`
)
},
sendMessage(body) {
// Calls ChatChannel#receive on the server
this.perform("receive", { body: body })
}
}
)Kode JavaScript di atas mendemonstrasikan lifecycle lengkap subscription. Callback connected dipanggil ketika subscription berhasil dibuat, disconnected ketika koneksi terputus, dan received ketika data diterima dari server. Method sendMessage menunjukkan bagaimana klien dapat mengirim data ke server menggunakan this.perform.
Pola ini memisahkan concerns dengan jelas: server menangani logika bisnis dan persistensi data, sementara klien menangani rendering dan interaksi pengguna.
Siap menguasai wawancara Ruby on Rails Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
Solid Cable di Rails 8
Rails 8 memperkenalkan Solid Cable sebagai adapter default untuk Action Cable. Solid Cable menyimpan messages di database relasional menggunakan polling yang dioptimalkan, mengeliminasi kebutuhan akan Redis untuk banyak kasus penggunaan. Pendekatan ini menyederhanakan infrastruktur deployment tanpa mengorbankan performa secara signifikan untuk aplikasi skala kecil hingga menengah.
# config/cable.yml (Rails 8 default)
development:
adapter: solid_cable
production:
adapter: solid_cable
connects_to:
database:
writing: cable
polling_interval: 0.1.seconds
message_retention: 1.dayKonfigurasi di atas menunjukkan setup Solid Cable untuk development dan production. Perhatikan penggunaan connects_to yang memungkinkan Solid Cable menggunakan database terpisah untuk operasi cable, mencegah interferensi dengan database utama aplikasi.
# config/database.yml (Rails 8 multi-database)
production:
primary:
<<: *default
database: myapp_production
cable:
<<: *default
database: myapp_cable_production
migrations_paths: db/cable_migrateKonfigurasi multi-database ini memisahkan storage untuk cable messages dari database utama. Pemisahan ini memberikan beberapa keuntungan: mengurangi beban pada database utama, memungkinkan scaling independen, dan menyederhanakan manajemen retensi data untuk messages yang bersifat ephemeral.
Solid Cable cocok untuk aplikasi dengan ratusan hingga ribuan koneksi simultan. Untuk aplikasi dengan skala yang lebih besar, Redis tetap menjadi pilihan yang direkomendasikan karena karakteristik performa yang lebih superior untuk operasi pub/sub.
Pola Broadcasting
Broadcasting merupakan mekanisme untuk mengirim data dari server ke semua subscribers yang relevan. Rails menyediakan beberapa pola untuk melakukan broadcast, masing-masing dengan trade-offs tersendiri.
# Broadcasting from a model callback
class Notification < ApplicationRecord
belongs_to :user
after_create_commit :broadcast_to_user
private
def broadcast_to_user
ActionCable.server.broadcast(
"notifications_#{user_id}",
{ id: id, title: title, read: false }
)
end
end
# Broadcasting from a background job
class DashboardUpdateJob < ApplicationJob
queue_as :default
def perform(dashboard_id)
dashboard = Dashboard.find(dashboard_id)
stats = dashboard.compute_stats
ActionCable.server.broadcast(
"dashboard_#{dashboard_id}",
{ stats: stats, updated_at: Time.current.iso8601 }
)
end
endKedua pola di atas mendemonstrasikan pendekatan yang berbeda untuk broadcasting. Model callback cocok untuk broadcast yang langsung terkait dengan perubahan data, memastikan konsistensi antara state database dan notifikasi real-time. Background job lebih tepat untuk operasi yang membutuhkan komputasi intensif atau tidak perlu blocking.
Penggunaan after_create_commit alih-alih after_create sangat penting untuk memastikan bahwa broadcast hanya terjadi setelah transaksi database berhasil di-commit. Pola ini mencegah race condition di mana klien menerima notifikasi tentang data yang belum tersedia di database.
Integrasi Turbo Streams
Turbo Streams, bagian dari Hotwire, menyediakan abstraksi tingkat tinggi untuk broadcasting DOM updates. Integrasi ini memungkinkan pengembang untuk membangun fitur real-time dengan kode minimal, mengikuti prinsip convention over configuration.
# app/models/message.rb
class Message < ApplicationRecord
belongs_to :chat_room
# Automatically broadcasts append to subscribers
broadcasts_to :chat_room
end
# app/views/chat_rooms/show.html.erb
<%= turbo_stream_from @chat_room %>
<div id="messages">
<%= render @chat_room.messages %>
</div>Dengan broadcasts_to, Rails secara otomatis melakukan broadcast Turbo Stream frames ketika model dibuat, diupdate, atau dihapus. Helper turbo_stream_from di view membuat subscription ke channel yang sesuai dan menangani rendering updates secara otomatis.
Pendekatan deklaratif ini secara signifikan mengurangi boilerplate code. Pengembang tidak perlu menulis JavaScript untuk handling DOM updates atau mendefinisikan channel classes untuk kasus penggunaan standar. Namun, untuk kebutuhan yang lebih kompleks, pendekatan manual tetap tersedia dan dapat dikombinasikan dengan Turbo Streams.
Scaling di Production
Untuk aplikasi dengan traffic tinggi, arsitektur Action Cable perlu dipertimbangkan dengan cermat. Setiap koneksi WebSocket mempertahankan state di server, yang berbeda dari model stateless HTTP tradisional.
# config/cable.yml — Redis adapter for high-scale production
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: myapp_productionRedis adapter merupakan pilihan standar untuk production deployment dengan skala besar. Redis menyediakan pub/sub yang efisien dengan latency rendah, memungkinkan multiple Rails processes atau servers untuk berbagi channel subscriptions.
Beberapa pertimbangan penting untuk scaling Action Cable meliputi pengelolaan connection pooling, implementasi health checks untuk WebSocket connections, dan strategi reconnection yang robust di sisi klien. Penggunaan load balancer yang mendukung WebSocket connections juga merupakan keharusan, dengan sticky sessions sebagai pendekatan yang umum digunakan.
Monitoring merupakan aspek kritis dalam production deployment. Metrik seperti jumlah koneksi aktif, message throughput, dan latency perlu dipantau untuk mengidentifikasi bottlenecks dan merencanakan capacity planning.
Dalam wawancara teknis, pemahaman tentang trade-offs antara Solid Cable dan Redis, serta kemampuan untuk menjelaskan strategi scaling, menunjukkan pengetahuan yang mendalam tentang sistem production.
Testing Channels
Rails menyediakan testing framework yang komprehensif untuk Action Cable channels. Testing memastikan bahwa authorization logic, broadcast behavior, dan subscription lifecycle berfungsi sesuai ekspektasi.
# test/channels/chat_channel_test.rb
require "test_helper"
class ChatChannelTest < ActionCable::Channel::TestCase
test "subscribes to a valid room" do
room = chat_rooms(:general)
user = users(:alice)
stub_connection current_user: user
subscribe room_id: room.id
assert subscription.confirmed?
assert_has_stream_for room
end
test "rejects subscription for unauthorized user" do
room = chat_rooms(:private)
user = users(:outsider)
stub_connection current_user: user
subscribe room_id: room.id
assert subscription.rejected?
end
test "broadcasts messages to room subscribers" do
room = chat_rooms(:general)
stub_connection current_user: users(:alice)
subscribe room_id: room.id
assert_broadcast_on(room, hash_including(body: "Hello")) do
perform :receive, body: "Hello"
end
end
endTest cases di atas mencakup tiga skenario penting: subscription yang valid, rejection untuk unauthorized user, dan verifikasi broadcast behavior. Helper stub_connection memungkinkan setup connection state tanpa actual WebSocket connection. Assertion seperti assert_has_stream_for dan assert_broadcast_on menyediakan cara ekspresif untuk memverifikasi behavior.
Testing channel behavior secara terpisah dari integration tests memungkinkan feedback loop yang lebih cepat selama development dan membantu mengidentifikasi regressions dengan lebih presisi.
Pertanyaan Wawancara Umum
Beberapa pertanyaan yang sering muncul dalam wawancara teknis terkait Action Cable dan WebSockets meliputi penjelasan perbedaan antara HTTP polling, long polling, Server-Sent Events, dan WebSockets. Kandidat diharapkan dapat menjelaskan bagaimana Action Cable menangani autentikasi dan otorisasi pada koneksi WebSocket, serta mendeskripsikan arsitektur internal Action Cable termasuk connections, channels, dan subscriptions.
Bagaimana Action Cable mengautentikasi koneksi? Autentikasi terjadi di ApplicationCable::Connection#connect selama WebSocket handshake. Cookies dari HTTP session tersedia pada tahap ini. Autentikasi berbasis token dapat dilakukan dengan mengirim token sebagai query parameter pada URL WebSocket.
Apa yang terjadi ketika koneksi WebSocket terputus? Library klien Action Cable mengimplementasikan reconnection otomatis dengan exponential backoff. Di sisi server, callback unsubscribed dipanggil untuk setiap channel yang disubscribe oleh koneksi tersebut.
Kapan sebaiknya menggunakan Solid Cable dibanding Redis? Solid Cable cocok untuk aplikasi dengan kebutuhan real-time moderat (di bawah 100 pesan per detik) yang ingin menghindari infrastruktur Redis tambahan. Redis tetap diperlukan untuk skenario high-throughput atau ketika latency di bawah 10ms menjadi keharusan.
Menempatkan logika otorisasi di connection class alih-alih di channel individual merupakan kesalahan umum. Connection menangani autentikasi identitas (siapa pengguna ini?). Channel menangani otorisasi akses (apakah pengguna ini berhak mengakses room ini?). Mencampurkan tanggung jawab ini dapat menimbulkan celah keamanan.
Kesimpulan
- WebSocket menyediakan komunikasi full-duplex yang berbeda dari model request-response HTTP tradisional
- Action Cable terdiri dari tiga komponen utama: connections untuk autentikasi, channels untuk logika bisnis, dan subscriptions untuk manajemen client-side
- Rails 8 memperkenalkan Solid Cable sebagai alternatif Redis yang lebih sederhana untuk deployment skala kecil hingga menengah
- Turbo Streams menyediakan abstraksi deklaratif untuk broadcasting DOM updates dengan boilerplate minimal
- Testing channel behavior secara terpisah memungkinkan verifikasi authorization dan broadcast logic yang lebih presisi
- Scaling membutuhkan pertimbangan tentang adapter choice, connection management, dan monitoring
- Latih pertanyaan wawancara Action Cable & WebSockets untuk memperkuat pemahaman konsep-konsep ini
Mulai berlatih!
Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.
Tag
Bagikan
Artikel terkait

Rails API Mode di 2026: RESTful API, Serialisasi JSON, dan Pertanyaan Interview
Panduan lengkap Rails 8 API Mode: rute RESTful, serialisasi Alba dan jsonapi-serializer, autentikasi JWT, error handling, dan RSpec.

Solid Queue dan Solid Cache di Rails 8: Panduan Lengkap untuk Persiapan Interview Teknis 2026
Pembahasan mendalam tentang Solid Queue dan Solid Cache sebagai komponen default berbasis database di Rails 8. Meliputi arsitektur, konfigurasi, kontrol concurrency, mekanisme caching, serta pertanyaan interview teknis yang sering diajukan di tahun 2026.

Ruby on Rails 8: Fitur Baru dan Panduan Migrasi Lengkap 2026
Rails 8 memperkenalkan Solid Trifecta, autentikasi bawaan, Kamal 2, dan Propshaft. Panduan lengkap dengan contoh kode serta langkah migrasi dari Rails 7.