NetGeX is a comprehensive toolkit for building robust gRPC and HTTP/REST services in Go with integrated support for metrics, profiling, health checks, and graceful shutdown management.
This package offers a unified approach to create and manage various server components:
- gRPC servers with reflection and health checks
- HTTP/REST gateway for gRPC services
- Metrics servers for Prometheus
- Profiling servers with pprof
- Graceful shutdown management
- Environment-based configuration
- JSON marshaling customization
- CORS configuration
server/- Main server implementationservice/- Service registration interfacesconfig/- Configuration utilitiessplash/- Terminal startup displayinternal/- Internal implementation details:grpc/- gRPC server implementationgateway/- HTTP/REST gateway server implementationmetrics/- Metrics server for Prometheuspprof/- Profiling serverpyroscope/- Continuous profiling
examples/- Example implementations
- Go 1.18+
- Protocol buffer compiler (for gRPC services)
- gRPC Gateway (for HTTP/REST support)
go get -u github.com/legrch/netgexThe server package uses environment variables for configuration:
| Variable | Description | Default |
|---|---|---|
LOG_LEVEL |
Logging level | info |
GRPC_ADDRESS |
gRPC server address | :9090 |
HTTP_ADDRESS |
HTTP/REST gateway address | :8080 |
METRICS_ADDRESS |
Metrics server address | :9091 |
PPROF_ADDRESS |
pprof server address | :6060 |
REFLECTION_ENABLED |
Enable gRPC reflection | true |
HEALTH_CHECK_ENABLED |
Enable health checks | true |
CLOSE_TIMEOUT |
Timeout for graceful shutdown | 10s |
SWAGGER_ENABLED |
Enable Swagger UI | true |
SWAGGER_DIR |
Directory containing swagger files | ./api |
SWAGGER_BASE_PATH |
Base path for swagger UI | / |
The service.Registrar interface defines the contract for services that can register with both gRPC and HTTP/REST servers:
type Registrar interface {
// RegisterGRPC registers the gRPC service with the gRPC server
RegisterGRPC(*grpc.Server)
// RegisterHTTP registers the HTTP/REST handlers with the gateway mux
RegisterHTTP(context.Context, *runtime.ServeMux, string, []grpc.DialOption) error
}The server.Server provides a unified way to initialize and run your application with all components:
// Create server options
opts := []server.Option{
server.WithLogger(logger),
server.WithServices(myService),
server.WithCloseTimeout(5 * time.Second),
server.WithGRPCAddress(":50051"),
server.WithHTTPAddress(":8080"),
server.WithReflection(true),
server.WithHealthCheck(true),
server.WithGatewayCORS(corsOptions),
server.WithSwaggerDir("./api/swagger"),
server.WithSwaggerBasePath("/api/v1"),
}
// Create server
srv := server.NewServer(opts...)
// Run the server
if err := srv.Run(ctx); err != nil {
logger.Error("server error", "error", err)
os.Exit(1)
}Here's a complete example of using the server package:
package main
import (
"context"
"log/slog"
"os"
"os/signal"
"syscall"
"time"
"github.com/legrch/netgex/server"
"github.com/legrch/netgex/service"
"github.com/rs/cors"
"google.golang.org/grpc"
"google.golang.org/grpc/runtime"
)
func main() {
// Create a context that will be canceled on SIGINT or SIGTERM
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()
// Create a logger
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelInfo,
}))
// Create service registrars
myService := NewMyServiceRegistrar()
// Create CORS options
corsOptions := cors.Options{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Accept", "Content-Type", "Content-Length", "Accept-Encoding", "Authorization"},
}
// Create server options
opts := []server.Option{
server.WithLogger(logger),
server.WithServices(myService),
server.WithCloseTimeout(5 * time.Second),
server.WithGRPCAddress(":50051"),
server.WithHTTPAddress(":8080"),
server.WithReflection(true),
server.WithHealthCheck(true),
server.WithGatewayCORS(corsOptions),
server.WithSwaggerDir("./api/swagger"),
server.WithSwaggerBasePath("/api/v1"),
}
// Create server
srv := server.NewServer(opts...)
// Run the server
if err := srv.Run(ctx); err != nil {
logger.Error("server error", "error", err)
os.Exit(1)
}
}
// NewMyServiceRegistrar creates a new service registrar
func NewMyServiceRegistrar() service.Registrar {
// Implement your service registrar here
return &myServiceRegistrar{}
}
// myServiceRegistrar implements the service.Registrar interface
type myServiceRegistrar struct{}
// RegisterGRPC registers the gRPC service with the gRPC server
func (s *myServiceRegistrar) RegisterGRPC(server *grpc.Server) {
// Register your gRPC service here
// Example: pb.RegisterMyServiceServer(server, s.service)
}
// RegisterHTTP registers the HTTP/REST handlers with the gateway mux
func (s *myServiceRegistrar) RegisterHTTP(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) error {
// Register your HTTP/REST handlers here
// Example: return pb.RegisterMyServiceHandlerFromEndpoint(ctx, mux, endpoint, opts)
return nil
}The server package provides the following configuration options:
WithLogger(logger *slog.Logger)- Sets the logger for the serverWithConfig(config *config.Config)- Sets the configuration for the serverWithCloseTimeout(timeout time.Duration)- Sets the timeout for graceful shutdownWithGRPCAddress(address string)- Sets the gRPC server addressWithHTTPAddress(address string)- Sets the HTTP server addressWithMetricsAddress(address string)- Sets the metrics server addressWithPprofAddress(address string)- Sets the pprof server addressWithSwaggerDir(dir string)- Sets the directory containing swagger filesWithSwaggerBasePath(path string)- Sets the base path for swagger UIWithReflection(enabled bool)- Enables or disables gRPC reflectionWithHealthCheck(enabled bool)- Enables or disables health checksWithServices(registrars ...service.Registrar)- Sets the service registrarsWithProcesses(processes ...Process)- Adds additional processes to the server
WithGRPCServerOptions(options ...grpc.ServerOption)- Sets additional options for the gRPC serverWithGRPCUnaryInterceptors(interceptors ...grpc.UnaryServerInterceptor)- Sets the unary interceptors for the gRPC serverWithGRPCStreamInterceptors(interceptors ...grpc.StreamServerInterceptor)- Sets the stream interceptors for the gRPC serverWithGatewayMuxOptions(options ...runtime.ServeMuxOption)- Sets the ServeMux options for the gateway serverWithGatewayCORS(options cors.Options)- Enables CORS with the specified options for the gateway
The gateway server supports customizable JSON marshaling through runtime.ServeMuxOption:
server.WithGatewayMuxOptions(
runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{
MarshalOptions: protojson.MarshalOptions{
UseProtoNames: true,
EmitUnpopulated: true,
UseEnumNumbers: false,
AllowPartial: true,
Multiline: true,
Indent: " ",
},
}),
)Options include:
UseProtoNames- Use proto field names instead of JSON namesEmitUnpopulated- Include unpopulated fields in outputUseEnumNumbers- Use enum numbers instead of string namesAllowPartial- Allow partial messagesMultiline- Format output with multiple linesIndent- Set indentation for multiline output
You can add custom processes to the server by implementing the Process interface:
type Process interface {
PreRun(ctx context.Context) error
Run(ctx context.Context) error
Shutdown(ctx context.Context) error
}Then add your process to the server:
server.WithProcesses(yourCustomProcess)See the examples/ directory for complete examples of how to use the server package:
simple/- Basic gRPC and gateway server setupadvanced/- Advanced configuration with service registration, Swagger, and morejson/- Examples of JSON configuration for the gatewayconfig/- Environment-based configuration examples
This project uses Task as a task runner instead of Make. To get started:
- Install Task:
go install github.com/go-task/task/v3/cmd/task@latest - Run
taskto see available commands
Common tasks:
task lint- Run linterstask test- Run teststask test:coverage- Run tests with coverage reporttask mock- Generate mocks
The project follows a structured release process:
- Prepare a release:
task prepare-release -- 1.2.3 - Update the CHANGELOG.md
- Create the release:
task release
For detailed information about creating releases, see docs/RELEASING.md.
- gRPC - gRPC documentation
- gRPC Gateway - gRPC Gateway documentation
- Protocol Buffers - Protocol Buffers documentation
This project is licensed under the MIT License - see the LICENSE file for details.