grpcx

package module
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Nov 29, 2023 License: Apache-2.0 Imports: 29 Imported by: 0

README

gRPCX

gRPCX is a library for easily building gRPC services in Go. It has support for REST APIs, ORM, Database Migrations, Cache, Message Streaming, Structured Logging, Config, Healthchecks, Prometheus Metrics, and more.

It is meant to be a batteries-included framework for building gRPC services.

go get github.com/autom8ter/grpcx

Example


	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	cfg, err := grpcx.NewConfig()
	if err != nil {
		panic(err)
	}
	cfg.Set("auth.username", "test")
	cfg.Set("auth.password", "test")
	srv, err := grpcx.NewServer(
		ctx,
		cfg,
		// Register Auth provider
		grpcx.WithAuth(basicauth.New()),
		// Register Cache Provider
		grpcx.WithCache(redis2.InMemProvider),
		// Register Stream Provider
		grpcx.WithStream(redis2.InMemStreamProvider),
		// Register Context Tagger
		grpcx.WithContextTagger(maptags.Provider),
		// Register Logger
		grpcx.WithLogger(slog2.Provider),
		// Register Database
		grpcx.WithDatabase(sqlite.Provider),
	)
	if err != nil {
		panic(err)
	}
	go func() {
		if err := srv.Serve(ctx, grpcx.EchoService()); err != nil {
			panic(err)
		}
	}()

	conn, err := grpc.DialContext(ctx, fmt.Sprintf("localhost:%v", cfg.GetInt("api.port")), grpc.WithInsecure())
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	echoClient := echov1.NewEchoServiceClient(conn)
	ctx = metadata.AppendToOutgoingContext(ctx, "authorization", "test:test")
	resp, err := echoClient.Echo(ctx, &echov1.EchoRequest{
		Message: "hello",
	})
	if err != nil {
		panic(err)
	}
	println(resp.Message)

Features

  • gRPC
  • gRPC-gateway
  • Serve Gateway/gRPC same port
  • Flexible Provider/Interface based architecture: use the same code with different providers depending on tech stack
  • Metrics(prometheus)
  • Structured Logging(slog)
  • Database Migrations(golang-migrate)
  • Database dependency injection(sqlite,mysql,postgres)
  • Cache dependency injection(redis)
  • Stream dependency injection(redis,nats,kafka,rabbitmq)
  • Context Tagging Middleware(maptags)
  • Auth dependency injection(basicauth)
  • Flexible configuration(viper)
  • Graceful Shutdown
  • Request validation middleware/interceptor
  • Panic Recovery middleware/interceptor
  • CORS middleware
  • Rate Limiting middleware/interceptor
  • Tracing

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func LoadConfig

func LoadConfig(filePath string) (*viper.Viper, error)

LoadConfig loads a config file from the given path(if it exists) and sets defaults: api.name: grpcx api.port: 8080 logging.level: debug logging.request_body: false logging.tags: [method, context_id, error, metadata] database.migrate: true api.cors.enabled: false api.cors.allowed_origins: [*] api.cors.allowed_methods: [GET, POST, PUT, DELETE, OPTIONS, PATCH] api.cors.allowed_headers: [*] api.cors.exposed_headers: [*] api.cors.allow_credentials: true

func NewConfig

func NewConfig() (*viper.Viper, error)

NewConfig creates a new config instance with the appropriate defaults

Types

type CustomHTTPRoute

type CustomHTTPRoute struct {
	Method  string
	Path    string
	Handler runtime.HandlerFunc
}

CustomHTTPRoute is a custom route that can be added to the rest-gateway

type Server

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

Server is a grpc server with a rest-gateway

func NewServer

func NewServer(ctx context.Context, cfg *viper.Viper, opts ...ServerOption) (*Server, error)

NewServer creates a new server with the given config and options

Example
package main

import (
	"context"
	"fmt"

	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"

	"github.com/autom8ter/grpcx"
	echov1 "github.com/autom8ter/grpcx/gen/echo"
	"github.com/autom8ter/grpcx/providers/basicauth"
	"github.com/autom8ter/grpcx/providers/maptags"

	redis2 "github.com/autom8ter/grpcx/providers/redis"

	slog2 "github.com/autom8ter/grpcx/providers/slog"
	"github.com/autom8ter/grpcx/providers/sqlite"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	cfg, err := grpcx.NewConfig()
	if err != nil {
		panic(err)
	}
	cfg.Set("auth.username", "test")
	cfg.Set("auth.password", "test")
	srv, err := grpcx.NewServer(
		ctx,
		cfg,
		// Register Auth provider
		grpcx.WithAuth(basicauth.New()),
		// Register Cache Provider
		grpcx.WithCache(redis2.InMemProvider),
		// Register Stream Provider
		grpcx.WithStream(redis2.InMemStreamProvider),
		// Register Context Tagger
		grpcx.WithContextTagger(maptags.Provider),
		// Register Logger
		grpcx.WithLogger(slog2.Provider),
		// Register Database
		grpcx.WithDatabase(sqlite.Provider),
	)
	if err != nil {
		panic(err)
	}
	go func() {
		if err := srv.Serve(ctx, grpcx.EchoService()); err != nil {
			panic(err)
		}
	}()

	conn, err := grpc.DialContext(ctx, fmt.Sprintf("localhost:%v", cfg.GetInt("api.port")), grpc.WithInsecure())
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	echoClient := echov1.NewEchoServiceClient(conn)
	ctx = metadata.AppendToOutgoingContext(ctx, "authorization", "test:test")
	resp, err := echoClient.Echo(ctx, &echov1.EchoRequest{
		Message: "hello",
	})
	if err != nil {
		panic(err)
	}
	println(resp.Message)
}
Output:

func (*Server) Config

func (s *Server) Config() *viper.Viper

Config returns the server config

func (*Server) Providers

func (s *Server) Providers() providers.All

Providers returns the server providers

func (*Server) Serve

func (s *Server) Serve(ctx context.Context, services ...Service) error

Serve registers the given services and starts the server. This function blocks until the server is shutdown. The server will shutdown when the context is canceled or an interrupt signal is received. The server will start grpc/rest-gateway servers on the port specified by the config key "api.port" The server will register a health check at /health and a readiness check at /ready The server will register a metrics endpoint at /metrics if the config key "metrics.prometheus" is true

type ServerOption

type ServerOption func(opt *serverOpt)

ServerOption is a function that configures the server. All ServerOptions are optional.

func WithAuth

func WithAuth(auth providers.Auth) ServerOption

WithAuth adds an auth provider to the server

func WithAuthz added in v0.3.0

func WithAuthz(authorizers ...authorizer.Authorizer) ServerOption

WithAuthz adds the authorizers to the server (see github.com/autom8ter/protoc-gen-authorize)

func WithCache

func WithCache(provider providers.CacheProvider) ServerOption

WithCache adds a cache provider

func WithContextTagger

func WithContextTagger(tagger providers.ContextTaggerProvider) ServerOption

WithContextTagger adds a context tagger to the server

func WithCustomHTTPRoute

func WithCustomHTTPRoute(method, path string, handler runtime.HandlerFunc) ServerOption

WithCustomHTTPRoute adds a custom http route to the rest-gateway

func WithDatabase

func WithDatabase(provider providers.DatabaseProvider) ServerOption

WithDatabase adds a database provider

func WithGatewayOpts

func WithGatewayOpts(opts ...runtime.ServeMuxOption) ServerOption

WithGatewayOpts adds options to the grpc gateway

func WithLogger

func WithLogger(provider providers.LoggingProvider) ServerOption

WithLogger adds a logging provider

func WithMetrics

func WithMetrics(metrics providers.MetricsProvider) ServerOption

WithMetrics adds a metrics provider to the server

func WithRateLimit

func WithRateLimit(rateLimit providers.RateLimiterProvider) ServerOption

WithRateLimit adds a rate limiter to the server

func WithStream

func WithStream(provider providers.StreamProvider) ServerOption

WithStream adds a stream provider

func WithStreamInterceptors

func WithStreamInterceptors(interceptors ...grpc.StreamServerInterceptor) ServerOption

WithStreamInterceptors adds interceptors to the grpc server

func WithUnaryInterceptors

func WithUnaryInterceptors(interceptors ...grpc.UnaryServerInterceptor) ServerOption

WithUnaryInterceptors adds unary interceptors to the server

type Service

type Service interface {
	// Register registers a service with the server
	Register(ctx context.Context, cfg ServiceRegistrationConfig) error
}

Service is a an interface that registers a service with the server

type ServiceRegistration

type ServiceRegistration func(ctx context.Context, cfg ServiceRegistrationConfig) error

ServiceRegistration is a function that registers a service with the server

func EchoService

func EchoService() ServiceRegistration

EchoService returns a ServiceRegistration that registers an echo service

func (ServiceRegistration) Register

Register implements the Service interface

type ServiceRegistrationConfig

type ServiceRegistrationConfig struct {
	Config      *viper.Viper
	GrpcServer  *grpc.Server
	RestGateway *runtime.ServeMux
	Providers   providers.All
}

ServiceRegistrationConfig is the config passed to a service registration function

Directories

Path Synopsis
gen
echo
Package echov1 is a reverse proxy.
Package echov1 is a reverse proxy.
mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

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