type PlaceOrderRequest struct { client requestgen.APIClient symbol string `param:"symbol,required"` } Your APIClient implementation for sending requests
//go:generate requestgen —type PlaceOrderRequest type PlaceOrderRequest struct { client requestgen.APIClient symbol string `param:"symbol,required"` } Add the go generate command with your type name
//go:generate requestgen —type PlaceOrderRequest type PlaceOrderRequest struct { client requestgen.APIClient symbol string `param:"symbol,required"` } Equivalent to this command curl -X POST -F symbol=BTCUSDT https://…….
// APIClient defines the request builder method and request method for the API service type APIClient interface { // NewRequest builds up the http request for public endpoints NewRequest(ctx context.Context, method, refURL string, params url.Values, payload interface{}) (*http.Request, error) // SendRequest sends the request object to the api gateway SendRequest(req *http.Request) (*Response, error) } Simply implement the following interface to support HTTP request:
type PlaceOrderRequest struct { client requestgen.APIClient // "buy" or "sell" side SideType `param:"side,required" validValues:"buy,sell"` } Simple Value Validator
type PlaceOrderRequest struct { client requestgen.APIClient // "buy" or "sell" side SideType `param:"side,required" validValues:"buy,sell"` } User-de fi ned types are supported type SideType string const ( SideTypeBuy SideType = "buy" SideTypeSell SideType = "sell" )
type PlaceOrderRequest struct { client requestgen.APIClient // page defines the query parameters for something like '?page=123' page *int64 `param:"page,query"` } Query parameter in the POST request
//go:generate requestgen -type PlaceOrderRequest -responseType .Response -responseDataField Data -responseDataType .Order type Response struct { Code string `json:"code"` Message string `json:"msg"` CurrentPage int `json:"currentPage"` PageSize int `json:"pageSize"` TotalNum int `json:"totalNum"` TotalPage int `json:"totalPage"` Data json.RawMessage `json:"data"` } Response Type
//go:generate requestgen -type PlaceOrderRequest -responseType .Response -responseDataField Data -responseDataType .Order type Response struct { Code string `json:"code"` Message string `json:"msg"` CurrentPage int `json:"currentPage"` PageSize int `json:"pageSize"` TotalNum int `json:"totalNum"` TotalPage int `json:"totalPage"` Data json.RawMessage `json:"data"` } Response Data Field Response Data Field
//go:generate requestgen -type PlaceOrderRequest -responseType .Response -responseDataField Data -responseDataType .Order type Response struct { Code string `json:"code"` Message string `json:"msg"` CurrentPage int `json:"currentPage"` PageSize int `json:"pageSize"` TotalNum int `json:"totalNum"` TotalPage int `json:"totalPage"` Data json.RawMessage `json:"data"` } Parsed into the Order struct
var apiResponse APIResponse if err := response.DecodeJSON(&apiResponse); err != nil { return nil, err } var data OrderResponse if err := json.Unmarshal(apiResponse.Data, &data); err != nil { return nil, err } return &data, nil The generated code Data Type
var apiResponse APIResponse if err := response.DecodeJSON(&apiResponse); err != nil { return nil, err } var data OrderResponse if err := json.Unmarshal(apiResponse.Data, &data); err != nil { return nil, err } return &data, nil The generated code Data Field
type ( // An ImportSpec node represents a single package import. ImportSpec struct { Doc *CommentGroup // associated documentation; or nil Name *Ident // local package name (including "."); or nil Path *BasicLit // import path Comment *CommentGroup // line comments; or nil EndPos token.Pos // end of spec (overrides Path.Pos if nonzero) } // A ValueSpec node represents a constant or variable declaration // (ConstSpec or VarSpec production). // ValueSpec struct { Doc *CommentGroup // associated documentation; or nil Names []*Ident // value names (len(Names) > 0) Type Expr // value type; or nil Values []Expr // initial values; or nil Comment *CommentGroup // line comments; or nil } ) import ( "golang.org/x/tools/go/packages" ) a := 1 + 2
Step 3 Resolve the AST node to Type Info switch decl := node.(type) { case *ast.FuncDecl: // get the first receiver node receiver := decl.Recv.List[0] // pass the receiver type token to the type info map receiverTypeAndValue, ok := pkg.TypesInfo.Types[receiver.Type] if !ok { return true } // inspect the REAL type switch v := recvTV.Type.(type) { case *types.Named: // type A int case *types.Pointer: // *int } } 5ZQF"OE7BMVFDPOUBJOTUIFUZQFJOGPSNBUJPO VTFUIFUZQFJOGPSNBUJPOUPDIFDL
Step 5 reformat the code import ( "go/format" ) src, err := format.Source(buf.Bytes()) if err != nil { // Should never happen, but can arise when developing this code. // The user can compile the output to see the error. log.Printf("warning: internal error: invalid Go generated: %s", err) log.Printf("warning: compile the package to analyze the error") return buf.Bytes() } return src