Workers RPC は、互いを信頼しない Workers 同士でも安全に通信できるようにするための仕組みです。RPC セッションの一方が、相手側の任意のオブジェクトにアクセスしたり、任意のコードを実行したりすることはできません。各側が呼び出せるのは、以前の呼び出しで明示的に stub を受け取ったオブジェクトと関数だけです。
このセキュリティモデルは、一般にオブジェクト能力(Object Capabilities)、または能力ベースセキュリティ(Capability-Based Security)と呼ばれます。Workers RPC は Cap'n Proto RPC ↗ の上に構築され、Cap'n Proto RPC は分散プログラミング言語 E ↗ で使われるオブジェクト転送プロトコル CapTP に基づいています。
クラスの プライベートプロパティ ↗ は、RPC 経由では直接公開されません。
アロー関数式はクラスの prototype ではなくインスタンス上に定義されるため、RPC 経由では公開されません。WorkerEntrypoint クラスのメソッドとしては使わないでください ↗。
import { WorkerEntrypoint } from "cloudflare:workers";
export default class extends WorkerEntrypoint {
// add() is exposed over RPC.
add(a, b) {
return a + b;
}
// subtract() is NOT exposed over RPC.
subtract = (a, b) => a - b;
}アプリケーション定義クラスのインスタンスを送ると、受信側がアクセスできるのはクラスに宣言されたメソッドとプロパティだけです。インスタンスのプロパティにはアクセスできません。たとえば次のとおりです。
class Foo extends RpcTarget {
constructor() {
super();
// i CANNOT be accessed over RPC
this.i = 0;
// funcProp CANNOT be called over RPC
this.funcProp = () => {}
}
// value CAN be accessed over RPC
get value() {
return this.i;
}
// method CAN be called over RPC
method() {}
}この動作は意図的です。クラス内部の非公開情報を誤って公開しないようにするためです。一般に、インスタンスプロパティは # を接頭辞にして ↗ プライベート宣言します。ただし、プライベートプロパティは比較的新しい JavaScript の機能で、エコシステムではまだ広く使われていません。
2 つの Workers 間の RPC インターフェイスはセキュリティ境界になり得るため、慎重に扱います。RPC で Workers 間通信する場合、インスタンスプロパティは # 接頭辞の有無にかかわらず常に非公開です。プロパティを公開したい場合は、上の例のようにクラスレベルで明示的な getter を宣言できます。
これらの可視性ルールは、RpcTarget、WorkerEntrypoint、DurableObject を継承するオブジェクトにだけ適用され、プレーンオブジェクトには適用されません。プレーンオブジェクトは「値渡し」され、すべての own プロパティが送られます。
関数を RPC 経由で渡すと、呼び出し側は関数オブジェクト自身の own プロパティにアクセスできます。
someRpcMethod() {
let func = () => {};
func.prop = 123; // `prop` is visible over RPC
return func;
}関数上のこうしたプロパティは、RpcTarget のクラスプロパティと同様に非同期でアクセスされます。ただし、上の RpcTarget の例とは異なり、関数のインスタンスプロパティは呼び出し側からアクセスできます。実務では、関数にプロパティを付けることはほとんどありません。