docs

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 1, 2025 License: MIT Imports: 1 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ConceptDatabase = map[string]Concept{
	"middleware": {
		Name:        "Middleware",
		Category:    "Core Concepts",
		Description: "Middleware in go-zero is a function that wraps HTTP handlers to add cross-cutting functionality. Middleware can handle authentication, logging, rate limiting, CORS, and more. go-zero supports both global middleware (applied to all routes) and route-specific middleware.\n\nMiddleware functions follow the pattern: func(next http.HandlerFunc) http.HandlerFunc\n\nMiddleware is registered in the .api file using the @server directive with the middleware keyword.",
		Example: `// Define middleware in middleware/auth.go
type AuthMiddleware struct {
    // dependencies
}

func NewAuthMiddleware() *AuthMiddleware {
    return &AuthMiddleware{}
}

func (m *AuthMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // Pre-processing
        token := r.Header.Get("Authorization")
        if token == "" {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }

        // Call next handler
        next(w, r)

        // Post-processing (if needed)
    }
}

// Register in .api file:
@server(
    middleware: Auth
)
service user-api {
    @handler LoginHandler
    post /user/login (LoginReq) returns (LoginResp)
}`,
		RelatedDocs: []string{
			"https://go-zero.dev/docs/concepts/middleware",
			"https://go-zero.dev/docs/tutorials/http/middleware",
		},
	},
	"api-definition": {
		Name:        "API Definition",
		Category:    "Core Concepts",
		Description: "The .api file is go-zero's Domain Specific Language (DSL) for defining HTTP services. It describes routes, request/response types, middleware, and service configuration in a declarative format.\n\nKey sections:\n- info: Service metadata\n- type: Request/response type definitions\n- @server: Route group configuration (prefix, middleware, etc.)\n- service: Service definition with handlers and routes",
		Example: `syntax = "v1"

info(
    title: "User API"
    desc: "User management service"
    author: "developer"
    version: "v1"
)

type (
    LoginReq {
        Username string ` + "`json:\"username\"`" + `
        Password string ` + "`json:\"password\"`" + `
    }

    LoginResp {
        Token string ` + "`json:\"token\"`" + `
        UserId int64 ` + "`json:\"user_id\"`" + `
    }
)

@server(
    prefix: /api/v1
    middleware: Auth
    group: user
)
service user-api {
    @handler LoginHandler
    post /user/login (LoginReq) returns (LoginResp)

    @handler GetUserHandler
    get /user/:id returns (UserInfo)
}`,
		RelatedDocs: []string{
			"https://go-zero.dev/docs/tutorials/http/api-definition",
			"https://go-zero.dev/docs/reference/api-syntax",
		},
	},
	"service-context": {
		Name:        "Service Context",
		Category:    "Core Concepts",
		Description: "ServiceContext is the dependency injection container in go-zero. It holds all shared dependencies like database connections, Redis clients, RPC clients, and configuration. The context is created once at startup and passed to all handlers.\n\nBenefits:\n- Centralized dependency management\n- Easy to test (mock dependencies)\n- Singleton pattern for shared resources\n- Type-safe dependency access",
		Example: `// Define in internal/svc/servicecontext.go
type ServiceContext struct {
    Config config.Config
    UserModel model.UserModel
    RedisClient *redis.Redis
}

func NewServiceContext(c config.Config) *ServiceContext {
    conn := sqlx.NewMysql(c.Mysql.DataSource)
    return &ServiceContext{
        Config: c,
        UserModel: model.NewUserModel(conn, c.CacheRedis),
        RedisClient: redis.MustNewRedis(c.Redis),
    }
}

// Use in handler
type LoginHandler struct {
    logx.Logger
    ctx    context.Context
    svcCtx *svc.ServiceContext
}

func (l *LoginHandler) Login(req *types.LoginReq) (*types.LoginResp, error) {
    // Access dependencies through svcCtx
    user, err := l.svcCtx.UserModel.FindOneByUsername(l.ctx, req.Username)
    if err != nil {
        return nil, err
    }

    return &types.LoginResp{
        Token: "...",
        UserId: user.Id,
    }, nil
}`,
		RelatedDocs: []string{
			"https://go-zero.dev/docs/concepts/service-context",
		},
	},
	"rpc": {
		Name:        "RPC Services",
		Category:    "Core Concepts",
		Description: "go-zero RPC services use gRPC for inter-service communication. Services are defined using Protocol Buffers (.proto files), and go-zero generates both server and client code.\n\nRPC features:\n- Automatic code generation from .proto files\n- Built-in service discovery (etcd, consul, kubernetes)\n- Load balancing\n- Circuit breaker\n- Interceptors for middleware functionality\n- Streaming support",
		Example: `// Define service in user.proto
syntax = "proto3";

package user;
option go_package = "./user";

message LoginRequest {
    string username = 1;
    string password = 2;
}

message LoginResponse {
    int64 user_id = 1;
    string token = 2;
}

service User {
    rpc Login(LoginRequest) returns (LoginResponse);
    rpc GetUser(GetUserRequest) returns (GetUserResponse);
}

// Generate code:
// goctl rpc protoc user.proto --go_out=. --go-grpc_out=. --zrpc_out=.

// Call RPC from API service:
type ServiceContext struct {
    UserRpc userclient.User
}

func NewServiceContext(c config.Config) *ServiceContext {
    return &ServiceContext{
        UserRpc: userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),
    }
}`,
		RelatedDocs: []string{
			"https://go-zero.dev/docs/tutorials/rpc/server",
			"https://go-zero.dev/docs/tutorials/rpc/client",
		},
	},
	"model": {
		Name:        "Database Models",
		Category:    "Core Concepts",
		Description: "go-zero provides automatic model generation from database schema. Models include CRUD operations, cache management, and connection pooling.\n\nFeatures:\n- Auto-generated from table schema or SQL DDL\n- Redis cache integration\n- Prepared statements\n- Transaction support\n- Customizable query methods\n- Support for MySQL, PostgreSQL, MongoDB",
		Example: `// Generate model from database:
// goctl model mysql datasource -url="user:pass@tcp(127.0.0.1:3306)/database" -table="user" -dir="./model"

// Generated model usage:
type (
    userModel interface {
        Insert(ctx context.Context, data *User) (sql.Result, error)
        FindOne(ctx context.Context, id int64) (*User, error)
        Update(ctx context.Context, data *User) error
        Delete(ctx context.Context, id int64) error
    }

    defaultUserModel struct {
        sqlc.CachedConn
        table string
    }

    User struct {
        Id       int64  ` + "`db:\"id\"`" + `
        Username string ` + "`db:\"username\"`" + `
        Password string ` + "`db:\"password\"`" + `
        CreateTime time.Time ` + "`db:\"create_time\"`" + `
    }
)

// Use in service:
user, err := l.svcCtx.UserModel.FindOne(l.ctx, userId)
if err != nil {
    return nil, err
}`,
		RelatedDocs: []string{
			"https://go-zero.dev/docs/tutorials/model/mysql",
			"https://go-zero.dev/docs/tutorials/model/cache",
		},
	},
	"configuration": {
		Name:        "Configuration",
		Category:    "Core Concepts",
		Description: "go-zero uses YAML configuration files to manage service settings. Configuration is automatically loaded and validated at startup. Supports environment variable expansion.\n\nCommon config sections:\n- Server: HTTP/RPC server settings (port, timeout, etc.)\n- Database: MySQL, PostgreSQL connection strings\n- Cache: Redis configuration\n- Log: Logging level and format\n- Telemetry: Prometheus, tracing settings",
		Example: `# etc/user-api.yaml
Name: user-api
Host: 0.0.0.0
Port: 8888

# Database configuration
Mysql:
  DataSource: user:password@tcp(localhost:3306)/users?charset=utf8mb4&parseTime=true

# Cache configuration
CacheRedis:
  - Host: localhost:6379
    Pass: ""
    Type: node

# Redis configuration
Redis:
  Host: localhost:6379
  Type: node
  Pass: ""

# Log configuration
Log:
  ServiceName: user-api
  Mode: console
  Level: info

# Telemetry
Prometheus:
  Host: 0.0.0.0
  Port: 9091
  Path: /metrics

# Load in code:
var c config.Config
conf.MustLoad(*configFile, &c)`,
		RelatedDocs: []string{
			"https://go-zero.dev/docs/tutorials/configuration/overview",
		},
	},
	"error-handling": {
		Name:        "Error Handling",
		Category:    "Best Practices",
		Description: "go-zero provides structured error handling with custom error codes and messages. Errors can be returned from handlers and automatically formatted into HTTP responses.\n\nError handling approaches:\n1. Return errors directly - converted to 500 status\n2. Use httpx.Error() for custom status codes\n3. Register custom error handler with httpx.SetErrorHandler()\n4. Define error types for different scenarios",
		Example: `// Custom error handler
func ErrorHandler(err error) (int, interface{}) {
    switch e := err.(type) {
    case *ValidationError:
        return http.StatusBadRequest, map[string]interface{}{
            "code": 400,
            "message": e.Message,
            "field": e.Field,
        }
    case *BusinessError:
        return e.StatusCode, map[string]interface{}{
            "code": e.Code,
            "message": e.Message,
        }
    default:
        return http.StatusInternalServerError, map[string]interface{}{
            "code": 500,
            "message": "Internal server error",
        }
    }
}

// Register in main.go
httpx.SetErrorHandler(ErrorHandler)

// Use in handler
func (l *LoginLogic) Login(req *types.LoginReq) (*types.LoginResp, error) {
    if req.Username == "" {
        return nil, &ValidationError{
            Field: "username",
            Message: "username is required",
        }
    }
    // ... logic
}`,
		RelatedDocs: []string{
			"https://go-zero.dev/docs/tutorials/http/error-handling",
		},
	},
	"jwt": {
		Name:        "JWT Authentication",
		Category:    "Best Practices",
		Description: "go-zero has built-in JWT support for stateless authentication. JWT middleware can be configured in .api files to protect routes.\n\nFeatures:\n- Automatic token validation\n- Claims extraction\n- Token expiration handling\n- Custom secret key per service\n- Integration with middleware chain",
		Example: `// Configure JWT in .api file
@server(
    jwt: Auth
    prefix: /api/v1
)
service user-api {
    @handler GetUserInfoHandler
    get /user/info returns (UserInfoResp)
}

// Configure in config.yaml
Auth:
  AccessSecret: your-secret-key
  AccessExpire: 7200

// Generate token in login handler
func (l *LoginLogic) Login(req *types.LoginReq) (*types.LoginResp, error) {
    // Verify credentials...

    now := time.Now().Unix()
    accessExpire := l.svcCtx.Config.Auth.AccessExpire

    token, err := l.getJwtToken(l.svcCtx.Config.Auth.AccessSecret,
        now, accessExpire, userId)
    if err != nil {
        return nil, err
    }

    return &types.LoginResp{
        Token: token,
        Expire: now + accessExpire,
    }, nil
}

// Extract claims in protected handler
userId := l.ctx.Value("userId").(json.Number).Int64()`,
		RelatedDocs: []string{
			"https://go-zero.dev/docs/tutorials/http/jwt",
		},
	},
	"cache": {
		Name:        "Cache",
		Category:    "Performance",
		Description: "go-zero provides automatic Redis caching for database models. Cache is managed transparently with cache-aside pattern.\n\nCache features:\n- Automatic cache key generation\n- Cache miss handling\n- Cache invalidation on updates/deletes\n- Configurable TTL\n- Support for cache tags\n- Distributed cache consistency",
		Example: `// Model with cache
func NewUserModel(conn sqlx.SqlConn, c cache.CacheConf) UserModel {
    return &customUserModel{
        defaultUserModel: &defaultUserModel{
            CachedConn: sqlc.NewConn(conn, c),
            table:      "` + "`user`" + `",
        },
    }
}

// Cache is used automatically
user, err := l.svcCtx.UserModel.FindOne(l.ctx, userId)
// First call: queries DB and caches result
// Subsequent calls: returns from cache

// Update invalidates cache
err = l.svcCtx.UserModel.Update(l.ctx, user)
// Cache entry is automatically deleted

// Configure cache in config.yaml
CacheRedis:
  - Host: localhost:6379
    Pass: ""
    Type: node`,
		RelatedDocs: []string{
			"https://go-zero.dev/docs/tutorials/model/cache",
		},
	},
	"validation": {
		Name:        "Request Validation",
		Category:    "Best Practices",
		Description: "go-zero supports automatic request validation using struct tags. Validation is performed before the handler is called.\n\nValidation tags:\n- optional: Field is optional\n- options: Enum validation\n- range: Numeric range validation\n- default: Default value if not provided\n- Custom validators can be added",
		Example: `// Define validation in types
type LoginReq {
    Username string ` + "`json:\"username\" validate:\"required,min=3,max=20\"`" + `
    Password string ` + "`json:\"password\" validate:\"required,min=6\"`" + `
    Email    string ` + "`json:\"email,optional\" validate:\"email\"`" + `
}

// Or use go-zero's built-in validation in .api file
type CreateUserReq {
    Username string ` + "`json:\"username\"`" + ` // required by default
    Age      int    ` + "`json:\"age,optional\"`" + ` // optional field
    Gender   string ` + "`json:\"gender,options=male|female\"`" + ` // enum validation
    Score    int    ` + "`json:\"score,range=[0:100]\"`" + ` // range validation
}

// Custom validation in handler
func (l *CreateUserLogic) CreateUser(req *types.CreateUserReq) error {
    if req.Age != 0 && (req.Age < 0 || req.Age > 150) {
        return errors.New("invalid age")
    }
    // ... logic
}`,
		RelatedDocs: []string{
			"https://go-zero.dev/docs/tutorials/http/parameter",
		},
	},
}

ConceptDatabase holds all go-zero framework concepts

View Source
var MigrationDatabase = map[string]MigrationGuide{
	"gin-to-gozero": {
		FromFramework: "Gin",
		ToGoZero:      "go-zero API service",
		Difficulty:    "Easy",
		KeyDifferences: `Main differences:
1. Route definition: Gin uses code, go-zero uses .api DSL
2. Handler structure: go-zero separates handler and logic layers
3. Dependency injection: go-zero uses ServiceContext
4. Code generation: go-zero auto-generates boilerplate`,
		Example: `// Gin handler
func LoginHandler(c *gin.Context) {
    var req LoginReq
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }

    // business logic here
    c.JSON(200, gin.H{"token": "xxx"})
}

// go-zero equivalent
// 1. Define in .api file:
type LoginReq {
    Username string ` + "`json:\"username\"`" + `
    Password string ` + "`json:\"password\"`" + `
}

type LoginResp {
    Token string ` + "`json:\"token\"`" + `
}

service user-api {
    @handler LoginHandler
    post /user/login (LoginReq) returns (LoginResp)
}

// 2. Implement in logic file:
func (l *LoginLogic) Login(req *types.LoginReq) (*types.LoginResp, error) {
    // business logic here
    return &types.LoginResp{
        Token: "xxx",
    }, nil
}`,
		Steps: []string{
			"1. Create .api file to define routes and types (replaces Gin router setup)",
			"2. Run 'goctl api go -api user.api -dir .' to generate code",
			"3. Move business logic from Gin handlers to generated logic files",
			"4. Replace Gin context usage with go-zero types and error handling",
			"5. Move middleware to go-zero middleware pattern",
			"6. Update configuration to use YAML instead of Gin config",
		},
	},
	"echo-to-gozero": {
		FromFramework: "Echo",
		ToGoZero:      "go-zero API service",
		Difficulty:    "Easy",
		KeyDifferences: `Main differences:
1. Echo uses echo.Context, go-zero uses generated types
2. Route definition: Echo uses code, go-zero uses .api DSL
3. Middleware: Similar pattern but different signature
4. Error handling: go-zero has centralized error handler`,
		Example: `// Echo handler
func login(c echo.Context) error {
    req := new(LoginRequest)
    if err := c.Bind(req); err != nil {
        return c.JSON(400, map[string]string{"error": err.Error()})
    }

    return c.JSON(200, map[string]string{"token": "xxx"})
}

// go-zero logic
func (l *LoginLogic) Login(req *types.LoginReq) (*types.LoginResp, error) {
    // business logic
    return &types.LoginResp{Token: "xxx"}, nil
}`,
		Steps: []string{
			"1. Map Echo routes to .api file definitions",
			"2. Generate go-zero code structure",
			"3. Convert Echo handlers to go-zero logic functions",
			"4. Adapt Echo middleware to go-zero middleware pattern",
			"5. Replace echo.Context usage with request/response types",
			"6. Set up centralized error handler",
		},
	},
	"grpc-to-gozero-rpc": {
		FromFramework: "gRPC (vanilla)",
		ToGoZero:      "go-zero RPC service",
		Difficulty:    "Easy",
		KeyDifferences: `Main differences:
1. go-zero adds automatic service discovery
2. Built-in load balancing and circuit breaker
3. Simplified client creation
4. Integrated with go-zero ecosystem (logging, tracing, metrics)`,
		Example: `// Vanilla gRPC server
type server struct {
    pb.UnimplementedUserServer
}

func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) {
    // logic
    return &pb.GetUserResponse{UserId: 1}, nil
}

// go-zero RPC (proto file is same, but generation and usage differ)
// Generate with: goctl rpc protoc user.proto --go_out=. --go-grpc_out=. --zrpc_out=.

// Server automatically gets:
// - Service discovery (etcd/consul/k8s)
// - Health checks
// - Metrics
// - Interceptors

// Client usage is simplified:
userRpc := userclient.NewUser(zrpc.MustNewClient(c.UserRpc))
resp, err := userRpc.GetUser(ctx, &user.GetUserRequest{UserId: 1})`,
		Steps: []string{
			"1. Keep existing .proto files (protobuf definitions stay the same)",
			"2. Use goctl to generate go-zero RPC code",
			"3. Migrate server implementation to generated logic files",
			"4. Update client code to use go-zero RPC client",
			"5. Configure service discovery (etcd, consul, or kubernetes)",
			"6. Add configuration files (YAML) for server and clients",
			"7. Enable metrics and tracing if needed",
		},
	},
	"springboot-to-gozero": {
		FromFramework: "Spring Boot",
		ToGoZero:      "go-zero microservices",
		Difficulty:    "Moderate",
		KeyDifferences: `Main differences:
1. Language: Java -> Go
2. Annotations -> .api/.proto files
3. Spring DI -> ServiceContext
4. JPA -> go-zero models
5. Compiled binary vs JVM`,
		Example: `// Spring Boot controller
@RestController
@RequestMapping("/api/user")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public ResponseEntity<LoginResp> login(@RequestBody LoginReq req) {
        return ResponseEntity.ok(userService.login(req));
    }
}

// go-zero equivalent
// .api file:
service user-api {
    @handler LoginHandler
    post /api/user/login (LoginReq) returns (LoginResp)
}

// Logic:
type LoginLogic struct {
    ctx    context.Context
    svcCtx *svc.ServiceContext
}

func (l *LoginLogic) Login(req *types.LoginReq) (*types.LoginResp, error) {
    // Access dependencies through svcCtx (like Spring DI)
    return l.svcCtx.UserService.Login(req)
}`,
		Steps: []string{
			"1. Map REST controllers to .api files",
			"2. Convert JPA entities to database models (use goctl model)",
			"3. Replace @Autowired with ServiceContext dependency injection",
			"4. Migrate service layer to go-zero logic layer",
			"5. Convert Java exceptions to Go error handling",
			"6. Replace Spring configuration with YAML config files",
			"7. Update deployment from JAR to Go binary",
			"8. Migrate Spring Security to go-zero JWT/middleware",
		},
	},
	"nodejs-express-to-gozero": {
		FromFramework: "Node.js Express",
		ToGoZero:      "go-zero API service",
		Difficulty:    "Moderate",
		KeyDifferences: `Main differences:
1. Language: JavaScript/TypeScript -> Go
2. Async/await -> goroutines and channels
3. Express middleware -> go-zero middleware
4. Route definition: Code -> .api DSL
5. Package.json -> go.mod`,
		Example: `// Express route
app.post('/api/user/login', async (req, res) => {
    try {
        const { username, password } = req.body;
        const result = await userService.login(username, password);
        res.json(result);
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

// go-zero
// .api file:
type LoginReq {
    Username string ` + "`json:\"username\"`" + `
    Password string ` + "`json:\"password\"`" + `
}

service user-api {
    @handler LoginHandler
    post /api/user/login (LoginReq) returns (LoginResp)
}

// Logic:
func (l *LoginLogic) Login(req *types.LoginReq) (*types.LoginResp, error) {
    result, err := l.svcCtx.UserService.Login(req.Username, req.Password)
    if err != nil {
        return nil, err
    }
    return result, nil
}`,
		Steps: []string{
			"1. Map Express routes to .api file definitions",
			"2. Convert async/await patterns to goroutines where needed",
			"3. Migrate Express middleware to go-zero middleware",
			"4. Replace Mongoose/Sequelize with go-zero models",
			"5. Convert promises to Go error handling",
			"6. Update package dependencies (npm -> go modules)",
			"7. Rewrite JavaScript/TypeScript logic in Go",
			"8. Update deployment from Node.js to Go binary",
		},
	},
}

MigrationDatabase holds migration guides

Functions

This section is empty.

Types

type Concept

type Concept struct {
	Name        string
	Category    string
	Description string
	Example     string
	RelatedDocs []string
}

Concept represents a go-zero framework concept with explanation

func GetConceptByName

func GetConceptByName(name string) *Concept

GetConceptByName retrieves a specific concept by name

func SearchConcepts

func SearchConcepts(query string) []Concept

SearchConcepts searches for concepts matching the query

type MigrationGuide

type MigrationGuide struct {
	FromFramework  string
	ToGoZero       string
	Difficulty     string
	KeyDifferences string
	Example        string
	Steps          []string
}

MigrationGuide represents a migration guide from other frameworks to go-zero

func GetMigrationGuide

func GetMigrationGuide(fromFramework string) *MigrationGuide

GetMigrationGuide retrieves a specific migration guide

func SearchMigrationGuides

func SearchMigrationGuides(query string) []MigrationGuide

SearchMigrationGuides searches for migration guides matching the query

Jump to

Keyboard shortcuts

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