The Go implementation of Connect: Protobuf RPC that works.
Connect =======
Connect is a slim library for building browser and gRPC-compatible HTTP APIs. You write a short [Protocol Buffer][protobuf] schema and implement your application logic, and Connect generates code to handle marshaling, routing, compression, and content type negotiation. It also generates an idiomatic, type-safe client. Handlers and clients support three protocols: gRPC, gRPC-Web, and Connect's own protocol.
The [Connect protocol][protocol] is a simple protocol that works over HTTP/1.1 or HTTP/2. It takes the best portions of gRPC and gRPC-Web, including streaming, and packages them into a protocol that works equally well in browsers, monoliths, and microservices. Calling a Connect API is as easy as using curl. Try it with our live demo:
curl \
--header "Content-Type: application/json" \
--data '{"sentence": "I feel happy."}' \
https://demo.connectrpc.com/connectrpc.eliza.v1.ElizaService/Say
Handlers and clients also support the gRPC and gRPC-Web protocols, including streaming, headers, trailers, and error details. gRPC-compatible [server reflection][grpcreflect] and [health checks][grpchealth] are available as standalone packages. Instead of cURL, we could call our API with a gRPC client:
go install github.com/bufbuild/buf/cmd/buf@latest
buf curl --protocol grpc \
--data '{"sentence": "I feel happy."}' \
https://demo.connectrpc.com/connectrpc.eliza.v1.ElizaService/Say
Under the hood, Connect is just [Protocol Buffers][protobuf] and the standard library: no custom HTTP implementation, no new name resolution or load balancing APIs, and no surprises. Everything you already know about net/http still applies, and any package that works with an http.Server, http.Client, or http.Handler also works with Connect.
For more on Connect, see the [announcement blog post][blog], the documentation on [connectrpc.com][docs] (especially the [Getting Started] guide for Go), the [demo service][examples-go], or the [protocol specification][protocol].
A small example
Curious what all this looks like in practice? From a Protobuf schema, we generate a small RPC package. Using that package, we can build a server. This example is available at internal/example:
package main
import ( "context" "log" "net/http"
"connectrpc.com/connect" pingv1 "connectrpc.com/connect/internal/gen/connect/ping/v1" "connectrpc.com/connect/internal/gen/simple/connect/ping/v1/pingv1connect" "connectrpc.com/validate" )
type PingServer struct { pingv1connect.UnimplementedPingServiceHandler // returns errors from all methods }
func (ps PingServer) Ping(ctx context.Context, req pingv1.PingRequest) (*pingv1.PingResponse, error) { return &pingv1.PingResponse{ Number: req.Number, }, nil }
func main() { mux := http.NewServeMux() // The generated constructors return a path and a plain net/http // handler. mux.Handle( pingv1connect.NewPingServiceHandler( &PingServer{}, // Validation via Protovalidate is almost always recommended connect.WithInterceptors(validate.NewInterceptor()), ), ) p := new(http.Protocols) p.SetHTTP1(true) // For gRPC clients, it's convenient to support HTTP/2 without TLS. p.SetUnencryptedHTTP2(true) s := &http.Server{ Addr: "localhost:8080", Handler: mux, Protocols: p, } if err := s.ListenAndServe(); err != nil { log.Fatalf("listen failed: %v", err) } }
With that server running, you can make requests with any gRPC or Connect client. To write a client using Connect:
package main
import ( "context" "log" "net/http"
pingv1 "connectrpc.com/connect/internal/gen/connect/ping/v1" "connectrpc.com/connect/internal/gen/simple/connect/ping/v1/pingv1connect" )
func main() { client := pingv1connect.NewPingServiceClient( http.DefaultClient, "http://localhost:8080/", ) req := &pingv1.PingRequest{Number: 42} res, err := client.Ping(context.Background(), req) if err != nil { log.Fatalln(err) } log.Println(res) }
Of course, http.ListenAndServe and http.DefaultClient aren't fit for production use! See Connect's [deployment docs][docs-deployment] for a guide to configuring timeouts, connection pools, observability, and h2c.
Ecosystem
- [grpchealth]: gRPC-compatible health checks for connect-go
- [grpcreflect]: gRPC-compatible server reflection for connect-go
- [validate]: [Protovalidate][protovalidate] interceptor for connect-go
- [examples-go]: service powering demo.connectrpc.com, including bidi streaming
- [connect-es]: Type-safe APIs with Protobuf and TypeScript
- [Buf Studio]: web UI for ad-hoc RPCs
- [conformance]: Connect, gRPC, and gRPC-Web interoperability tests
Status: Stable
This module is stable. It supports:
- The two most recent major releases of Go (the same versions of Go that continue
- [APIv2] of Protocol Buffers in Go (
google.golang.org/protobuf).
connect follows semantic versioning. We will
not make breaking changes in the 1.x series of releases.
Legal
Offered under the [Apache 2 license][license].
[APIv2]: https://blog.golang.org/protobuf-apiv2 [Buf Studio]: https://buf.build/studio [Getting Started]: https://connectrpc.com/docs/go/getting-started [blog]: https://buf.build/blog/connect-a-better-grpc [conformance]: https://github.com/connectrpc/conformance [grpchealth]: https://github.com/connectrpc/grpchealth-go [grpcreflect]: https://github.com/connectrpc/grpcreflect-go [connect-es]: https://github.com/connectrpc/connect-es [examples-go]: https://github.com/connectrpc/examples-go [docs-deployment]: https://connectrpc.com/docs/go/deployment [docs]: https://connectrpc.com [go-support-policy]: https://golang.org/doc/devel/release#policy [license]: https://github.com/connectrpc/connect-go/blob/main/LICENSE [protobuf]: https://developers.google.com/protocol-buffers [protocol]: https://connectrpc.com/docs/protocol [slack]: https://buf.build/links/slack [validate]: https://github.com/connectrpc/validate-go [protovalidate]: https://protovalidate.com