Skip to content

goctl FAQ

How do I add custom logic without it being overwritten on re-generation?

Section titled “How do I add custom logic without it being overwritten on re-generation?”

goctl only generates stub logic files if they don’t already exist. It never overwrites files in internal/logic/. Re-running goctl api go on an existing project is safe — only missing files are created.

Use the --style flag:

Terminal window
goctl api go -api user.api -dir . --style go_zero
# produces: user_handler.go, create_user_logic.go, etc.

Options: gozero (default), go_zero, goZero.

go-zero does not include a built-in validator. Use go-playground/validator:

import "github.com/go-playground/validator/v10"
var validate = validator.New()
func (l *CreateUserLogic) CreateUser(req *types.CreateUserReq) (*types.CreateUserResp, error) {
if err := validate.Struct(req); err != nil {
return nil, errorx.NewCodeError(400, err.Error())
}
// ...
}

Define an error package:

package errorx
type CodeError struct {
Code int `json:"code"`
Msg string `json:"msg"`
}
func (e *CodeError) Error() string { return e.Msg }
func NewCodeError(code int, msg string) *CodeError {
return &CodeError{Code: code, Msg: msg}
}

Then register a custom error handler in main.go:

httpx.SetErrorHandler(func(err error) (int, any) {
var ce *errorx.CodeError
if errors.As(err, &ce) {
return http.StatusOK, ce
}
return http.StatusInternalServerError, nil
})

How to generate multiple services from one repo?

Section titled “How to generate multiple services from one repo?”

Run goctl from each service directory, each with its own .api or .proto file:

Terminal window
cd services/user && goctl api go -api user.api -dir .
cd services/order && goctl api go -api order.api -dir .