Cap'n Proto 0.9(capnproto.org) |
Cap'n Proto 0.9(capnproto.org) |
I’ve been using grpc/protobuf with Java and Scala. Overall I like it, but the grpc Java library does feel like it comes with a lot of opinions baked in. As an example, I was looking in to implementing automatic retries on the client side for certain classes of error. Grpc Java has some experimental retry support, but it seemed tightly coupled to their also-opinionated way of doing service discovery. I can see why you might want the server to inform clients how to do retries, keepalives, etc. But for less sophisticated operations (read: me) it is frustrating and over complicated. Why can’t I just specify a retry policy when creating a client stub?
Still, it’s better than anything else I’ve seen.
But I do long for a simpler alternative. Is that Cap’n proto? Seems like for Java there is only 3rd party support for serialization only, and not RPC.
This results in cool things like promise pipelining. It is very interesting how it can simplify interface design, and there are examples on the RPC page[0].
This seems to go completely unmentioned on the home page, other than the word “capability system” in the very first sentence.
What does capability based security mean for a data interchange format? The notion hardly makes any sense to me.
From the homepage: “Think JSON, except binary.”
What would JSON look like with capability-based security?
> You can work with results without actually having the results, e.g. before the results exist
This sounds exactly like promises, or perhaps a functional effect system. What does this have to do with data serialization?
If you're happy with protobuf but just not with gRPC, you can check out Twirp [1] and DRPC [2]. Both aim to be simpler alternatives while keeping protobuf for serialization. Their development is Go focused though.
That said I also haven’t found anything better either and the technology is popular enough that I stick with it and just work around the limitations.
For your specific case I highly recommend ignoring the built in GRPC retry nonsense and using the Java failsafe library retry policies instead. That has worked well for my team at least.
what's what opinions are - they necessarily must be wrong to some people. Otherwise, it'd just be called facts!
Capnproto tried to do too much with distributed objects and RPC, I was looking into it years ago but it still seems like the C++ impl is the only one that supports those advanced concepts.
Caveats:
1) I needed to work in C++ and Java
2) I was transporting serialized messages over ZeroMQ
It is missing many nice-to-have features however and is also apparently unmaintained, with the last release 16 months ago...
Parametric type polymorphism AKA generics.
I regularly think of Cap'n Proto when working with gRPC or GraphQL, despite not ever having had the chance to use it in a real project.
There's a list at https://capnproto.org/ under "other advantages".
- It has yet to escape the ZeroVer versioning scheme and produce a “stable” API.
- Maturity for languages other than C++ can be a bit spotty.
- The RPC protocol is cool, but apparently most of it was never implemented. The C++ implementation only implements “level 1.”
Cap’n Proto is undeniably cooler than Protobuf, although in practice I worry primarily about maturity and support.
great to see he is still pushing cap'n proto forward!
Edit: oh you do mean sandcats..
Also, I need to make a web site for KJ.
I used Protobufs for awhile and really didn’t like the C options.
When a reference is constructed, only the creator has the capability of invoking the interface. If the reference is then passed to another server, they and only they have the capability of invoking the interface.
That's what they mean by capability.
> This sounds exactly like promises
Yes, the API is Promise-based. Both Cap'n Proto and JavaScript Promises are inspired by the E programming language, which is a strict object-capability language.
The biggest issue is undeniably that the language maturity isn't quite as solid as the alterntaives. You've got C++, Rust, Python, C#, maybe one or two others. Only C++ is first class. So gRPC and Protobuf win here. But the actual RPC design and IDL design of Cap'n is solid and way more well engineered than the alternatives, IMO.
I have no opinions on the ZeroVer thing. Cap'n Proto is very stable in my experience but I see why others would raise their eyebrows.
A lot of their tests were checking for Exception raises and were basically testing AttributeError due to a change in interface instead of the initial error they were testing for.
With it being fundamental to Cloudflare Workers at this point, you should assume it's support will be solid for at least as long as Cloudflare Workers is a significant part of Cloudflare's business.
Having worked with it over years, the API stability is there. Backwards compatibility is given very strong emphasis, , even with early versions.
> Maturity for languages other than C++ can be a bit spotty.
The language support is a pain at times, especially as the more esoteric language support tends to be built with a specific use case in mind and may not use and implement all the features of the protocol in sometimes undocumented ways.
People can and do write implementations and contribute to existing ones. The C++ and its Javascript and Python bindings work well enough for many use cases. The Rust ones are also fine. There are probably others that have good support now, too.
> The RPC protocol is cool, but apparently most of it was never implemented. The C++ implementation only implements “level 1.”
The RPC protocol is perfectly usable, just not for the higher levels – which all do things not found in other RPC systems. Level 2 can be trivially implemented between client and server at the app level, as anything similar would need to be in any other RPC system. Level 3 sounds way beyond standard RPC needs.
The language maturity one, I can concur though. The rust implementation has been fine, but pycapnp was plagued with memory leaks until recently, and curre tly has performance problems[1] that makes it unsuitable for my use case.
As for the level 2+ protocol, it looks cool on paper, but it looks like a lot of added complexity to address an advanced use case.
The language itself has generics and sum types, which makes it much better at modelling the problem domain than protobuf.
Opinions don’t exist in a void — they’re still the outcome of argument, and can easily be compared by that ruler.
And in this case, it’s trivial to imagine utterly terrible opinionated outcomes — use hyphen to represent addition, having functions like c’s get() (impossible to use correctly, and having defaults that are backwards in the common case.
It’s also trivial to imagine what a poorly reasoned opinion might look like: “ what's what opinions are - they necessarily must be wrong to some people. Otherwise, it'd just be called facts!”