Live data from Hacker News

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

blog.cloudflare.com

41–50 of 305 posts

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

#41
post #29

Looks very cool, especially passing functions back and forth. But then I wonder, what would I actually use that for? You mention that it’s schemaless as if that’s a good thing. Having a well defined schema is one of the things I like about tRPC and zod. Is there some way that you get the benefits of a schema with less work?

You can use TypeScript to define your API, and get all the benefits of schemas.

Well, except you don't get runtime type checking with TypeScript, which might be something you really want over RPC. For now I actually suggest using zod for type checks, but my dream is to auto-generate type checks based on the TypeScript types...

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

#42

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/…

That's what I noticed reading through this.

It looks like the server affinity is accomplished by using websockets. The http batching simply sends all the requests at once and then waits for the response.

I don't love this because it makes load balancing hard. If a bunch of chatty clients get a socket to the same server, now that server is burdened and potentially overloadable.

Further, it makes scaling in/out servers really annoying. Persistent long lived connections are beasts to deal with because now you have to handle that "what do I do if multiple requests are in flight?".

One more thing I don't really love about this, it requires a timely client. This seems like it might be trivial to DDOS as a client can simply send a stream of push events and never pull. The server would then be burdened to keep those responses around so long as the client remains connected. That seems bad.

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

#43

This seems great and I'm really excited to try it in place of trpc/orpc. Although it seems to solve one of the problems that GraphQL solved that trpc doesn't (the ability to request nested information from items in a list or properties of an object without changes to server side code), there is no included solution for the server side problem that creates that the data loader pattern was intended to solve, where a na…

I generally agree that the .map() trick doesn't actually replace GraphQL without some sort of server-side optimizations to avoid turning this into N+1 selects.

However, if your database is sqlite in a Cloudflare Durable Object, and the RPC protocol is talking directly to it, then N+1 selects are actually just fine.

https://www.sqlite.org/np1queryprob.html

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

#44
are there security issues with no schemas + callback stubs + language on the server with little typing. for example with this `hello(name)` example the server expects a string but can the client pass an callback object that is string-like and then use this to try and trick the server into doing something bad?

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

#45
post #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 i…

^ maybe the most knowledgable person in the world about these gritty details

RPC SDKs should have session management, otherwise you end up in this situation:

"Any sufficiently complicated gRPC or Cap'n'Proto program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Akka"

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

#46

are there security issues with no schemas + callback stubs + language on the server with little typing. for example with this `hello(name)` example the server expects a string but can the client pass an callback object that is string-like and then use this to try and trick the server into doing something bad?

The protocol explicitly blocks overriding `toString()` (and all other Object.prototype members), as well as `toJSON()`, to prevent the obvious ways that you might accidentally invoke a callback when you weren't expecting to. How else might you invoke a callback by accident?

That said, type checking is called out both in the blog post (in the section on TypeScript) and in the readme (under "Security Considerations"). You probably should use some runtime type checking library, just like you should with traditional JSON inputs.

In the future I'm hoping someone comes up with a way to auto-generate type checks based on TypeScript types.

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

#47

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/…

My limited knowledge of Cap'n'Proto (read the docs once years ago) server and clients can peer stubs, so that is server C receives a stub originated from server A via client B then C can try to call A directly.

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

#48
post #6
post #2

Since Cap'n Web is a simplification of Cap'n Proto RPC, it would be amazing if eventually the simplification traveled back to all the languages that Cap'n Proto RPC supports (C++, etc.). Or at least could be made to be binary compatible. Regardless, this is great.

Yeah I now want to go back and redesign the Cap'n Proto RPC protocol to be based on this new design, as it accomplishes all the same features with a lot less complexity! But it may be tough to justify when we already have working Cap'n Proto implementations speaking the existing protocol, that took a lot of work to build. Yes, the new implementations will be less work than the original, but it's still a lot of work t…

You mean redesign Cap'n Proto to not have a schema? Or did you mean the API, not the protocol?

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

#49
I really dig the flexibility of transport. Having something that works over postMessage is totally clutch!!

> Similarly, supports passing objects by reference: If a class extends the special marker type RpcTarget, then instances of that class are passed by reference, with method calls calling back to the location where the object was created.

Can this be relaxed? Having to design the object model ahead of time for RpcTarget is constraining. If we could just attach a ThingClass.prototype[Symbol.for('RpcTarget')] = true then there would be a lot more flexibility, less need to design explciitly for RpcTarget, to use RpcTarget with the objects/classes of 3rd party libraries.

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

#50

What's going on under the hood with that authentication example? Is the server holding onto some state in memory that this specific client has already authenticated? Or is the API key somehow stored in the new AuthenticatedSession stub on the client side and included in subsequent requests? Or is it something else entirely?

The server constructs a new AuthenticatedSession implementation each time authenticate() is called, and can store the key (or just the authenticated user info) in the server-side object.

This does mean the server is holding onto state, but remember the state only lasts for the lifetime of the particular connection. (In HTTP batch mode, it's only for the one batch. In WebSocket mode, it's for the lifetime of the WebSocket.)

Post reply on HN