package
0.0.0-20250305165956-269064b29c6f
Repository: https://github.com/bryk-io/pkg.git
Documentation: pkg.go.dev

# README

Package drpc

DRPC is a lightweight, drop-in, protocol buffer-based gRPC replacement. The DRPC protocol strips out huge swaths of unnecessary complexity; it is implemented in just a few thousand lines of straightforward Go! DRPC is small, extensible, efficient, and can still be autogenerated from your existing Protobuf definition files.

More information: https://github.com/storj/drpc

Server

This package simplifies the process of running a DRPC server in production by providing often required additional functionality, for example:

  • Properly setup TLS to provide secure communication channels
  • Protect against panics produced by external services
  • Generate structured logs for all processed requests
  • Request authentication/authorization (authN, authZ)
  • Rate limiting requests to avoid resource exhaustion attacks

For example, to start a typical production server.

// Token validation function. This will usually handle JWT or PASETO
// tokens for example.
myCustomCredsValidation := func(token string) bool {
  return token == "super-secure-credentials"
}

// Server TLS settings. Cert, key and CA are usually read from a file
// or another secret-management tool.
tlsSettings := ServerTLS{
  Cert:             my-cert-pem,
  PrivateKey:       my-key-pem,
  CustomCAs:        [][]byte{my-ca-cert-pem},
  IncludeSystemCAs: true,
}

// Define the middleware elements to use.
// In this case:
// - Use zerolog to produce "pretty" detailed output
// - Limit the processing to 100 RPC requests per-second
// - Provide a custom token-based authentication mechanism
// - Prevent the server from crashing on `panic` calls
smw := []srvmw.Middleware{
  srvmw.Logging(xlog.WithZero(true, "error").Sub(xlog.Fields{"component": "server"}), nil),
  srvmw.RateLimit(100),
  srvmw.AuthByToken("auth.token", myCustomCredsValidation),
  srvmw.PanicRecovery(),
}

// RPC server settings.
// - The server will listen on TCP port 8080
// - The server will handle DRPC and HTTP requests
// - The server will use TLS for secure connections
// - The server will provide bi-directional streaming over WebSockets (and DRPC)
opts := []Option{
  WithServiceProvider(myServiceImplementation()),
  WithPort(8080),
  WithHTTP(),
  WithMiddleware(smw...),
  WithTLS(tlsSettings),
  WithWebSocketProxy(
    ws.EnableCompression(),
    ws.CheckOrigin(func(r *http.Request) bool { return true }),
    ws.HandshakeTimeout(2*time.Second),
    ws.SubProtocols([]string{"rfb", "sip"}),
  ),
}

// Create and start the new server
srv, err := NewServer(opts...)
if err != nil {
  panic(err)
}
srv.Start()

Client

This package simplifies the process of running a DRPC client in production by providing often required additional functionality, for example:

  • Concurrent RPC requests (using connection pools)
  • Properly setup TLS to provide secure communication channels
  • Protect against panics produced by external services
  • Generate structured logs for all processed requests
  • Provide custom metadata on all requests send to the server (e.g. credentials)

For example, to start a typical production client.

// Custom metadata. Can be used to provide identifiers, credentials or
// additional contextual details.
kv := map[string]string{
  "metadata.user": "rick",
}

// Client TLS settings.
tlsSettings := ClientTLS{
  IncludeSystemCAs: true,
  CustomCAs:        [][]byte{ca-cert-pem},
  ServerName:       "my-server.local.acme.com",
}

// Client middleware.
// - Provide custom details (`kv`) on every request
// - Use zerolog to produce "pretty" detailed output
// - Limit the client to 100 RPC requests per-second
// - Prevent the client from crashing on `panic` calls
cmw := []clmw.Middleware{
  clmw.Metadata(kv),
  clmw.Logging(xlog.WithZero(true, "error").Sub(xlog.Fields{"component": "client"}), nil),
  clmw.RateLimit(100),
  clmw.PanicRecovery(),
}

// Client options.
// - Up to 5 concurrent RPC calls
// - Include a protocol selection header (between DRPC and HTTP)
// - Use TLS to verify server's identity and establish secure connections
opts := []ClientOption{
  WithProtocolHeader(),
  WithPoolCapacity(5),
  WithClientTLS(tlsSettings),
  WithClientMiddleware(cmw...),
}

// Start new client
cl, err := NewClient("tcp", ":8080", opts...)
if err != nil {
  panic(err)
}

// When no longer needed, the client must be closed
defer cl.Close()

// The client can be used directly to create stubs to consume
// specific DRPC services.
// RPC request
mySvc := samplev1.NewDRPCFooAPIClient(cl)
res, _ := mySvc.Ping(context.Background(), &emptypb.Empty{})

Custom Middleware

You can provide your own custom middleware to extend/adjust the processing of RPC requests on both server and client using the decorator pattern. You can then use the WithMiddleware and WithClientMiddleware options when creating a new server or client instance.

# Packages

No description provided by the author
Package ws provides a WebSocket proxy with support for bidirectional streaming on DRPC servers.

# Functions

ContextWithMetadata adds custom data to a given context.
LoadCertificate provides a helper method to conveniently parse and existing certificate and corresponding private key.
MetadataFromContext retrieve any custom metadata available on the provided context.
NewClient returns a ready-to-use DRPC client instance.
NewServer returns a ready-to-use server instance.
WithAuthByCertificate enables certificate-based authentication on the server.
WithAuthCertificate enabled certificate-based client authentication with the provided credentials.
WithClientMiddleware register the provided middleware to customize/extend the processing of RPC requests.
WithClientTLS adjust the client to establish a secure communication channel with the server.
WithHTTP enable access to the services exposed by the server via HTTP / JSON.
WithMiddleware register the provided middleware to customize/extend the processing of RPC requests.
WithPoolCapacity adjust the max limit of concurrent DRPC connections a single client instance can support.
WithPort specifies which TCP port the server use.
WithProtocolHeader ensure the client connections include the protocol selection header.
WithServiceProvider can be used to expose RPC services described and implemented by "sp" through a server instance.
WithTLS enables the server to use secure communication channels with the provided credentials and settings.
WithUnixSocket specifies the path to a UNIX socket to use as main access point.
WithWebSocketProxy enable bidirectional streaming on the DRPC server via websocket connections.

# Structs

Client represents an instance used to consume DRPC services offered by other entities in the network.
ClientTLS defines the configuration options available when establishing a secure communication channel with a server.
Server instances are intended to expose DRPC services for network-based consumption.
ServerTLS provides available settings to enable secure TLS communications.

# Interfaces

ServiceProvider elements define the services that are to be exposed through a server instance.

# Type aliases

ClientOption allows adjusting client settings following a functional pattern.
Option allows adjusting server settings following a functional pattern.