Live data from Hacker News

Cap'n Web: a new RPC system for browsers and web servers

blog.cloudflare.com

31–40 of 305 posts

Re: Cap'n Web: a new RPC system for browsers and web servers

#31

Really nice to have something I could potentially use across the whole app. I've been looking into things I can use over HTTP, websockets, and also over message channels to web workers. I've usually ended up implementing something that rounds to JSON-RPC (i.e. just use an `id` per request and response to tie them together). But this looks much sturdier. Building an operation description from the callback inside the `…

The .map() callback receives as its input an RpcPromise, not the actual value. You can't do any computation (including branching) on an RpcPromise, the only thing you can do is pipeline on it. Since the map callback must be synchronous, you can't await the promise either.

So it turns out it's actually not easy to mess up in a map callback. The main thing you have to avoid is side effects that modify stuff outside the callback. If you do that, the effect you'll see is those modifications only get applied once, rather than N times. And any stubs you exfiltrate from the callback simply won't work if called later.

Re: Cap'n Web: a new RPC system for browsers and web servers

#32
post #19

It's inspired by and created by a coauthor of [Cap'n Proto]( https://capnproto.org ), which is also what OCapN (referenced in a separate comment) name refers to. Cap'n Proto is inspired by ProtoBuf, protobuf has gRPC and gRPC web. We've been using ProtoBuf/gRPC/gRPC-web both in the backends and for public endpoints powering React / TS UI's, at my last startup. It worked great, particularly with the GCP Kubernetes inf…

Of course, all programming language APIs even in dynamic languages have some implied type (aka schema). You can't write code against an API without knowing what methods it provides, what their inputs and outputs are, etc. -- and that's a schema, whether or not it's actually written out as such.

But Cap'n Web itself does not need to know about any of that. Cap'n Web just accepts whatever method call you make, sends it to the other end of the connection, and attempts to deliver it. The protocol itself has no idea if your invocation is valid or not. That's what I mean by "schemaless" -- you don't need to tell Cap'n Web about any schemas.

With that said, I strongly recommend using TypeScript with Cap'n Web. As always, TypeScript schemas are used for build-time type checking, but are then erased before runtime. So Cap'n Web at runtime doesn't know anything about your TypeScript types.

Re: Cap'n Web: a new RPC system for browsers and web servers

#33
Looking at this quickly, it does seem to require (or strongly encourage?) a stateful server to hold on to the import and export tables and the state of objects in each.

One thing about a traditional RPC system where every call is top-level and you pass keys and such on every call is that multiple calls in a sequence can usually land on different servers and work fine.

Is there a way to serialize and store the import/export tables to a database so you can do the same here, or do you really need something like server affinity or Durable Objects?

Re: Cap'n Web: a new RPC system for browsers and web servers

#34

What would this look like for other language backends to support? Eg would be neat if Rust (my webservers) could support this on the backend edit : Downvoted, is this a bad question? The title is generically "web servers", obviously the content of the post focuses primarily on TypeScript, but i'm trying to determine if there's something unique about this that means it cannot be implemented in other languages. The ser…

I'm hoping the answer will be:

* Use Cap'n Proto in your Rust backend. This is what you want in a type-safe language like Rust: generated code based on a well-defined schema.

* We'll build some sort of proxy that, given a Cap'n Proto schema, converts between Cap'n Web and Cap'n Proto. So your frontend can speak Cap'n Web.

But this proxy is just an idea for now. No idea if or when it'll exist.

Re: Cap'n Web: a new RPC system for browsers and web servers

#35
post #31

Really nice to have something I could potentially use across the whole app. I've been looking into things I can use over HTTP, websockets, and also over message channels to web workers. I've usually ended up implementing something that rounds to JSON-RPC (i.e. just use an `id` per request and response to tie them together). But this looks much sturdier. Building an operation description from the callback inside the `…

The .map() callback receives as its input an RpcPromise, not the actual value. You can't do any computation (including branching) on an RpcPromise, the only thing you can do is pipeline on it. Since the map callback must be synchronous, you can't await the promise either. So it turns out it's actually not easy to mess up in a map callback. The main thing you have to avoid is side effects that modify stuff outside the…

Yeah that's what I meant, reading/writing variables captured into the callback. But that sounds like the kind of code that would be easy to sniff out in a code review, or write lints for.

Re: Cap'n Web: a new RPC system for browsers and web servers

#36

Looking at this quickly, it does seem to require (or strongly encourage?) a stateful server to hold on to the import and export tables and the state of objects in each. One thing about a traditional RPC system where every call is top-level and you pass keys and such on every call is that multiple calls in a sequence can usually land on different servers and work fine. Is there a way to serialize and store the import/…

The state only lives for a single RPC session.

When using WebSockets, that's the lifetime of the WebSocket.

But when using the HTTP batch transport, a session is a single HTTP request, that performs a batch of calls all at once.

So there's actually no need to hold state across multiple HTTP requests or connections, at least as far as Cap'n Web is concerned.

This does imply that you shouldn't design a protocol where it would be catastrophic if the session suddenly disconnected in the middle and you lost all your capabilities. It should be possible to reconnect and reconstruct them.

Re: Cap'n Web: a new RPC system for browsers and web servers

#37
post #28
post #10

Just making sure I understand the "one round trip" point. If the client has chained 3 calls together, that still requires 3 messages sent from the client to the server. Correct? That is, the client is not packaging up all its logic and sending a single blob that describes the fully-chained logic to the server on its initial request. Right? When I first read it, I was thinking it meant 1 client message and 1 server re…

To chain three calls, the client will send three messages, yes. (At least when using the WebSocket transport. With the HTTP batch transport, the entire batch is concatenated into one HTTP request body.) But the client can send all three messages back-to-back without waiting for any replies from the server. In terms of network communications, it's effectively the same as sending one message.

Yep - agreed. Thanks!

Re: Cap'n Web: a new RPC system for browsers and web servers

#38

This seems like a similar and more feature complete / polished version of JSON RPC? The part that's most exciting to me is actually the bidirectional calling. Having set this up before via JSON RPC / custom protocol the experience was super "messy" and I'm looking forward to a framework making it all better. Can't wait to try it out!

Yeah, JSON RPC doesn't support the pass-by-reference and lifecycle management stuff. You just have a static list of top-level functions you can call. This makes a pretty big difference in what kinds of APIs you can express.

OTOH, JSON RPC is extremely simple. Cap'n Web is a relatively complicated and subtle underlying protocol.

Re: Cap'n Web: a new RPC system for browsers and web servers

#39
post #20

> RPC is often accused of committing many of the fallacies of distributed computing. > But this reputation is outdated. When RPC was first invented some 40 years ago, async programming barely existed. We did not have Promises, much less async and await. I'm confused. How is this a "protocol" if its core premises rely on very specific implementation of concurrency in a very specific language?

[deleted]

Re: Cap'n Web: a new RPC system for browsers and web servers

#40
post #19

It's inspired by and created by a coauthor of [Cap'n Proto]( https://capnproto.org ), which is also what OCapN (referenced in a separate comment) name refers to. Cap'n Proto is inspired by ProtoBuf, protobuf has gRPC and gRPC web. We've been using ProtoBuf/gRPC/gRPC-web both in the backends and for public endpoints powering React / TS UI's, at my last startup. It worked great, particularly with the GCP Kubernetes inf…

I think rather than related to each other, Cap'n and OCapN are both references to object capabilities, aka ocaps. (Insert joke about unforgeable references here)
Post reply on HN