GoGRPCBridge

module
v0.0.19 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 27, 2026 License: MIT

README

GoGRPCBridge

Native gRPC in the browser using WebSocket transport, without rewriting your service contracts.

Go Reference Test Release

What You Get

  • One public integration package for new work: pkg/grpctunnel.
  • Unary and streaming RPC support from js/wasm clients.
  • Server-side hardening hooks (origin policy, limits, connection controls).
  • CI quality gates for lint, race/coverage, security scanners, compile, and value-proposition benchmarks.

Architecture

Browser WASM gRPC client
  -> websocket (ws/wss)
    -> grpctunnel bridge handler (Go HTTP server)
      -> in-process grpc.Server
        -> your existing protobuf services

The project keeps your protobuf and generated client/server contracts intact. It only adapts transport for browser constraints.

Install

go get github.com/monstercameron/GoGRPCBridge@latest

Requires Go 1.25+ (see go.mod toolchain requirements).

Module Identity

  • GitHub repository: github.com/monstercameron/GoGRPCBridge
  • Canonical Go module path: github.com/monstercameron/GoGRPCBridge

The module path remains github.com/monstercameron/GoGRPCBridge for consumer compatibility and existing go get installs. Use the module path for imports and go get, and use GoGRPCBridge as the project/repository name.

Show, Not Tell: Minimal Integration

1. Server bridge in front of your grpc.Server
package main

import (
	"log"
	"net/http"
	"time"

	"github.com/monstercameron/GoGRPCBridge/pkg/grpctunnel"
	"google.golang.org/grpc"
)

func isAllowedOrigin(r *http.Request) bool {
	switch r.Header.Get("Origin") {
	case "https://app.example.com":
		return true
	default:
		return false
	}
}

func main() {
	grpcServer := grpc.NewServer()
	// Register generated services on grpcServer.

	handler := grpctunnel.Wrap(
		grpcServer,
		grpctunnel.WithOriginCheck(isAllowedOrigin),
		grpctunnel.WithKeepalive(30*time.Second, 2*time.Minute),
		grpctunnel.WithReadLimitBytes(4<<20),
		grpctunnel.WithMaxActiveConnections(2000),
		grpctunnel.WithMaxConnectionsPerClient(20),
		grpctunnel.WithMaxUpgradesPerClientPerMinute(60),
	)

	mux := http.NewServeMux()
	mux.Handle("/grpc", handler)

	log.Fatal(http.ListenAndServe(":8080", mux))
}
2. Browser js/wasm gRPC client over tunnel
//go:build js && wasm

package main

import (
	"context"
	"log"
	"time"

	pb "github.com/your-org/your-proto/gen"
	"github.com/monstercameron/GoGRPCBridge/pkg/grpctunnel"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	conn, err := grpctunnel.BuildTunnelConn(ctx, grpctunnel.TunnelConfig{
		Target:      "/grpc", // same-origin route on your host app
		GRPCOptions: grpctunnel.ApplyTunnelInsecureCredentials(nil),
	})
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	client := pb.NewTodoServiceClient(conn)
	res, err := client.ListTodos(context.Background(), &pb.ListTodosRequest{})
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("todos: %d", len(res.GetTodos()))
}

Evidence: Baseline Benchmark Snapshot

Source: benchmarks/quality_baseline.json (generated 2026-03-26T13:07:50Z, windows/amd64, Go 1.25.0).

Scenario gRPC bridge REST baseline Delta
Payload 1000 items (B/op) 352,567 751,877 -53.1%
Bidirectional 100 messages (B/op) 200,639 1,087,660 -81.6%
Bidirectional 100 messages (allocs/op) 5,333 10,854 -50.9%
Large dataset stream 1000 items (B/op) 805,667 905,704 -11.0%

This is why the project exists: keep gRPC semantics while reducing transport overhead in browser-driven workflows.

Production Guardrails You Can Enforce

  • Origin allow-list with WithOriginCheck.
  • Frame/read bounds with WithReadLimitBytes (or explicit disable only when upstream bounds exist).
  • Abuse controls with:
    • WithMaxActiveConnections
    • WithMaxConnectionsPerClient
    • WithMaxUpgradesPerClientPerMinute
  • Keepalive and idle behavior with WithKeepalive.
  • Structured logs plus OpenTelemetry span/metric integration in the canonical path (pkg/grpctunnel).

Quality and Security Gates

Run from this repository root (third_party/GoGRPCBridge):

go run ./tools/runner.go quality
go run ./tools/runner.go quality-trend
go run ./tools/runner.go canonical-publish-check

canonical-publish-check verifies module path alignment, canonical repository identity (GoGRPCBridge), and a clean-consumer go get + compile smoke test.

Release workflow also enforces:

  • gosec high-severity/high-confidence policy
  • govulncheck
  • API governance checks
  • compile verification
  • benchmark trend artifact generation

Documentation Map

Directories

Path Synopsis
examples
custom-router command
Custom router example - compatibility wiring for existing HTTP servers.
Custom router example - compatibility wiring for existing HTTP servers.
direct-bridge command
Direct gRPC-over-WebSocket example - no proxy needed!
Direct gRPC-over-WebSocket example - no proxy needed!
grpc-server command
production-bridge command
Production bridge example - compatibility-oriented full configuration.
Production bridge example - compatibility-oriented full configuration.
simple-bridge command
Simple bridge server example - minimal compatibility configuration.
Simple bridge server example - minimal compatibility configuration.
pkg
bridge
Package bridge provides low-level gRPC-over-WebSocket primitives.
Package bridge provides low-level gRPC-over-WebSocket primitives.
grpctunnel
Package grpctunnel provides a high-level API for running gRPC over WebSocket.
Package grpctunnel provides a high-level API for running gRPC over WebSocket.
wasm/dialer
Package dialer provides browser-specific gRPC dial integration for WebAssembly.
Package dialer provides browser-specific gRPC dial integration for WebAssembly.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL