mix

package module
v1.21.2 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2026 License: MIT Imports: 45 Imported by: 0

README

mix

Go Reference

mix 是一个开箱即用的 Go 微服务运行时:在同一进程中同时暴露 HTTPgRPC,并内置可观测性、访问日志与优雅关停。

适合与 hopeio/protobuf 工具链配合,快速搭建基于 Protobuf 的云原生服务。

server

特性

  • 同端口多协议 — HTTP/1.1、明文 HTTP/2(gRPC)共用主监听地址;按 Content-Type 自动分发到 gRPC 或 HTTP 处理器
  • HTTP/3 — 基于 quic-go 可选启用
  • 请求上下文 — 通过 mix.Metadata 在 HTTP / gRPC 链路中传递 trace、token、logger 等
  • 访问日志 — HTTP 与 gRPC 均可记录请求/响应体,支持路径前缀过滤
  • OpenTelemetry — HTTP、gRPC 链路追踪与指标,与 hopeio/gox 日志字段对齐
  • 内部端口 — 默认 :8081 暴露 OpenAPI 文档(Redoc)与 pprof 调试端点
  • CORS / 中间件 / TLS — 通过 Option 组合配置
  • 优雅关停 — 监听 SIGINT / SIGTERM,依次停止 gRPC 与 HTTP

架构

                    ┌─────────────────────────────────┐
  Client ──────────►│  :8080  主服务(HTTP + gRPC)    │
                    │  ├─ HTTP  → Gin / ServeMux / …  │
                    │  └─ gRPC  → grpc.Server         │
                    └─────────────────────────────────┘
                    ┌─────────────────────────────────┐
  运维 / 文档 ──────►│  :8081  内部端口                 │
                    │  ├─ /openapi  Redoc 文档        │
                    │  └─ /debug    pprof             │
                    └─────────────────────────────────┘

快速开始

安装
go get github.com/hopeio/mix
最小示例
package main

import (
	"net/http"

	"github.com/hopeio/mix"
	"google.golang.org/grpc"
)

func main() {
	mix.NewServer(
		mix.WithHttpHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.Write([]byte("hello"))
		})),
		mix.WithGrpcHandler(func(s *grpc.Server) {
			// pb.RegisterYourServiceServer(s, &impl{})
		}),
	).Run()
}

完整示例见 _example/

go run ./_example

_example 演示了 gRPC 服务注册,以及通过 gox/net/http/grpc/gateway 将 RPC 暴露为 HTTP 接口。

配置选项

Option 说明
WithHttpHandler 主 HTTP 处理器(必填)
WithGrpcHandler 注册 gRPC 服务
WithHttp 自定义 http.Server 字段(地址、超时等)
WithHTTP3 启用 HTTP/3
WithInternalServer 自定义内部端口(OpenAPI / pprof)
WithCors 跨域配置
WithOtel OpenTelemetry
WithMiddleware HTTP 中间件链
WithGrpc gRPC 拦截器与 ServerOption
请求元数据

在 Handler 中通过 context 获取请求元数据:

import "github.com/hopeio/mix"

func handler(ctx context.Context) {
	md := mix.GetMetadata(ctx)
	if md != nil {
		_ = md.TraceId
		_ = md.Token
		md.Set("key", "value")
	}
}
与配置注入框架配合

Server 实现了 BeforeInject / AfterInject,可与 hopeio/initialize 等 DI 框架集成:

global.Conf.Server.WithOptions(
	mix.WithHttpHandler(app),
	mix.WithGrpcHandler(api.GrpcRegister),
).Run()

工具链

mix 本身不负责代码生成,推荐配合 hopeio 系列工具使用:

安装 protoc 插件
  • 安装 protoc
  • 安装 hopeio 工具集:
go run $(go list -m -f {{.Dir}} github.com/hopeio/protobuf)/tools/install_tools.go
生成代码
protogen go -d -e -w -v -i _example/proto -o _example/protobuf
标志 含义
-d OpenAPI 文档
-e 枚举扩展
-w Gin gRPC-Gateway
-v 请求校验代码
-g GraphQL(可选)

也可使用 Docker:

docker run --rm -v $PWD:/work jybl/protogen \
  protogen go -d -e -w -i $proto_path -o $proto_output_path

生成物可对接:

  • Gin Gatewayprotoc-gen-grpc-gin 生成的路由
  • grpc-gateway — 标准 google.api.http 注解

默认端口

端口 用途
:8080 主服务(HTTP + gRPC)
:8081 OpenAPI 文档 / pprof

相关项目

仓库 说明
hopeio/gox 日志、HTTP 工具、gRPC-Gateway 封装
hopeio/protobuf protoc 插件与 protogen CLI
hopeio/scaffold OTel、Prometheus、JWT 等脚手架
hopeio/initialize 配置加载与服务初始化

License

MIT

Documentation

Index

Constants

View Source
const (
	ContentTypeJson     = "json"
	ContentTypeProtobuf = "protobuf"
)
View Source
const ScopeName = "github.com/hopeio/mix"

Variables

View Source
var MetadataKey = metadataKey{}

Functions

func DefaultAccessLog

func DefaultAccessLog(ctx context.Context, param *AccessLogParam)

func DefaultGrpcAccessLog

func DefaultGrpcAccessLog(ctx context.Context, param *GrpcAccessLogParam)

func WithMetadata

func WithMetadata(ctx context.Context, metadata *Metadata) context.Context

Types

type AccessLog

type AccessLog = func(ctx context.Context, pram *AccessLogParam)

type AccessLogConfig

type AccessLogConfig struct {
	RecordFunc      AccessLog
	ExcludePrefixes []string
	IncludePrefixes []string
}

type AccessLogParam

type AccessLogParam struct {
	Method, Url string
	*httpx.Recorder
	Metadata *Metadata
}

type Body

type Body struct {
	ContentType string
	Raw         []byte
	Data        any
}

type CorsConfig

type CorsConfig struct {
	Enabled bool
	cors.Options
}

type DebugHandlerConfig

type DebugHandlerConfig struct {
	Enabled   bool
	UriPrefix string
}

type GRPCStatus

type GRPCStatus interface {
	GRPCStatus() *status.Status
}

type GrpcAccessLog

type GrpcAccessLog = func(ctx context.Context, pram *GrpcAccessLogParam)

type GrpcAccessLogParam

type GrpcAccessLogParam struct {
	Method            string
	Request, Response any
	Err               error
	Metadata          *Metadata
}

type GrpcConfig

type GrpcConfig struct {
	Addr                     string
	RecordFunc               GrpcAccessLog
	Options                  []grpc.ServerOption
	UnaryServerInterceptors  []grpc.UnaryServerInterceptor
	StreamServerInterceptors []grpc.StreamServerInterceptor
}

type Http3Config

type Http3Config struct {
	Enabled bool
	http3.Server
	CertFile string
	KeyFile  string
}

type Metadata

type Metadata struct {
	sync.RWMutex
	Logger                *log.Logger
	Data                  any
	DataM                 map[any]any
	TraceId               string
	RequestType           RequestType
	Token                 string
	AuthRaw               []byte
	AuthID                string
	Request               *http.Request
	ResponseWriter        http.ResponseWriter
	RequestAt             time.Time
	GrpcMD                metadata.MD                // grpc only
	ServerTransportStream grpc.ServerTransportStream // grpc only
	AccessLogFields       []zap.Field
	Bagage                baggage.Baggage // can not edit
}

func GetMetadata

func GetMetadata(ctx context.Context) *Metadata

func (*Metadata) Del

func (m *Metadata) Del(key any)

func (*Metadata) Get

func (m *Metadata) Get(key any) any

func (*Metadata) Set

func (m *Metadata) Set(key, value any)

type OpenapiConfig

type OpenapiConfig struct {
	Enabled        bool
	UriPrefix, Dir string
}

type Option

type Option func(server *Server)

func WithContext

func WithContext(ctx context.Context) Option

func WithCors

func WithCors(handler func(cors *cors.Options)) Option

func WithGrpc

func WithGrpc(handler func(option *GrpcConfig)) Option

func WithGrpcHandler

func WithGrpcHandler(handler func(*grpc.Server)) Option

func WithHTTP3

func WithHTTP3(handler func(s *Http3Config)) Option

func WithHttp

func WithHttp(handler func(s *http.Server)) Option

func WithHttpHandler

func WithHttpHandler(handler http.Handler) Option

func WithInternalServer

func WithInternalServer(handler func(s *http.Server)) Option

func WithMiddleware

func WithMiddleware(mw ...httpx.Middleware) Option

func WithOtel

func WithOtel(handler func(otel *OtelConfig)) Option

type OtelConfig

type OtelConfig struct {
	Enabled      bool
	OtelhttpOpts []otelhttp.Option
	OtelgrpcOpts []otelgrpc.Option
}

func (*OtelConfig) SetOtelgrpcOptions

func (c *OtelConfig) SetOtelgrpcOptions(otelgrpcOpts []otelgrpc.Option)

func (*OtelConfig) SetOtelhttpOptions

func (c *OtelConfig) SetOtelhttpOptions(otelhttpOpts []otelhttp.Option)

type PrometheusConfig

type PrometheusConfig struct {
	Enabled bool
	HttpURI string
	promhttp.HandlerOpts
}

type RequestType

type RequestType int
const (
	RequestTypeHttp RequestType = iota
	RequestTypeGrpc
)

type Server

type Server struct {
	http.Server
	CertFile       string
	KeyFile        string
	AccessLog      AccessLogConfig
	HTTP3          Http3Config
	Cors           CorsConfig
	Grpc           GrpcConfig
	InternalServer http.Server
	Openapi        OpenapiConfig
	Otel           OtelConfig

	DebugHandler DebugHandlerConfig
	BaseContext  context.Context
	Middlewares  []httpx.Middleware
	HttpHandler  http.Handler
	GrpcHandler  func(*grpc.Server)
	// contains filtered or unexported fields
}

func NewServer

func NewServer(options ...Option) *Server

func (*Server) AfterInject

func (s *Server) AfterInject()

func (*Server) BeforeInject

func (s *Server) BeforeInject()

implement initialize

func (*Server) Init

func (s *Server) Init()

func (*Server) InternalHandler

func (s *Server) InternalHandler()

func (*Server) Run

func (s *Server) Run()

func (*Server) StreamAccess

func (s *Server) StreamAccess(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) (err error)

func (*Server) UnaryAccess

func (s *Server) UnaryAccess(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error)

func (*Server) WithContext

func (s *Server) WithContext(ctx context.Context) *Server

func (*Server) WithOptions

func (s *Server) WithOptions(options ...Option) *Server

Directories

Path Synopsis
api
client command

Jump to

Keyboard shortcuts

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