gRPC Services
Full gRPC server and client code generation with streaming support
Go support includes the complete Protocol Buffer ecosystem with all major plugins and performance optimizations. Perfect for microservices, CLI tools, and high-performance backend systems.
gRPC Services
Full gRPC server and client code generation with streaming support
HTTP/JSON APIs
REST API gateways via grpc-gateway or modern Connect protocol
High Performance
3.8x faster serialization with vtprotobuf optimization
Validation
Built-in message validation with CEL expressions
Essential Protocol Buffer Support
Plugin | Description | Generated Files | Status |
---|---|---|---|
protoc-gen-go | Base message generation | *.pb.go | ✅ Stable |
protoc-gen-go-grpc | gRPC services | *_grpc.pb.go | ✅ Stable |
protoc-gen-connect-go | Connect protocol | *_connect.go | ✅ Modern |
protoc-gen-grpc-gateway | HTTP/JSON gateway | *.pb.gw.go | ✅ Popular |
Message Validation
Plugin | Description | Generated Files | Recommendation |
---|---|---|---|
protovalidate | Modern CEL validation | Runtime validation | ✨ Recommended |
protoc-gen-validate | Legacy validation | *.pb.validate.go | ⚠️ Legacy |
Advanced Features
Plugin | Description | Generated Files | Performance |
---|---|---|---|
protoc-gen-go-vtproto | Fast serialization | *_vtproto.pb.go | 3.8x faster |
protoc-gen-go-json | JSON integration | *.pb.json.go | Fast JSON |
protoc-gen-openapiv2 | OpenAPI v2 docs | *.swagger.json | API Docs |
protoc-gen-grpc-federation | BFF generation | *_federation.pb.go | 🧪 Experimental |
languages.go = {enable = true;outputPath = "gen/go";packagePrefix = "github.com/myorg/myproject";options = [ "paths=source_relative" "require_unimplemented_servers=false"];};
languages.go = {enable = true;outputPath = "gen/go";grpc = { enable = true; options = ["paths=source_relative"];};gateway = { enable = true; options = [ "paths=source_relative" "generate_unbound_methods=true" ];};};
languages.go = {enable = true;outputPath = "gen/go";grpc.enable = true;protovalidate.enable = true;vtprotobuf = { enable = true; options = [ "paths=source_relative" "features=marshal+unmarshal+size+pool" ];};json = { enable = true; options = ["paths=source_relative"];};};
languages.go = { enable = true; outputPath = "gen/go"; packagePrefix = "github.com/myorg/myproject"; options = ["paths=source_relative"];
# gRPC service generation grpc = { enable = true; options = [ "paths=source_relative" "require_unimplemented_servers=false" ]; };
# HTTP/JSON gateway for REST APIs gateway = { enable = true; options = [ "paths=source_relative" "generate_unbound_methods=true" "allow_delete_body=true" ]; };
# Modern validation (recommended) protovalidate = { enable = true; };
# Legacy validation validate = { enable = true; options = ["lang=go"]; };
# Modern Connect protocol connect = { enable = true; options = ["paths=source_relative"]; };
# High-performance serialization vtprotobuf = { enable = true; options = [ "paths=source_relative" "features=marshal+unmarshal+size+pool" ]; };
# JSON integration json = { enable = true; options = ["paths=source_relative" "orig_name=true"]; };
# OpenAPI documentation openapiv2 = { enable = true; options = ["logtostderr=true"]; };
# gRPC Federation (experimental) federation = { enable = true; options = ["paths=source_relative"]; };};
Use Buf registry plugins directly:
languages.go = { enable = true; plugins = [ "buf.build/protocolbuffers/go" "buf.build/grpc/go" { plugin = "buf.build/community/planetscale-vtprotobuf"; opt = ["features=marshal+unmarshal+size+pool"]; } "buf.build/community/mfridman-go-json" "buf.build/bufbuild/validate-go" ];};
syntax = "proto3";
package user.v1;
option go_package = "github.com/myorg/myproject/gen/go/user/v1;userv1";
import "validate/validate.proto";import "google/api/annotations.proto";
message User { string id = 1; string name = 2 [(validate.rules).string = {min_len: 1, max_len: 100}]; string email = 3 [(validate.rules).string.email = true]; int32 age = 4 [(validate.rules).int32 = {gte: 0, lte: 150}]; repeated string roles = 5; UserStatus status = 6; repeated Address addresses = 7;
message Address { string street = 1; string city = 2; string state = 3; string zip = 4; string country = 5; }}
enum UserStatus { USER_STATUS_UNSPECIFIED = 0; USER_STATUS_ACTIVE = 1; USER_STATUS_INACTIVE = 2; USER_STATUS_SUSPENDED = 3;}
service UserService { rpc CreateUser(CreateUserRequest) returns (CreateUserResponse) { option (google.api.http) = { post: "/v1/users" body: "user" }; }
rpc GetUser(GetUserRequest) returns (GetUserResponse) { option (google.api.http) = { get: "/v1/users/{user_id}" }; }}
message CreateUserRequest { User user = 1;}
message CreateUserResponse { User user = 1;}
message GetUserRequest { string user_id = 1;}
message GetUserResponse { User user = 1;}
package main
import ( "context" "log" "net"
"google.golang.org/grpc" pb "github.com/myorg/myproject/gen/go/user/v1")
type server struct { pb.UnimplementedUserServiceServer users map[string]*pb.User}
func (s *server) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) { user := req.GetUser()
// Validation happens automatically if validate plugin is enabled if err := user.Validate(); err != nil { return nil, err }
s.users[user.GetId()] = user return &pb.CreateUserResponse{User: user}, nil}
func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) { user, exists := s.users[req.GetUserId()] if !exists { return nil, status.Error(codes.NotFound, "user not found") } return &pb.GetUserResponse{User: user}, nil}
func main() { lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) }
s := grpc.NewServer() pb.RegisterUserServiceServer(s, &server{ users: make(map[string]*pb.User), })
log.Println("Server listening on :50051") if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) }}
package main
import ( "context" "log" "net/http"
"connectrpc.com/connect" pb "github.com/myorg/myproject/gen/go/user/v1" "github.com/myorg/myproject/gen/go/user/v1/userv1connect")
type server struct { users map[string]*pb.User}
func (s *server) CreateUser( ctx context.Context, req *connect.Request[pb.CreateUserRequest],) (*connect.Response[pb.CreateUserResponse], error) { user := req.Msg.GetUser() s.users[user.GetId()] = user
return connect.NewResponse(&pb.CreateUserResponse{ User: user, }), nil}
func (s *server) GetUser( ctx context.Context, req *connect.Request[pb.GetUserRequest],) (*connect.Response[pb.GetUserResponse], error) { user, exists := s.users[req.Msg.GetUserId()] if !exists { return nil, connect.NewError(connect.CodeNotFound, errors.New("user not found")) }
return connect.NewResponse(&pb.GetUserResponse{ User: user, }), nil}
func main() { srv := &server{users: make(map[string]*pb.User)}
mux := http.NewServeMux() path, handler := userv1connect.NewUserServiceHandler(srv) mux.Handle(path, handler)
log.Println("Connect server listening on :8080") http.ListenAndServe(":8080", mux)}
package main
import ( "context" "log" "net" "net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc" pb "github.com/myorg/myproject/gen/go/user/v1")
func main() { // Start gRPC server go func() { lis, _ := net.Listen("tcp", ":50051") s := grpc.NewServer() pb.RegisterUserServiceServer(s, &server{ users: make(map[string]*pb.User), }) s.Serve(lis) }()
// Start HTTP gateway ctx := context.Background() mux := runtime.NewServeMux() opts := []grpc.DialOption{grpc.WithInsecure()}
err := pb.RegisterUserServiceHandlerFromEndpoint(ctx, mux, "localhost:50051", opts) if err != nil { log.Fatal(err) }
log.Println("HTTP gateway listening on :8080") http.ListenAndServe(":8080", mux)}
package main
import ( "context" "log" "time"
"google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" pb "github.com/myorg/myproject/gen/go/user/v1")
func main() { conn, err := grpc.NewClient("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { log.Fatal(err) } defer conn.Close()
client := pb.NewUserServiceClient(conn) ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel()
// Create user createResp, err := client.CreateUser(ctx, &pb.CreateUserRequest{ User: &pb.User{ Id: "123", Name: "John Doe", Email: "john@example.com", Age: 30, Roles: []string{"user", "admin"}, Status: pb.UserStatus_USER_STATUS_ACTIVE, }, }) if err != nil { log.Fatal(err) } log.Printf("Created user: %v", createResp.GetUser())
// Get user getResp, err := client.GetUser(ctx, &pb.GetUserRequest{ UserId: "123", }) if err != nil { log.Fatal(err) } log.Printf("Retrieved user: %v", getResp.GetUser())}
Enable vtprotobuf for 3.8x faster serialization:
languages.go = { enable = true; vtprotobuf = { enable = true; options = [ "paths=source_relative" "features=marshal+unmarshal+size+pool" ]; };};
Usage:
// Fast marshalingdata, err := user.MarshalVT()
// Fast unmarshalingvar user pb.Usererr := user.UnmarshalVT(data)
// Object poolinguser := pb.UserFromVTPool()defer user.ReturnToVTPool()
paths=source_relative
for cleaner importscd examples/simple-flakenix developgo run main.go
If you see import errors, ensure your packagePrefix
matches your Go module path:
languages.go = { packagePrefix = "github.com/yourusername/yourproject";};
Some plugins aren’t yet in nixpkgs. Provide custom packages:
languages.go = { vtprotobuf.package = pkgs.buildGoModule { ... };};
{ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; bufrnix = { url = "github:conneroisu/bufrnix"; inputs.nixpkgs.follows = "nixpkgs"; }; };
outputs = { nixpkgs, flake-utils, bufrnix, ... }: flake-utils.lib.eachDefaultSystem ( system: let pkgs = import nixpkgs {inherit system;}; in { devShells.default = pkgs.mkShell { packages = with pkgs; [ go protobuf protoc-gen-go protoc-gen-go-grpc buf ]; };
packages = { default = bufrnix.lib.mkBufrnixPackage { inherit pkgs; config = { root = "."; protoc = { includeDirectories = ["proto"]; files = ["proto/example/v1/user.proto"]; };
languages = { go = { enable = true; outputPath = "proto/gen/go";
# gRPC support grpc.enable = true;
# OpenAPI v2 generation openapiv2 = { enable = true; outputPath = "proto/gen/openapi"; };
# High-performance vtprotobuf plugin vtprotobuf = { enable = true; options = [ "paths=source_relative" "features=marshal+unmarshal+size+pool" ]; };
# JSON marshaling support json.enable = true; }; }; }; }; }; } );}