serviceproxy

package
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2025 License: Apache-2.0 Imports: 16 Imported by: 0

README

Service Proxy

This package offers an easy way to forward gRPC requests to a service. It is mostly useful for gRPC-Web servers that need to forward requests to a different gRPC server without having to write RPCs that only wrap the original RPCs.

Note: Only supports unary and server streaming RPCs.

Usage

Create a new ServiceProxy instance using NewServiceProxy

  1. Register your connections using the AddConn method
import "go.alis.build/client/serviceproxy"

var (
    ServiceProxy *serviceproxy.ServiceProxy
)

func init() {
    ServiceProxy = serviceproxy.NewServiceProxy()
    
    conn,err := grpc.Dial(host, opts...)
    if err != nil {}
    err = ServiceProxy.AddConn(pb.Service_ServiceDesc.ServiceName, conn)
    if err != nil {}
}

You can optionally specify which methods to allow.

ServiceProxy.AddConn(pb.Service_ServiceDesc.ServiceName, conn, "org.product.v1.Service/*", "org.product.v1.OtherService/ExampleMethod")
  1. Use the IsAllowedMethod and ForwardUnaryRequest, ForwardServerStreamRequest, or ForwardRestRequest in your own custom interceptors

func main() {
    grpcServer := grpc.NewServer(grpc.UnaryInterceptor(unaryInterceptor), grpc.StreamInterceptor(streamInterceptor))
	
	wrappedGrpc := grpcweb.WrapServer(grpcServer)
	h := http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
		// ...

		// Handle REST requests
		// If the method is allowed, forward the request to the appropriate service
		if clients.ServiceProxy.IsAllowedMethod(req.RequestURI) {
			clients.ServiceProxy.ForwardRestRequest(resp, req)
			return
		}
	})

	// required for h2c server on google cloudrun
	ctx := context.Background()
	_, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
	defer stop()

	// Start the server
	port := "8080"
	h2s := &http2.Server{}
	server := &http.Server{
		Addr:    ":" + port,
		Handler: h2c.NewHandler(h, h2s),
	}
	if err := server.ListenAndServe(); err != nil {
	}
}

func unaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
	// If the method is allowed, forward the request to the appropriate service
	if  clients.ServiceProxy.IsAllowedMethod(info.FullMethod) {
		return clients.ServiceProxy.ForwardUnaryRequest(ctx, req, info)
	}
	
	// Call the handler
	h, err := handler(ctx, req)
	if err != nil {
	}
	return h, err
}

// Stream interceptor that validates the request and then calls the handler
func streamInterceptor(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
	// If the method is allowed, forward the request to the appropriate service
	if clients.ServiceProxy.IsAllowedMethod(info.FullMethod) {
		return clients.ServiceProxy.ForwardServerStreamRequest(stream.Context(), stream, info)
	}

	// Call the handler
	err := handler(srv, stream)
	if err != nil {
	}
	return err
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type HttpError added in v0.1.2

type HttpError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	// contains filtered or unexported fields
}

HttpError represents an HTTP error with a status code and message.

func (HttpError) Error added in v0.1.2

func (e HttpError) Error() string

func (HttpError) Is added in v0.1.2

func (e HttpError) Is(target error) bool

type ServiceProxy

type ServiceProxy struct {
	// contains filtered or unexported fields
}

ServiceProxy is a gRPC service proxy that forwards requests to other services

func NewServiceProxy

func NewServiceProxy() *ServiceProxy

NewServiceProxy creates a new ServiceProxy

func (*ServiceProxy) AddConn

func (f *ServiceProxy) AddConn(service string, clientConn *grpc.ClientConn, allowedMethods ...string) error

AddConn adds a connection to the service proxy.

allowedMethods can be passed to restrict the methods that can be proxied. For example, to allow only the method "ExampleMethod" in the service "Service" and package "org.product.v1":

AddConn("org.product.v1.Service", clientConn, "org.product.v1.Service/ExampleMethod")

To allow all methods in the service "Service" and package "org.product.v1":

AddConn("org.product.v1.Service", clientConn, "org.product.v1.Service/*")

If no methods are provided, all methods in the service will be allowed.

func (*ServiceProxy) ForwardClientStreamRequest added in v0.1.3

func (f *ServiceProxy) ForwardClientStreamRequest(ctx context.Context, stream grpc.ServerStream, info *grpc.StreamServerInfo) error

ForwardClientStreamRequest forwards a client streaming request to the appropriate service.

func (*ServiceProxy) ForwardRestRequest added in v0.1.2

func (f *ServiceProxy) ForwardRestRequest(response http.ResponseWriter, request *http.Request)

ForwardRestRequest forwards a REST request to the appropriate service.

func (*ServiceProxy) ForwardServerStreamRequest added in v0.0.9

func (f *ServiceProxy) ForwardServerStreamRequest(ctx context.Context, stream grpc.ServerStream, info *grpc.StreamServerInfo) error

ForwardServerStreamRequest forwards a server streaming request to the appropriate service.

func (*ServiceProxy) ForwardUnaryRequest

func (f *ServiceProxy) ForwardUnaryRequest(ctx context.Context, req any, info *grpc.UnaryServerInfo) (any, error)

ForwardUnaryRequest forwards a unary request to the appropriate service.

func (*ServiceProxy) IsAllowedMethod

func (f *ServiceProxy) IsAllowedMethod(fullMethod string) bool

IsAllowedMethod checks if a method is allowed to be proxied

func (*ServiceProxy) RemoveConn

func (f *ServiceProxy) RemoveConn(service string)

RemoveConn removes a connection from the service proxy

func (*ServiceProxy) RevokeMethod

func (f *ServiceProxy) RevokeMethod(method string)

RevokeMethod revokes a method from the service proxy

Jump to

Keyboard shortcuts

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