Cap'n Web discussion
Seems easy to accidentally foot-gun yourself by sharing capabilities to peers in unexpected ways. Need to be careful which scopes you are passing around.
20 Replies
That's what I thought you were saying but I can't imagine why I'd do that thing that fires the gun. Maybe when I start using it, I'll see the risk more clearly.
Maybe Auth stuff like the example?
I could imagine someone might over-share capabilities to a client without realizing it. If you are intentional about the RPC it should be fine. I would probably create a sub-set / mini-wrapper that explicitly exposes only safe methods.
I feel like it might have solved an issue I had with durable objects storing Auth tokens that I didn’t have with d1 where it needed to get the stub first before it could address the durable object which had some timing issues that resulted in instability, but it’s also more into the weeds then I like to be for backend stuff so maybe I’m reading more into it then I should be
Do you typically use rpc for anything besides communication between internal services? That’s been my primary use case
Moving on...
As I said yesterday, I've built something similar. Cap'n Web has some things my system does not and the DX is better than mine but it's missing some stuff I currently rely upon.
I think they went too light weight with the serialization in the desire to make it human readable. In particular, I regularly send cyclic objects over the wire in my current system. I use an npm package @ungap/structured-clone to do this. I also occasionally send Map and Set.
I'd have to do some testing. It probably will capture scopes outside of the closure if you accidentally reference them. I am not sure.
It's interesting stuff for sure. We may try later.
Classic, seems like that’s a lot of things these days where they do 90% of what you need but the extra 10% is the important part
We mostly use the service bindings between internal services invoking the DO RPC methods.
I asked questions about authentication yesterday to help avoid this. If authentication and your access control is behind those public methods (That's how my system is currently built.), you should be fine, is my preliminary thinking but as you say, it's early.
or link the binding and fetch the stub
That’s exclusively been my use case, both outside of projects to other ones or from worker to durable object. Part of why I was curious
Yeah, I have auth-n at the Worker level with auth-z at the DO level with my current design. This looks like it's best to all be at the DO level. I think that could be OK, but I'm noodling.
I have my own bi-directional RPC all the way from browser client to the DO and vice-versa.
All the browser communication we are doing websockets with a json-rpc like message structure. Very simple stuff
Interesting, why use rpc on the client?
It's a bit late here I'm half asleep HST time zone.
DX
Also, MCP is designed that way and all of my work for the last 6 months has been on building my own MCP framework.
We opt'd out of the complex browser-server RPC stuff for now and don't have a true bi-directional RPC to the browser. We have named events that match each other and can be manually invoked. It gets the job done and keeps the code simple to reason about.
To add some color, when we receive messages from the server we usually emit the name-spaced event using a full-featured event emitter in our front-end, the UI reacts to the messages. Our product is a browser-based operating system and instant messaging platform built with HTML / JS.
I just use websockets if I need bi-directional communication
rpc serves a role for being able to communicate securely between processes without needing to expose anything externally
RPC in both directions is an advantage of using WebSockets. I know it sounds strange for the server to call the client, but it's quite powerful. Cap'n Web (and my framework) have this ability.
Yes, you don't need a fully formalized system to achieve this. It's quite possible to have the same functionality by enforcing the convention where needed. YMMV.