Deprecated documentation

We made improvements to remote code generation features of the BSR. This page has been replaced with a new BSR go module proxy section.

For existing users, please see the Migrating from alpha guide and if you run into issues contact us on Buf Public Slack.

The Buf Schema Registry (BSR) supports remote code generation for Go. With this feature, you can push Buf modules to the BSR and go get Go code stubs generated from those Protobuf definitions—without ever needing to generate code on your own. Go source code generated by the BSR is hosted on the BSR's Go module proxy.

With this feature, you no longer need to maintain Protobuf files or runtime dependencies like [protoc] plugins—in fact, JavaScript and TypeScript developers can avoid local code generation altogether for any Buf modules that have been pushed to the BSR.

This feature is especially useful for creating API clients for Go, as it provides consumers of your API with generated Go SDKs on demand. With remote generation, you no longer need to generate Go code from Protobuf locally, and thus no longer need for consumers to pull in Protobuf files or perform any generation whatsoever.

BSR Go module proxy

The BSR Go module proxy implements the GOPROXY protocol for Buf modules by generating assets on the fly—Go code stubs aren't generated until you request them using go get.

The key to consuming from the BSR Go module proxy is choosing the right Go module path. The import path for generated Go code has this format:

Go module path syntax
Examplego.buf.build/grpc/go/bufbuild/eliza
Legend:
constant{variable}

So if you wanted to, for example, generate the acme/paymentapis Protobuf module using the grpc/go template, you could install the generated code like this:

$ go get go.buf.build/grpc/go/acme/paymentapis

You can use any template that generates Go, which can simplify Protobuf workflows down to two steps:

  1. buf push your module to the BSR
  2. go get your generated Go module

Try it out!

In this example, we'll use the Go gRPC client for the Eliza demo service. Since this is a gRPC/Protobuf API we get a generated client SDK with minimal effort. The grpc/go template is used to generate the bufbuild/eliza module.

See the above for a refresher on Go module import paths.

package main

import (
	"context"
	"crypto/tls"
	"log"

	// Import the Eliza API definitions and generate using the template grpc/go.
	elizav1 "go.buf.build/grpc/go/bufbuild/eliza/buf/connect/demo/eliza/v1"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

func main() {
	cc, err := grpc.Dial(
		"demo.connect.build:443",
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
	)
	if err != nil {
		log.Fatalf("Failed to dial GCS API: %v", err)
	}
	client := elizav1.NewElizaServiceClient(cc)
	resp, err := client.Say(context.Background(), &elizav1.SayRequest{
		Sentence: "Hello remote generation",
	})
	if err != nil {
		log.Fatalf("Failed to get bucket: %v", err)
	}
	log.Println(resp)
}

If you're using Go modules you'll observe a version such as v1.4.6 in the go.mod file. To better understand versioning, see the synthetic versions documentation.

go.mod
require (
	go.buf.build/grpc/go/bufbuild/eliza v1.4.6
)

Generate private modules

To generate Go code from private modules you'll need to make sure the Go tooling is correctly configured.

  1. Log into the BSR:

    The go tool uses .netrc credentials if available and you can use buf registry login to add this to your .netrc file. You can obtain an API token (password) from the Settings page.

    $ buf registry login
    
    ~/.netrc
    machine buf.build
    		login <USERNAME>
    		password <TOKEN>
    machine go.buf.build
    		login <USERNAME>
    		password <TOKEN>
    
  2. Go Environment Configuration

    The GOPRIVATE environment variable controls which modules the go command considers to be private and thus shouldn't use the proxy or checksum database. This is important since you don't want to send private information to the default Go module proxy at https://proxy.golang.org.

    Set this environment variable:

    $ export GOPRIVATE=go.buf.build
    

    If you already have GONOSUMDB configured, you also need to add go.buf.build to it:

    $ export GONOSUMDB=$GONOSUMDB,go.buf.build
    

    This isn't necessary if you do not already have GONOSUMDB configured, as GOPRIVATE automatically sets it in this case.

    For more information, see the official private modules documentation.