-
Cap'n Web은 TypeScript로 구현된 신규 RPC 프로토콜로, 웹 환경에 최적화되어 다양한 자바스크립트 런타임에서 동작함
- 스키마나 번거로운 보일러플레이트 없이, JSON 기반 직렬화 및 인간이 읽을 수 있는 데이터 포맷을 제공함
-
객체-권한 기반 모델을 통해 양방향 호출, 함수·객체 레퍼런스 전달, 약속(promise) 파이프라이닝, 보안 패턴 구현이 가능함
-
WebSocket, HTTP, postMessage 등 다양한 네트워크 환경을 지원하며, 10kB 이하의 경량 오픈소스임
-
GraphQL과 유사한 waterfall 문제 해결 뿐만 아니라, 일반 자바스크립트 API와 같은 자연스러운 RPC 모델링을 가능하게 해줌
Cap'n Web이란 무엇인가
-
Cap'n Web은 Cloudflare에서 개발된 TypeScript 기반 오픈소스 RPC(protocol) 시스템임
- Cap'n Proto에서 영감을 받았으나, 별도의 스키마 정의 없이 동작하고, JSON을 활용한 인간 친화적 직렬화 방식 채택
-
TypeScript와 통합되어 자동 완성, 타입 체크 등 개발자 경험을 향상시키며, 런타임 타입 검증은 별도(type guard 등)로 처리 가능
-
HTTP, WebSocket, postMessage 등 네트워크 프로토콜을 지원하며, 주요 브라우저·Cloudflare Workers·Node.js 등에서 동작
- 종속성 없는 경량 구조로 minify + gzip 시 10kB 미만으로 제공됨
Cap'n Web의 객체-권한 기반 모델(OCap)
-
객체-권한(object-capability) 기반 모델을 채택하여, 기존 RPC 시스템보다 더 다양한 표현 가능
-
양방향 호출: 클라이언트와 서버가 서로 함수를 호출 가능
-
함수·객체 레퍼런스 전달: 함수나 객체를 RPC로 넘기면, 상대방은 스텁을 받아 호출 시 원위치에서 실행함
-
Promise Pipelining: 여러 RPC를 체인으로 연결할 때 한 번의 네트워크 왕복으로 처리
-
보안 패턴: 권한 부여 및 세션 관리 등 보안적 제어를 자연스럽게 구현 가능
기본적인 사용법
-
클라이언트 예시
import { newWebSocketRpcSession } from "capnweb"
let api = newWebSocketRpcSession("wss://example.com/api"">wss://example.com/api")
let result = await api.hello("World")
console.log(result)
-
서버 예시(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})
}
}
-
API에 메소드 추가, 클라이언트의 콜백 함수 전달, TypeScript 인터페이스 정의 및 적용이 간단하게 가능함
RPC란 무엇이고, Cap'n Web에서의 특징
-
RPC(Remote Procedure Call) 는 네트워크 상의 두 프로그램이 마치 함수 호출처럼 통신할 수 있도록 해주는 개념임
- 전통적인 HTTP/REST 프로토콜과 달리, RPC는 함수 호출 추상화로 개발자의 사고방식과 일치하는 코드 작성 가능
- Cap'n Web은 async/await, Promise, Exception 지원 등 최신 자바스크립트의 흐름과 잘 맞음
- RPC의 역사적 논란(동기적 호출, 네트워크 오류)과 달리, 현대 JS 환경에서는 더욱 안전하고 효율적 사용이 가능함
Cap'n Web의 활용 시나리오
-
두 자바스크립트 애플리케이션 간 네트워크 통신이 필요한 모든 환경에서 활약
- 클라이언트-서버, 마이크로서비스 간 호출 등
- 특히 실시간 협업 웹앱, 복잡한 보안 경계를 넘는 상호작용에 적합함
- 실험적 단계로, 최신 기술 수용에 열려있는 개발자에게 더욱 유익함
다양한 기능
HTTP 배치 모드
-
지속적인 연결이 필요하지 않을 때 HTTP 배치(batch) 모드로 여러 RPC 호출을 한 번에 묶어서 처리 가능
import { newHttpBatchRpcSession } from "capnweb"
let batch = newHttpBatchRpcSession("https://example.com/api")
let result = await batch.hello("World")
console.log(result)
-
하나의 배치 내에서 여러 호출을 동시에 실행, 결과를 병렬로 받을 수 있음
let promise1 = batch.hello("Alice")
let promise2 = batch.hello("Bob")
let [result1, result2] = await Promise.all([promise1, promise2])
Promise Pipelining(체인 호출)
-
이전 호출의 결과를 기다리지 않고, 결과를 바로 다음 호출의 인자로 사용하는 방식 지원
-
예시) getMyName()의 결과 Promise를 바로 hello()에 넘겨 한 번의 네트워크 왕복으로 처리
let namePromise = batch.getMyName()
let result = await batch.hello(namePromise)
-
Cap'n Web의 Promise는 프록시(proxy) 객체로 동작하여, 추가 메소드 호출 시 지연 없이 체인 처리 가능
let sessionPromise = batch.authenticate(apiKey)
let name = await sessionPromise.whoami()
보안: 인증과 객체-권한
- 인증(authenticate) 메소드를 통해 성공시 권한(세션) 객체 할당, 이후 추가 인증 단계 없이 기능 호출 가능
- 기존 RPC와 달리 세션 객체를 위조할 수 없고, 인증 없이 권한이 필요한 메소드에 접근이 불가함
- WebSocket의 구조적 한계를 자연스럽게 극복, 인증 로직의 일관성 보장
- TypeScript로 API 인터페이스 선언 시, 클라이언트~서버에 자동으로 적용할 수 있으며, 자동완성 및 타입 안정성 확보
GraphQL과의 비교 및 Cap'n Web의 차별점
-
GraphQL은 REST의 waterfall(다단계 호출) 문제를 완화하지만, 새로운 언어·스키마·툴체인 도입이 필요함
-
Cap'n Web은 자바스크립트 코드만으로 waterfall 문제를 해결하며,
-
약속 파이프라이닝/객체 레퍼런스 지원으로, 중첩 호출이나 복합 트랜잭션 로직을 자연스럽게 모델링 가능
let user = api.createUser({ name: "Alice" })
let friendRequest = await user.sendFriendRequest("Bob")
-
GraphQL의 복잡성, 학습·관리 비용 없이, 자바스크립트 API와 유사하게 활용 가능
배열 연산(array.map 등)과 최적화
-
Cap'n Web에서는 배열의 각 원소에 대해 네트워크 추가 왕복 없이 map 연산 가능
-
map 콜백 함수를 클라이언트에서 한 번 실행해 연산 내용을 기록(record-replay), 서버로 전송하여 서버 측에서 일괄 처리
let friendsWithPhotos = friendsPromise.map(friend => {
return {friend, photo: api.getUserPhoto(friend.id)}
})
let results = await friendsWithPhotos
-
제한된 도메인 특화 언어(DSL)를 통해, 자바스크립트 함수처럼 표현하되, 실제로는 Cap'n Web 프로토콜을 활용해 다중 호출을 최적화 처리함
내부 프로토콜 구조 및 통신 흐름
-
JSON + 특별 전처리를 통한 구조화 데이터 전송, 배열·날짜 등 특별 타입 지원
- 대칭적 프로토콜로 클라이언트·서버 구분 없는 양방향 통신 가능
- 각 파티(예시: Alice와 Bob)는 export/import 테이블을 관리하며, 객체·함수 레퍼런스를 ID로 구분
- push/pull 메시지 및 Promise ID 할당 등을 통해, 한 번의 라운드 트립에 다수 호출 반영 가능
현황 및 적용 사례
-
Cap'n Web은 아직 실험적 오픈소스로, Cloudflare Wrangler의 remote bindings 등 실제 서비스에 활용 중
-
추가적인 블로그 포스팅과 다양한 프론트엔드 실험 예정
-
MIT 라이선스로 공개, 누구나 자유롭게 적용 가능
-
GitHub 저장소 바로가기