Categorygithub.com/bufbuild/connect-go
modulepackage
1.10.0
Repository: https://github.com/bufbuild/connect-go.git
Documentation: pkg.go.dev

# README

Connect

Build Report Card GoDoc

Connect is a slim library for building browser and gRPC-compatible HTTP APIs. You write a short Protocol Buffer 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 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.connect.build/buf.connect.demo.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 and health checks are available as standalone packages. Instead of cURL, we could call our API with buf curl:

go install github.com/bufbuild/buf/cmd/buf@latest
buf curl --protocol grpc \
    --data '{"sentence": "I feel happy."}' \
    https://demo.connect.build/buf.connect.demo.eliza.v1.ElizaService/Say

Under the hood, Connect is just Protocol Buffers 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, the documentation on connect.build (especially the Getting Started guide for Go), the demo service, or the protocol specification.

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:

package main

import (
  "context"
  "log"
  "net/http"

  "github.com/bufbuild/connect-go"
  pingv1 "github.com/bufbuild/connect-go/internal/gen/connect/ping/v1"
  "github.com/bufbuild/connect-go/internal/gen/connect/ping/v1/pingv1connect"
  "golang.org/x/net/http2"
  "golang.org/x/net/http2/h2c"
)

type PingServer struct {
  pingv1connect.UnimplementedPingServiceHandler // returns errors from all methods
}

func (ps *PingServer) Ping(
  ctx context.Context,
  req *connect.Request[pingv1.PingRequest],
) (*connect.Response[pingv1.PingResponse], error) {
  // connect.Request and connect.Response give you direct access to headers and
  // trailers. No context-based nonsense!
  log.Println(req.Header().Get("Some-Header"))
  res := connect.NewResponse(&pingv1.PingResponse{
    // req.Msg is a strongly-typed *pingv1.PingRequest, so we can access its
    // fields without type assertions.
    Number: req.Msg.Number,
  })
  res.Header().Set("Some-Other-Header", "hello!")
  return res, nil
}

func main() {
  mux := http.NewServeMux()
  // The generated constructors return a path and a plain net/http
  // handler.
  mux.Handle(pingv1connect.NewPingServiceHandler(&PingServer{}))
  err := http.ListenAndServe(
    "localhost:8080",
    // For gRPC clients, it's convenient to support HTTP/2 without TLS. You can
    // avoid x/net/http2 by using http.ListenAndServeTLS.
    h2c.NewHandler(mux, &http2.Server{}),
  )
  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-go,

package main

import (
  "context"
  "log"
  "net/http"

  "github.com/bufbuild/connect-go"
  pingv1 "github.com/bufbuild/connect-go/internal/gen/connect/ping/v1"
  "github.com/bufbuild/connect-go/internal/gen/connect/ping/v1/pingv1connect"
)

func main() {
  client := pingv1connect.NewPingServiceClient(
    http.DefaultClient,
    "http://localhost:8080/",
  )
  req := connect.NewRequest(&pingv1.PingRequest{
    Number: 42,
  })
  req.Header().Set("Some-Header", "hello from connect")
  res, err := client.Ping(context.Background(), req)
  if err != nil {
    log.Fatalln(err)
  }
  log.Println(res.Msg)
  log.Println(res.Header().Get("Some-Other-Header"))
}

Of course, http.ListenAndServe and http.DefaultClient aren't fit for production use! See Connect's deployment docs for a guide to configuring timeouts, connection pools, observability, and h2c.

Ecosystem

Status: Stable

This module is stable. It supports:

Within those parameters, connect-go follows semantic versioning. We will not make breaking changes in the 1.x series of releases.

Legal

Offered under the Apache 2 license.

# Packages

No description provided by the author

# Functions

CodeOf returns the error's status code if it is or wraps an [*Error] and [CodeUnknown] otherwise.
DecodeBinaryHeader base64-decodes the data.
EncodeBinaryHeader base64-encodes the data.
IsNotModifiedError checks whether the supplied error indicates that the requested resource hasn't changed.
IsWireError checks whether the error was returned by the server, as opposed to being synthesized by the client.
NewBidiStreamHandler constructs a [Handler] for a bidirectional streaming procedure.
NewClient constructs a new Client.
NewClientStreamHandler constructs a [Handler] for a client streaming procedure.
NewError annotates any Go error with a status code.
NewErrorDetail constructs a new error detail.
NewErrorWriter constructs an ErrorWriter.
NewNotModifiedError indicates that the requested resource hasn't changed.
NewRequest wraps a generated request message.
NewResponse wraps a generated response message.
NewServerStreamHandler constructs a [Handler] for a server streaming procedure.
NewUnaryHandler constructs a [Handler] for a request-response procedure.
NewWireError is similar to [NewError], but the resulting *Error returns true when tested with [IsWireError].
WithAcceptCompression makes a compression algorithm available to a client.
WithClientOptions composes multiple ClientOptions into one.
WithCodec registers a serialization method with a client or handler.
WithCompression configures handlers to support a compression algorithm.
WithCompressMinBytes sets a minimum size threshold for compression: regardless of compressor configuration, messages smaller than the configured minimum are sent uncompressed.
WithConditionalHandlerOptions allows procedures in the same service to have different configurations: for example, one procedure may need a much larger WithReadMaxBytes setting than the others.
WithGRPC configures clients to use the HTTP/2 gRPC protocol.
WithGRPCWeb configures clients to use the gRPC-Web protocol.
WithHandlerOptions composes multiple HandlerOptions into one.
WithHTTPGet allows Connect-protocol clients to use HTTP GET requests for side-effect free unary RPC calls.
WithHTTPGetMaxURLSize sets the maximum allowable URL length for GET requests made using the Connect protocol.
WithIdempotency declares the idempotency of the procedure.
WithInterceptors configures a client or handler's interceptor stack.
WithOptions composes multiple Options into one.
WithProtoJSON configures a client to send JSON-encoded data instead of binary Protobuf.
WithReadMaxBytes limits the performance impact of pathologically large messages sent by the other party.
WithRecover adds an interceptor that recovers from panics.
WithRequireConnectProtocolHeader configures the Handler to require requests using the Connect RPC protocol to include the Connect-Protocol-Version header.
WithSendCompression configures the client to use the specified algorithm to compress request messages.
WithSendGzip configures the client to gzip requests.
WithSendMaxBytes prevents sending messages too large for the client/handler to handle without significant performance overhead.

# Constants

CodeAborted indicates that operation was aborted by the system, usually because of a concurrency issue such as a sequencer check failure or transaction abort.
CodeAlreadyExists indicates that client attempted to create an entity (for example, a file or directory) that already exists.
CodeCanceled indicates that the operation was canceled, typically by the caller.
CodeDataLoss indicates that the operation has resulted in unrecoverable data loss or corruption.
CodeDeadlineExceeded indicates that deadline expired before the operation could complete.
CodeFailedPrecondition indicates that the system is not in a state required for the operation's execution.
CodeInternal indicates that some invariants expected by the underlying system have been broken.
CodeInvalidArgument indicates that client supplied an invalid argument.
CodeNotFound indicates that some requested entity (for example, a file or directory) was not found.
CodeOutOfRange indicates that the operation was attempted past the valid range (for example, seeking past end-of-file).
CodePermissionDenied indicates that the caller doesn't have permission to execute the specified operation.
CodeResourceExhausted indicates that some resource has been exhausted.
CodeUnauthenticated indicates that the request does not have valid authentication credentials for the operation.
CodeUnavailable indicates that the service is currently unavailable.
CodeUnimplemented indicates that the operation isn't implemented, supported, or enabled in this service.
CodeUnknown indicates that the operation failed for an unknown reason.
IdempotencyIdempotent is the idempotency level that specifies that a given call is "idempotent", such that multiple instances of the same request to this procedure would have the same side-effects as a single request.
IdempotencyNoSideEffects is the idempotency level that specifies that a given call has no side-effects.
IdempotencyUnknown is the default idempotency level.
These constants are used in compile-time handshakes with connect's generated code.
These constants are used in compile-time handshakes with connect's generated code.
These constants are used in compile-time handshakes with connect's generated code.
The names of the Connect, gRPC, and gRPC-Web protocols (as exposed by [Peer.Protocol]).
The names of the Connect, gRPC, and gRPC-Web protocols (as exposed by [Peer.Protocol]).
The names of the Connect, gRPC, and gRPC-Web protocols (as exposed by [Peer.Protocol]).
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Version is the semantic version of the connect module.

# Structs

BidiStream is the handler's view of a bidirectional streaming RPC.
BidiStreamForClient is the client's view of a bidirectional streaming RPC.
Client is a reusable, concurrency-safe client for a single procedure.
ClientStream is the handler's view of a client streaming RPC.
ClientStreamForClient is the client's view of a client streaming RPC.
An Error captures four key pieces of information: a [Code], an underlying Go error, a map of metadata, and an optional collection of arbitrary Protobuf messages called "details" (more on those below).
An ErrorDetail is a self-describing Protobuf message attached to an [*Error].
An ErrorWriter writes errors to an [http.ResponseWriter] in the format expected by an RPC client.
A Handler is the server-side implementation of a single RPC defined by a service schema.
Peer describes the other party to an RPC.
Request is a wrapper around a generated request message.
Response is a wrapper around a generated response message.
ServerStream is the handler's view of a server streaming RPC.
ServerStreamForClient is the client's view of a server streaming RPC.
Spec is a description of a client call or a handler invocation.

# Interfaces

AnyRequest is the common method set of every [Request], regardless of type parameter.
AnyResponse is the common method set of every [Response], regardless of type parameter.
A ClientOption configures a [Client].
Codec marshals structs (typically generated from a schema) to and from bytes.
A Compressor is a reusable wrapper that compresses data written to an underlying sink.
A Decompressor is a reusable wrapper that decompresses an underlying data source.
A HandlerOption configures a [Handler].
HTTPClient is the interface connect expects HTTP clients to implement.
An Interceptor adds logic to a generated handler or client, like the decorators or middleware you may have seen in other libraries.
Option implements both [ClientOption] and [HandlerOption], so it can be applied both client-side and server-side.
StreamingClientConn is the client's view of a bidirectional message exchange.
StreamingHandlerConn is the server's view of a bidirectional message exchange.

# Type aliases

A Code is one of the Connect protocol's error codes.
An IdempotencyLevel is a value that declares how "idempotent" an RPC is.
StreamingClientFunc is the generic signature of a streaming RPC from the client's perspective.
StreamingHandlerFunc is the generic signature of a streaming RPC from the handler's perspective.
StreamType describes whether the client, server, neither, or both is streaming.
UnaryFunc is the generic signature of a unary RPC.
UnaryInterceptorFunc is a simple Interceptor implementation that only wraps unary RPCs.