go-zero

repository·master·Indexed 12 days ago

https://github.com/zeromicro/go-zero

A Go framework providing a REST framework, configuration system, and integration for the Model Context Protocol (MCP). It includes a powerful configuration loader with environment variable support, the logx logging library, a MapReduce tool for concurrent data processing, and a Gateway server supporting gRPC reflection and protoset modes.

Tokens
51.3K
Snippets
170
Records
207
Agent score
96%

What's inside go-zero

  1. Understand go-zero core features and architecture

    master

    go-zero is a high-performance web and RPC framework designed for high-concurrency, resilient microservices. It is part of the CNCF Landscape.

    Key Features

    • Resilience by Design: Built-in adaptive circuit breakers, rate limiting, load shedding, and timeout control.
    • Code Generation: Powerful goctl tool for generating Go, iOS, Android, Kotlin, Dart, TypeScript, and JavaScript code from .api files.
    • Automatic Validation: Client request parameters are automatically validated based on .api definitions.
    • Service Mesh Capabilities: Built-in support for service discovery, load balancing, and call tracing.
    • Developer Productivity: Integrated middleware, cache management, and monitoring tools.

    Design Principles

    • Simplicity: Keeping things simple is the first principle.
    • High Availability: Stable operation under high concurrency.
    • Resilience: Fault-oriented programming with adaptive protection.
    • Developer Friendly: Encapsulating complexity to provide one way to do one thing.
    • Extensibility: Flexible architecture for growth.
  2. Support for gRPC streaming and Google well-known types

    master

    The goctl rpc module provides full support for advanced gRPC features:

    Streaming Patterns:

    • Server Streaming: rpc ServerStream(Req) returns (stream Reply);
    • Client Streaming: rpc ClientStream(stream Req) returns (Reply);
    • Bidirectional Streaming: rpc BidiStream(stream Req) returns (stream Reply);

    Google Well-Known Types: goctl automatically recognizes these types and generates the correct Go imports:

    Proto TypeGo Type
    google.protobuf.Emptyemptypb.Empty
    google.protobuf.Timestamptimestamppb.Timestamp
    google.protobuf.Durationdurationpb.Duration
    google.protobuf.Anyanypb.Any
    google.protobuf.Structstructpb.Struct
    google.protobuf.FieldMaskfieldmaskpb.FieldMask
    google.protobuf.*Valuewrapperspb.*Value
    service StreamService {
      rpc ServerStream(Req) returns (stream Reply);
      rpc ClientStream(stream Req) returns (Reply);
      rpc BidiStream(stream Req) returns (stream Reply);
    }
  3. Handle cross-package type resolution in goctl rpc

    master

    When an imported proto file has a different go_package than your main proto, goctl now automatically generates the correct Go import paths and qualified type references in your server, logic, and client code.

    Type Resolution Logic:

    • Simple Types (e.g., GetReq): Interpreted as pb.GetReq (no extra import needed).
    • Same-package Dot Notation (e.g., ext.ExtReq where ext shares the same go_package): Interpreted as pb.ExtReq (merged into the main package).
    • Cross-package Dot Notation (e.g., common.TypesReq with a different go_package): Interpreted as common.TypesReq with the corresponding import "example.com/demo/pb/common" automatically added to the generated files.
  4. Importing external proto files

    master

    You can import proto files from different directories using the -I or --proto_path flag. goctl supports:

    • Same directory imports: import "types.proto";
    • Subdirectory imports: import "common/types.proto";
    • External directory imports: Specifying paths outside the current project.
    • Transitive dependencies: If A imports B and B imports C, goctl will recursively resolve them.
    • Cross-package imports: Automatically handles correct Go imports even if proto files have different go_package definitions.
    goctl rpc protoc service.proto \
      --go_out=output --go-grpc_out=output --zrpc_out=output \
      --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
      --module=example.com/demo \
      -I . -I ./shared_protos -I /path/to/external_protos
  5. Implement gRPC streaming RPCs with goctl

    master

    The goctl rpc tool supports all three gRPC streaming patterns:

    1. Server streaming: The stream keyword is applied to the response type.
    2. Client streaming: The stream keyword is applied to the request type.
    3. Bidirectional streaming: The stream keyword is applied to both request and response types.

    When using goctl, the tool automatically generates separate logic files for each streaming RPC method within the internal/logic directory. For clients, goctl generates streaming client wrapper methods; you must use the returned gRPC stream object to call Send() and Recv() for message exchange.

  6. Directory structure for multiple services mode

    master

    When using the -m (--multiple) flag, goctl generates a specific directory structure to accommodate multiple services within one project. The services are grouped by name in key directories, but they share the main entry point and service context.

    Key structural characteristics:

    • client/: Contains subdirectories for each service (e.g., client/searchservice/).
    • internal/logic/: Contains subdirectories for each service's logic (e.g., internal/logic/notifyservice/).
    • internal/server/: Contains subdirectories for each service's server implementation (e.g., internal/server/searchservice/).
    • multisvc.go: The single entry point for the entire application.
    • internal/svc/servicecontext.go: A shared service context used by all services.
    • internal/config/config.go: A shared configuration file.
    • pb/: Contains the generated protobuf code for all services and shared messages.
    output/
    ├── client
    │   ├── notifyservice
    │   │   └── notifyservice.go
    │   └── searchservice
    │       └── searchservice.go
    ├── etc
    │   └── multisvc.yaml
    ├── go.mod
    ├── internal
    │   ├── config
    │   │   └── config.go
    │   ├── logic
    │   │   ├── notifyservice
    │   │   │   └── notifylogic.go
    │   │   └── searchservice
    │   │       └── searchlogic.go
    │   ├── server
    │   │   ├── notifyservice
    │   │   │   └── notifyserviceserver.go
    │   │   └── searchservice
    │   │       └── searchserviceserver.go
    │   └── svc
    │       └── servicecontext.go
    ├── multisvc.go
    └── pb
        ├── multi.pb.go
        ├── multi_grpc.pb.go
        └── shared.pb.go
  7. Understand the generated model code structure

    master

    The generated model code follows a specific pattern to facilitate both direct SQL execution and cached lookups.

    Key components include:

    • Interface: Defines the CRUD operations (e.g., Insert, FindOne, Update, Delete).
    • Struct: Represents the database table with db tags mapping fields to columns.
    • NewUserModel: A constructor that accepts a sqlx.SqlConn and cache.CacheConf to initialize the model with caching capabilities.
    • Caching Logic: Methods like FindOneByXxx use QueryRowIndex to check the cache for the primary key before querying the database. If a cache miss occurs, the database is queried, and the result is used to populate the cache.
    type ( 
    	UserModel interface {
    		Insert(data User) (sql.Result, error)
    		FindOne(id int64) (*User, error)
    		// ... other methods
    	}
    
    	User struct {
    		Id         int64     `db:"id"` 
    		Name       string    `db:"name"` 
    		// ... other fields
    	}
    
    	defaultUserModel struct {
    		sqlc.CachedConn
    		table string
    	}
    )
    
    func NewUserModel(conn sqlx.SqlConn, c cache.CacheConf) UserModel {
    	return &defaultUserModel{
    		CachedConn: sqlc.NewConn(conn, c),
    		table:      "user",
    	}
    }
  8. Support for Google Well-Known Types

    master

    goctl automatically recognizes and handles Google protobuf well-known types, generating the correct Go imports for them. You can use these directly as RPC parameter types.

    | Proto Type | Go Type |
    |-----------|---------|
    | `google.protobuf.Empty` | `emptypb.Empty` |
    | `google.protobuf.Timestamp` | `timestamppb.Timestamp` |
    | `google.protobuf.Duration` | `durationpb.Duration` |
    | `google.protobuf.Any` | `anypb.Any` |
    | `google.protobuf.Struct` | `structpb.Struct` |
    | `google.protobuf.FieldMask` | `fieldmaskpb.FieldMask` |
    | `google.protobuf.*Value` | `wrapperspb.*Value` |
  9. Understand the .api file syntax structure

    master

    The .api files used by goctl follow a specific structural order. While syntax blocks can technically be declared in any order, it is highly recommended to follow this sequence to improve readability and ensure compatibility with future strict mode enforcement:

    1. syntax declaration: Defines the API version.
    2. import blocks: Includes other .api files.
    3. info block: Provides metadata about the API service.
    4. type blocks: Defines request/response data structures.
    5. service blocks: Defines the actual API routes and handlers.
    6. hidden channels: Comments and documentation.
    syntax = "v1"
    
    import "foo.api"
    
    info(
        author: "songmeizi"
        desc: "description"
    )
    
    type Foo {
        Foo int `json:"foo"`
    }
    
    service foo-api {
        @handler foo
        post /foo (Foo) returns (Bar)
    }
  10. Support for streaming RPCs

    master

    The goctl rpc module fully supports all gRPC streaming modes:

    • Server-side streaming: rpc Method(Req) returns (stream Reply);
    • Client-side streaming: rpc Method(stream Req) returns (Reply);
    • Bidirectional streaming: rpc Method(stream Req) returns (stream Reply);
    service StreamService {
      rpc ServerStream(Req) returns (stream Reply);
      rpc ClientStream(stream Req) returns (Reply);
      rpc BidiStream(stream Req) returns (stream Reply);
    }
  11. Choose between SSE and Streamable HTTP transport

    master

    The MCP implementation supports two transport modes via configuration:

    1. SSE (Server-Sent Events): The original 2024-11-05 spec. Set useStreamable: false (default). Requires sseEndpoint (default /sse).
    2. Streamable HTTP: The newer 2025-03-26 spec for better connection management. Set useStreamable: true. Requires messageEndpoint (default /message).