10 ms·
Connect: A Better gRPC
- racketprogram 4y agonice
- derekperkins 4y agoBuf has done an amazing job simplifying the whole proto generation process, and now they're at it again, making gRPC easier to deal with. I've been using buf for years now and am excited to dive into connect! The team is rock solid and I love their development philosophies. This is a technology to bet on. No affiliation, just a fan
- misterpigs 4y agoCan I say _finally_ !!
- dontlaugh 4y agoHow does it compare to Twirp, which is already well established?
- dalyons 4y agotwirp is great. You get all the benefits of a schema'd/proto'd wire format (like automatic client library generation), but using standard http infrastructure (web servers, loadbalancers, etc etc) without the custom grpc routing stuff.
- akshayshah 4y agoTwirp _is_ great. For unary RPC, Connect is similar: using the Connect protocol, it works over HTTP/1.1 or HTTP/2, doesn't require any special networking infra, and has first-class support for JSON payloads. In short, `curl | jq` works again. To us, the biggest difference is that Connect _also_ supports the gRPC and gRPC-Web protocols. That lets your code interop with a much, much larger ecosystem of tools and systems, many of which are better-supported than their Twirp equivalents. We designed the Connect protocol and the Go APIs to make multi-protocol support seamless. Server-side code supports the Twirp-like protocol and the gRPC protocols simultaneously by default. Clients can switch protocol with one option, no other code changes required.
- mf192 4y agoI think another differentiator is support for streaming. Tbh I am shocked at the number of folks that use streaming, but alas. It was the #3 issue opened on twirp repository, but they never settled on a solution. https://github.com/twitchtv/twirp/issues/3 https://github.com/twitchtv/twirp/issues/3 One super underrated feature Connect offers for Go devs is access to the request/response headers. No more plumbing incoming/outgoing context :phew:
- bnajdecki 4y agoIs there any reason that this browser compatible protocol is just not a part of gRPC-Web? It would be much better to maintain community project than building new branded project. How strongly connect relies on gRPC? Because it sounds like it’s easy to lock in to buf’s ecosystem.
- akshayshah 4y agoIn theory, there's no reason that grpc-web couldn't support a new protocol. That would be complicated, though; Envoy would also need to support it, and the gRPC team has already designed a protocol that they presumably like. Connect supports gRPC fully, so you shouldn't ever be locked in - you can always migrate systems to `grpc-go`, one piece at a time. We intend all the Connect projects to be community projects - we're happy to accept contributions, design proposals, and anything else. At the same time, we're committing our resources to keeping these projects well-maintained.
- codebutler 4y agoCurious to see their typescript implementation and how it compares with https://github.com/stephenh/ts-proto https://github.com/stephenh/ts-proto which works great for grpc-web.
- idbehold 4y agohttps://github.com/bufbuild/protobuf-es/blob/main/docs/generated_code.md https://github.com/bufbuild/protobuf-es/blob/main/docs/gener... And there's also this which is by the same author but came before it: https://github.com/timostamm/protobuf-ts https://github.com/timostamm/protobuf-ts The latter has code-generation for services and has various transport packages for twirp, grpc, and grpc-web.
- akshayshah 4y agoYou found us :) That's the very early version of the marshaling support - it's pure ECMAScript, so it'll work in browsers, Node, or Deno. `connect-web` will add the RPC layer, built on top of the browser's `fetch` API.
- mountainriver 4y agoVery cool, love the direction and this is definitely needed
- comrad 4y agoYeah, and i am still sad that they've removed Java RMI.
- melony 4y agoAny similar frameworks for flatbuffers?
- akshayshah 4y agoYou can use Connect for flatbuffers, too - the gRPC, gRPC-Web, and Connect wire protocols aren't tied to protobuf. https://connect.build/docs/go/serialization-and-compression#custom-serialization https://connect.build/docs/go/serialization-and-compression#... covers this, and coincidentally uses flatbuffers as the example :)
- melony 4y agoAwesome, do you have any example code for flatbuffers?
- akshayshah 4y agoI don't - I've never actually used flatbuffers. There are two pieces of code you'll want (if possible): 1. A `connect.Codec` implementation. I think it'd look almost the same as our Protobuf codec [0], but you'd use `FlatbuffersCodec.Marshal` and `FlatbuffersCodec.Unmarshal` (from github.com/google/flatbuffers/go). You _must_ have a `Codec`, but it looks like it should be pretty quick. 2. Ideally, you'd have a standalone program to parse your Flatbuffer schema and produce Connect code. The output would probably be very similar to `protoc-gen-connect-go`'s [1]. This isn't required, but it's a nice quality of life improvement (check out [1] to see the kind of conveniences it adds). With Protobuf, you'd do this via a `protoc` plugin and you wouldn't need to parse the schema yourself. From a quick look, I don't think `flatc` supports plugins at all - so maybe you'd either skip this step or put in the effort to parse the schema yourself? [0]: https://github.com/bufbuild/connect-go/blob/main/codec.go#L51 https://github.com/bufbuild/connect-go/blob/main/codec.go#L5... [1]: https://github.com/bufbuild/connect-go/blob/main/internal/gen/connect/ping/v1/pingv1connect/ping.connect.go https://github.com/bufbuild/connect-go/blob/main/internal/ge... Also, thank you for making me stop and think about this in detail. I just pulled Flatbuffers out of a hat when I was writing that part of the docs and assumed that `flatc` supported plugins like `protoc`. Turns out that when you assume... I'm updating that portion of the documentation now :)
- theogravity 4y agoSince this serves on a REST endpoint, does that mean you wouldn't need an envoy proxy if you want to use gRPC from the web?
- akshayshah 4y agoThat's correct! Edit: That's _mostly_ correct! You don't need Envoy to have JS/TS running in a browser call your handler. If I'm being really picky, though, in that case the browser and your handler would need to use either the gRPC-Web or Connect protocol, not the backend gRPC-over-HTTP/2 protocol. Any `connect-go` handler you write supports all three protocols by default, so the short answer is still "yes!"
- jchw 4y agoBuf is cool, but I do wonder about this custom protocol. It sounds good, but I thought gRPC’s bidirectional streaming was neat. It seems that Connect may support it, but it’s not straightforward and it may only work in some conditions: > Streaming RPCs may be half- or full-duplex. In server streaming RPCs, the client sends a single message and the server responds with a stream of messages. In client streaming RPCs, the client sends a stream of messages and the server responds with a single message. In bidirectional streaming RPCs, both the client and server send a stream of messages. Depending on the Connect implementation, IDL, and HTTP version in use, some or all of these streaming RPC types may be unavailable. I am also curious to check out if it assails my concerns about gRPC streams in its own API. I recall having a lot of trouble with figuring out whether gRPC would handle streaming connections hanging gracefully, for example.
- xyzzy_plugh 4y agoI think everything gRPC can do, Connect can do too, either via gRPC or its own protocol. Given browser support is planned, I think the "in some conditions" you refer to is basically the browser using HTTP/1.1. I imagine they'll support a websocket driver for true bidirectional streaming. > I recall having a lot of trouble with figuring out whether gRPC would handle streaming connections hanging gracefully, for example. I think I know what you mean, I've always had a hard time differentiating from protocol errors and application errors. Ultimately I gave up trying to be smart and just treated any interruption the same way: resume the stream from where it left off. Transactional behavior is impossible within just gRPC, as far as I can tell.
- jchw 4y agoYeah, I suppose if you can just use ordinary gRPC, this is basically not a real problem. I’ll definitely want to take a look at the API to see if it improves on the confusion I ran into with upstream gRPC Go. The inability to do “transactional” stuff with gRPC isn’t really a deal breaker, I just want good error handling and recovery.
- akshayshah 4y ago
- jeffbee 4y ago> Excluding comments, grpc-go is 130 thousand lines of hand-written code. It has dozens of subpackages, nearly a hundred configuration options, and bespoke name resolution and load balancing mechanisms. In short: what's the deal with all these fences, and who the hell was "Chesterton"?
- sa46 4y agoI don't think that's fair. It's telling that two companies have ditched the enormous complexity of gRPC for their own solution. There's a great comment from a gRPC engineer back when Twirp launched evaluating why Twirp has gained traction: https://news.ycombinator.com/item?id=18688942 https://news.ycombinator.com/item?id=18688942 I evaluated gRPC but the web story is a disaster; you need an envoy proxy, and TypeScript support was half-baked. I went with Twirp instead. If Connect had been around, I would have gone with it over Twirp because it's compatible with gRPC and Twirp makes a few weird choices like JSON for error messages.
- paulgb 4y agoTo abuse Chesterton’s analogy a bit, I suspect that some of the fences only keep in google-shaped sheep. Sometimes the best way to find out which fences are necessary is to tear them all down.
- IshKebab 4y agoThis is such a low effort and information free argument. I suppose nothing is ever unnecessary in your eyes?
- mf192 4y agoIt always felt like gRPC was solving Google problems, heck that's (probably) what the g stands for. Connect is for the rest of us. I wonder what kind of useful general-purpose interceptors folks will come up with?
- charcircuit 4y agoNo, the g in gRPC stands for gRPC.
- nycdotnet 4y agoIt’s something new every release. Current is golazo, previous was gravity. https://github.com/grpc/grpc/releases https://github.com/grpc/grpc/releases They use this to pad the release notes so they don’t have to comprehensively document the behavior changes.
- 0des 4y ago> They use this to pad the release notes so they don’t have to comprehensively document the behavior changes. I want to laugh, but I also want to cry because it's true.
- charcircuit 4y agoA better link https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md
- qbasic_forever 4y agoThere's definitely a tipping point where having language independent interfaces/protobufs and definitions of services are basically mandatory for any cross-team collaboration or work to be possible. But yeah for small teams or single products it really might not be necessary or be total overkill early on in a new product.
- pjmlp 4y agoOnly when "rest of us" === Go developers, in its current state.
- est 4y agoanother gRPC alternative https://brpc.apache.org/ https://brpc.apache.org/
- Meai 4y agoI'd appreciate it if they could be more upfront about their language support and what this even does for me. Right now this is: "A better gRPC for Go". And I don't know what's better about it without doing much more research. Apparently proto3 has support for json encoding by default. So they somehow give me a better schema validation. That's their claim but I don't see how exactly they do that without going much deeper into it. Meanwhile .proto files are obviously already a schema, so they might be parsing your golang server code to see if it still matches your .proto file. That sounds very brittle to me if true. I'm not convinced at all from this post and I don't see how this works.
- theptip 4y agoThe OP discusses code complexity, bugs, API instability, and incompatibility with the rest of the Go HTTP library ecosystem as issues that it’s aiming to solve.
- akshayshah 4y agoFair criticism - you're all the first people to see a lot of this writing, so we're taking notes and we'll try to make the next iteration clearer. Right now, we've got a Go RPC library that's ready for early adopters. In a month or two, we'll have a TypeScript library for web developers. A while after that, we'll probably tackle server-side TypeScript. We're not sure what will be highest-priority after that: could be Swift + Kotlin for mobile, could be Python, could be something else. We think that `connect-go` is a better choice than Google's gRPC implementations because it's (1) a simpler implementation, (2) interoperates better with the Go HTTP ecosystem, and (3) supports a nicer protocol _in addition to_ the gRPC and gRPC-Web protocols. You get everything that's good about gRPC, very little (hopefully none!) of what's bad, and you get some extra goodies on top. The same is true of the upcoming `connect-web` compared to `grpc-web`, and so on. Re: JSON, you're right - proto3 defines a Protobuf-to-JSON mapping that everyone uses. What's less obvious is that if you use JSON with the gRPC protocol, you don't actually end up with JSON HTTP payloads. Instead, you get `<5 bytes of binary framing>{"some": "json"}` - which isn't all that useful, because it's no longer JSON. Then consider that gRPC doesn't use meaningful HTTP status codes, even for request-response RPCs, and it requires using HTTP trailers, and it requires HTTP/2. All of a sudden, it's not much like the ubiquitous, un-fussy HTTP APIs that make REST so successful. The `connect-go` library offers you a solution for this by supporting the Connect _protocol_, which fixes these warts. Hopefully that's a little clearer <3
- Matthias247 4y agoFrom scanning the page it’s a little bit confusing what the scope of this actually is: A new protocol specification that fulfills the goals of working in browser environments (no trailers) and is more debuggable? Seems to be like it - but then it wouldn’t really be compatible to regular gRPC and gRPC-Web. A library which implements the new protocol and the existing ones? Apparently from how far how understand the page - but probably wouldn’t fulfill the „no-bloat“ goal too much.
- ghotli 4y agoI read the whole page and the argument felt quite clear.
- linux2647 4y agoAt $WORK, we wrote our own RPC framework that uses protobufs HTTP. gRPC wasn’t an option because our infrastructure couldn’t support HTTP/2 and we needed first-class Ruby support, something Google seems doesn’t seem to have much interest in. Twirp didn’t exist when we started building our framework, but I’m not sure it would satisfy our needs anyways. connect-go looks very similar to what we’ve built. If you ever release Ruby bindings, there’s a strong chance we could switch to it. Nice work!
- nurettin 4y agoThis is really interesting, having built your own rpc layer, which parts of the code did you visit to compare implementations? For example: for logging frameworks, I immediately check if they do buffering and support reentrancy.
- dalyons 4y agoWhy wouldn’t twirp satisfy your needs? It’s just protos, codegen and http. And supported very well in ruby
- dfee 4y ago… because you really couldn’t make a worse gRPC. Ok, though, that really is the point of the article. And, it’s more than fair. Really hoping for a Java version of this.
- DeathArrow 4y agoThis might be a better gRPC for Go. When I read the title I expected a new protocol based on gRPC, maybe something like Cap'n Proto.
- stoicjumbotron 4y agoIs there any good guide on when to use gRPC over JSON and is it good to use for small teams?
- thinkharderdev 4y agogRPC and JSON are not really alternatives. gRPC is an RPC framework that typically uses protocol buffers as a serialization format but is perfectly capable of using JSON. When you would use JSON over HTTP vs gRPC? I can think of a couple cases: 1. Your infrastructure doesn't support HTTP/2 with trailers. 2. You need to send/receive payloads that aren't well-defined. The nice thing about JSON vs protocol buffers is that JSON is self-describing and flexible. In most languages you have libraries which can deal with JSON as essentially a Map<String,Object>, with maybe a nice cursor API that allows you to pick/update specific fields without knowing anything else about the object structure. You can encode the JSON AST in protocol buffers but it will not be very nice I don't think. 3. You want your wire-format to be human readable for some reason. You can technically do this with gRPC as it is not strictly tied to protocol buffers as the wire format for messages, but in practice it is kind of a pain and language support for doing it can be spotty. At the very least you have to figure out how to do it as protocol buffers is very much the default. 4. The code-generated classes/structs from gRPC IDL are often quite bad to work with. If you've ever used the case classes generated by scalapb (Scala) or the structs generated by Prost (Rust) then you know what I mean. You end up having to create a parallel set of data structures for your protobuf message types to keep yourself sane. With JSON on the other hand, you can typically create classes/structs which are nice to work with internally but also directly serializable to JSON. All that said, gRPC is really nice. If I am bootstrapping a project, gRPC is definitely the default and I need a good reason to use anything else.
- stoicjumbotron 4y agoUnderstood. I think I'll have to play around with it just to get a good feel of whether it is worth the switch for my personal projects at least. Thanks.
- Copenjin 4y agoThe main problem I have with grpc is how the connection is handled, I don't really like how minimal the api is in regard to handling disconnections or connectivity issues (the famous GOAWAY). Sometimes it's not enough if the library just autonomously reestablish the session, I want to be notified of any issue and being able to act in a custom way.
- voz_ 4y agoI worked with the author of buf at Uber. He's brilliant. You should use his stuff.
- swyx 4y ago> We've got big plans for the Connect ecosystem! Along with Connect in Go, we've been working on a TypeScript implementation for browsers. It shares the same design priorities: it's idiomatic TypeScript all the way down, stays close to the browser's fetch API, fits neatly into React hooks, and supports both gRPC-Web and Connect's own protocol. It also produces tiny bundles. We've already replaced grpc-web in the Buf Schema Registry frontend, and we're planning to release connect-web soon — stay tuned. i belive this will be huge. biggest blocker for grpc adoption is the really poor js and grpc-web implementations.
- divan 4y agoIntro definitely hits some pain points. I use Go+gRPC+Flutter stack for the last few years, and when Connect have Dart implementation, will give it a try for sure.
- javier2 4y agoHow does it differ from Twirp?
- scanr 4y agoThis looks great. Congrats buf team. How does it compare to https://storj.github.io/drpc/ https://storj.github.io/drpc/?
- koeng 4y agoDRPC doesn't actually support gRPC generally - you can't connect with a python client to the go DRPC server. (At least, was that way when I tried to use it)
- CMCDragonkai 4y agoI've been using grpc-js for peer to peer work. It's been tough so much do that I'm considering dropping it in favour of just json RPC. I'd hope that when the typescript version is available that it actually uses promises, Async generators and supports both client side and server side. And most importantly we can use any underlying stream socket (like UDP).
- kristiandupont 4y agoAre you familiar with https://trpc.io/ https://trpc.io/?
- steeve 4y ago> Rather than using the Go standard library's net/http, grpc-go uses its own implementation of HTTP/2. It's incompatible with the rest of Go's HTTP ecosystem, so you can't cleanly serve gRPC requests alongside other HTTP traffic and can't use most third-party packages. Mostly because grpc-go's implementation is about 5-10x faster than net/http.
- nhoughto 4y agoGood stat, anymore detail? Love to read more into why
- pvillano 4y agoinvoking Cunningham Maybe it follows the spec completely and defensively, requiring many more checks and supporting typically unused behavior
- avg_dev 4y agoI'm curious how the performance of the two (grpc-go and connect) compare in benchmarks in terms of memory usage and so on. I know there is fasthttp in Go which sometimes people use as an alternative to net/http for performance sensitive code. https://www.sobyte.net/post/2022-03/nethttp-vs-fasthttp/ https://www.sobyte.net/post/2022-03/nethttp-vs-fasthttp/ I also presume there are some reduction in bugs simply by reducing the LoC in this project compared to grpc-go.
- mgaunard 4y agoAll these web technologies stacking inefficiencies on top of each other to build massive frameworks that you can do much better with a hundred lines of C.
- pftq_ 4y agoyour site gives 403 forbidden error
- secondcoming 4y agoHmm, I'm really surprised that gRPC is build on HTTP/2. It's a very complex protocol.
- asim 4y agoGood luck Buf! I spent many years building an RPC framework around gRPC called Go Micro (https://github.com/asim/go-micro https://github.com/asim/go-micro). I think one of the biggest issues was just resources to see it through but also my own desire to move beyond it towards a platform and services. I hope you're able to bring some sense to the gRPC world. It's mostly a networking library. The ecosystem around it is too low level. If anything abstractions and more developer friendly tooling would be a massive improvement. No one needs to see or touch the guts of gRPC. I wish I didn't have to peak into the internals but unfortunately that's what it takes to integrate it elsewhere. I hope you build something awesome for the community!
- giancarlostoro 4y ago> If anything abstractions and more developer friendly tooling would be a massive improvement. This was what I missed when I did JMS for a project in Java. The tooling felt confusing and I never found good tooling to see the messages passed through and poke and prod at them.
- bmon 4y agoAt my company we would love to use buf but can't: because of the BSR. We already pay shitloads for our VCS - we don't want to pay for another product that does the same thing. After using go and getting a taste of what life is like without third party package publishers (like npm, pypi, etc) it's hard to want to go back.
- AtNightWeCode 4y agoPretty cool. Maybe if it gets supported by some big org this can be something. gRPC in general is not a good option for reasons this project mention among other things like it does not play nice with common infra. This also needs the magic of Envoyproxy or?