Sistem RPC baru untuk browser dan server web: Cap'n Web
(blog.cloudflare.com)- Cap'n Web adalah protokol RPC baru yang diimplementasikan dengan TypeScript, dioptimalkan untuk lingkungan web dan berjalan di berbagai runtime JavaScript
- Tanpa skema atau boilerplate yang merepotkan, ia menyediakan serialisasi berbasis JSON serta format data yang mudah dibaca manusia
- Melalui model berbasis object-capability, dimungkinkan pemanggilan dua arah, pengiriman referensi fungsi·objek, promise pipelining, dan implementasi pola keamanan
- Mendukung berbagai lingkungan jaringan seperti WebSocket, HTTP, postMessage, serta merupakan open source ringan berukuran di bawah 10kB
- Selain menyelesaikan masalah waterfall yang mirip dengan GraphQL, ia juga memungkinkan pemodelan RPC yang alami seperti API JavaScript biasa
Apa itu Cap'n Web
- Cap'n Web adalah sistem RPC open source berbasis TypeScript yang dikembangkan oleh Cloudflare
- Terinspirasi oleh Cap'n Proto, tetapi bekerja tanpa definisi skema terpisah dan mengadopsi metode serialisasi yang ramah manusia dengan memanfaatkan JSON
- Terintegrasi dengan TypeScript untuk meningkatkan pengalaman developer seperti autocomplete dan type checking, sementara validasi tipe saat runtime dapat ditangani secara terpisah (misalnya dengan type guard)
- Mendukung protokol jaringan seperti HTTP, WebSocket, dan postMessage, serta berjalan di browser utama, Cloudflare Workers, Node.js, dan lainnya
- Dengan struktur ringan tanpa dependensi, ukurannya kurang dari 10kB setelah minify + gzip
Model berbasis object-capability (OCap) di Cap'n Web
- Mengadopsi model berbasis object-capability, sehingga mampu mengekspresikan lebih banyak hal dibanding sistem RPC tradisional
- Pemanggilan dua arah: klien dan server dapat saling memanggil fungsi
- Pengiriman referensi fungsi·objek: ketika fungsi atau objek dikirim lewat RPC, pihak lawan menerima stub dan eksekusi terjadi di sisi asal saat dipanggil
- Promise Pipelining: saat beberapa RPC dirangkai dalam chain, semuanya dapat diproses dalam satu round trip jaringan
- Pola keamanan: kontrol keamanan seperti otorisasi dan manajemen sesi dapat diimplementasikan secara alami
Cara penggunaan dasar
-
Contoh klien
import { newWebSocketRpcSession } from "capnweb" let api = newWebSocketRpcSession("wss://example.com/api") let result = await api.hello("World") console.log(result) -
Contoh server (berbasis Cloudflare Worker)
import { RpcTarget, newWorkersRpcResponse } from "capnweb" class MyApiServer extends RpcTarget { hello(name) { return `Hello, ${name}!` } } export default { fetch(request, env, ctx) { let url = new URL(request.url) if (url.pathname === "/api") { return newWorkersRpcResponse(request, new MyApiServer()) } return new Response("Not found", {status: 404}) } } -
Menambahkan method ke API, mengirim fungsi callback dari klien, serta mendefinisikan dan menerapkan interface TypeScript dapat dilakukan dengan mudah
Apa itu RPC dan karakteristiknya di Cap'n Web
- RPC (Remote Procedure Call) adalah konsep yang memungkinkan dua program di jaringan berkomunikasi seolah-olah sedang melakukan pemanggilan fungsi
- Berbeda dari protokol HTTP/REST tradisional, RPC menggunakan abstraksi pemanggilan fungsi sehingga memungkinkan penulisan kode yang selaras dengan cara berpikir developer
- Cap'n Web sangat cocok dengan alur JavaScript modern, termasuk dukungan async/await, Promise, dan Exception
- Berbeda dari kontroversi historis RPC (pemanggilan sinkron, error jaringan), di lingkungan JS modern ia bisa digunakan dengan lebih aman dan efisien
Skenario penggunaan Cap'n Web
- Cocok untuk semua lingkungan yang membutuhkan komunikasi jaringan antar dua aplikasi JavaScript
- Seperti klien-server, pemanggilan antar-microservice, dan lain-lain
- Sangat cocok khususnya untuk web app kolaborasi real-time dan interaksi yang melintasi batas keamanan yang kompleks
- Masih berada pada tahap eksperimental, sehingga lebih bermanfaat bagi developer yang terbuka pada adopsi teknologi terbaru
Berbagai fitur
Mode batch HTTP
-
Saat koneksi persisten tidak diperlukan, beberapa pemanggilan RPC dapat digabung dan diproses sekaligus dengan mode batch HTTP
import { newHttpBatchRpcSession } from "capnweb" let batch = newHttpBatchRpcSession("https://example.com/api") let result = await batch.hello("World") console.log(result) -
Dalam satu batch, beberapa pemanggilan dapat dijalankan bersamaan dan hasilnya diterima secara paralel
let promise1 = batch.hello("Alice") let promise2 = batch.hello("Bob") let [result1, result2] = await Promise.all([promise1, promise2])
Promise Pipelining (pemanggilan berantai)
-
Mendukung cara menggunakan hasil panggilan sebelumnya langsung sebagai argumen untuk panggilan berikutnya tanpa menunggu hasil sebelumnya selesai
-
Contoh) Promise hasil
getMyName()langsung diberikan kehello()sehingga diproses dalam satu round trip jaringanlet namePromise = batch.getMyName() let result = await batch.hello(namePromise) -
Promise di Cap'n Web bekerja sebagai objek proxy, sehingga pemanggilan method tambahan dapat dirangkai tanpa penundaan
let sessionPromise = batch.authenticate(apiKey) let name = await sessionPromise.whoami()
Keamanan: autentikasi dan object-capability
- Melalui method authenticate, objek hak akses (sesi) diberikan saat berhasil, dan setelah itu fitur dapat dipanggil tanpa tahap autentikasi tambahan
- Berbeda dari RPC tradisional, objek sesi tidak dapat dipalsukan, dan method yang membutuhkan hak akses tidak bisa diakses tanpa autentikasi
- Secara alami mengatasi keterbatasan struktural WebSocket dan menjaga konsistensi logika autentikasi
- Saat mendeklarasikan interface API dengan TypeScript, penerapannya bisa otomatis ke sisi klien~server, sambil memperoleh autocomplete dan type safety
Perbandingan dengan GraphQL dan pembeda Cap'n Web
-
GraphQL meredakan masalah waterfall bertingkat pada REST, tetapi memerlukan pengenalan bahasa, skema, dan toolchain baru
-
Cap'n Web menyelesaikan masalah waterfall hanya dengan kode JavaScript,
- Dengan dukungan promise pipelining/referensi objek, pemanggilan bertingkat maupun logika transaksi kompleks dapat dimodelkan secara alami
let user = api.createUser({ name: "Alice" }) let friendRequest = await user.sendFriendRequest("Bob") -
Dapat digunakan mirip API JavaScript tanpa kompleksitas serta biaya belajar·pengelolaan ala GraphQL
Operasi array (array.map dan sebagainya) serta optimisasi
-
Di Cap'n Web, operasi map pada setiap elemen array dapat dilakukan tanpa round trip jaringan tambahan
-
Fungsi callback map dijalankan sekali di klien untuk merekam isi operasinya (record-replay), lalu dikirim ke server agar diproses secara massal di sisi server
let friendsWithPhotos = friendsPromise.map(friend => { return {friend, photo: api.getUserPhoto(friend.id)} }) let results = await friendsWithPhotos -
Melalui bahasa spesifik domain (DSL) yang terbatas, ekspresinya tetap seperti fungsi JavaScript, tetapi di balik layar Cap'n Web mengoptimalkan banyak pemanggilan lewat protokolnya
Struktur protokol internal dan alur komunikasi
- Mengirim data terstruktur melalui JSON + prapemrosesan khusus, dengan dukungan tipe khusus seperti array dan tanggal
- Sebagai protokol simetris, ia memungkinkan komunikasi dua arah tanpa pembedaan klien·server
- Setiap pihak (misalnya Alice dan Bob) mengelola tabel export/import dan membedakan referensi objek·fungsi dengan ID
- Melalui pesan push/pull dan alokasi Promise ID, banyak pemanggilan dapat direfleksikan dalam satu round trip
Status saat ini dan contoh penerapan
- Cap'n Web masih merupakan open source eksperimental, tetapi sudah digunakan dalam layanan nyata seperti remote bindings di Cloudflare Wrangler
- Direncanakan akan ada posting blog tambahan dan berbagai eksperimen frontend
- Dirilis dengan lisensi MIT, sehingga siapa pun dapat menggunakannya dengan bebas
- Langsung ke repositori GitHub
Belum ada komentar.