requestgen

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jun 18, 2023 License: MIT Imports: 15 Imported by: 0

README

requestgen

!!! This is a fork of the https://github.com/c9s/requestgen project !!

requestgen generates the cascade call for your request object

Installation

go install github.com/txt1899/cmd/requestgen

Usage

requestgen scans all the fields of the target struct, and generate setter methods and getParameters method.

package api

import "github.com/txt1899/requestgen"

//go:generate requestgen -type PlaceOrderRequest
type PlaceOrderRequest struct {
	// client is an optional field to implement.
	// If the API needs authentication, the client type should be `AuthenticatedAPIClient`. Otherwise, `APIClient`.
	// The `Do()` method will be generated if the client field is provided.
	// note, you will have to add flag "-url" and "-method" to specify your endpoint and the request method.
	client requestgen.AuthenticatedAPIClient
	
	// A combination of case-sensitive alphanumerics, all numbers, or all letters of up to 32 characters.
	clientOrderID *string `param:"clientOid,required" defaultValuer:"uuid()"`

	symbol string `param:"symbol,required"`

	// A combination of case-sensitive alphanumerics, all numbers, or all letters of up to 8 characters.
	tag *string `param:"tag"`

	// "buy" or "sell"
	side SideType `param:"side,required" validValues:"buy,sell"`

	orderType OrderType `param:"ordType" validValues:"limit,market"`

	size string `param:"size"`

	// limit order parameters
	price *string `param:"price,omitempty"`

	timeInForce *TimeInForceType `param:"timeInForce,omitempty" validValues:"GTC,GTT,FOK"`

	complexArg ComplexArg `param:"complexArg"`

	startTime *time.Time `param:"startTime,milliseconds" defaultValuer:"now()"`
}

Or you can run generate command manually like this:

go run ./cmd/requestgen -type PlaceOrderRequest -method GET -url "/api/v1/bullet" -debug ./example/api 

Then you can do:

req := &PlaceOrderRequest{}
err := req.Tag(..).
	OrderType(OrderTypeLimit).
	Side(SideTypeBuy).
	Do(ctx)
Embedding parameter in the URL

You can use the slug attribute to embed the parameter into the url:

//go:generate GetRequest -url "/api/v1/accounts/{accountID}" -type NewGetAccountRequest -responseDataType []Account
type NewGetAccountRequest struct {
	client requestgen.AuthenticatedAPIClient
	accountID string `param:"accountID,slug"`
}

Command Options

-submitFormat [submitDataForamt]

query: Usually used for query as get requests

from: Usually used for post requests, received in from format

json: Usually used for post requests, received in json format
// When the field tag contains "query"
// the field will be appended to the URL for sending the request
// even if the submit format is not "query".
type MyRequest struct {
	// ... other filed
	tag string `param:"tag, query"` // https://example.com/api/v1/order?tag=xxx
}

-responseType [responseTypeSelector]

When responseTypeSelector is not given, interface{} will be used for decoding the response content from the API server.

You can define your own responseType struct that can decode the API response, like this, e.g.,

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"`
	Orders      []Orders `json:"orders"`
}

And then use the type selector like this:

# if the type is in a relative package
requestgen ... -responseType '"./example/api".Response'

# if the type is in the same package
requestgen ... -responseType '".".Response'

When using requestgen with go:generate, you should handle the quote escaping for the type selector, for example:

//go:generate requestgen -type PlaceOrderRequest -responseType "\".\".Response" -responseDataField Data -responseDataType "\".\"Order"

But don't worry about the escaping, the above selector can be simplified as:

//go:generate requestgen -type PlaceOrderRequest -responseType .Response -responseDataField Data -responseDataType .Order

If you want to reference a type defined in an external package, you can pass something like "net/url".Response as the type selector, but it needs to be escaped like this:

//go:generate requestgen -type PlaceOrderRequest -responseType "\"net/url\".Response"

-responseDataField [dataField]

When dataField is given, it means your data is inside the responseType, the field name is where you want to extract the data from. Be sure to define dataField as a json.RawMessage so that the generated code can handle the decoding separately.

For example:

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"`
}

-responseDataType [dataType]

When dataType is given, it means your data is inside the responseType. the raw json message will be decoded with this given type.

Placing parameter in the request query

//go:generate GetRequest -url "/api/orders" -type GetOpenOrdersRequest -responseDataType []Order
type GetOpenOrdersRequest struct {
	client requestgen.AuthenticatedAPIClient
	market string `param:"market,query"`
}

func (c *RestClient) NewGetOpenOrdersRequest(market string) *GetOpenOrdersRequest {
	return &GetOpenOrdersRequest{
		client: c,
		market: market,
	}
}

Placing parameter in the request path

//go:generate requestgen -method DELETE -url "/api/orders/:orderID" -type CancelOrderRequest -responseType .APIResponse
type CancelOrderRequest struct {
	client  requestgen.AuthenticatedAPIClient
	orderID string `param:"orderID,required,slug"`
}

func (c *RestClient) NewCancelOrderRequest(orderID string) *CancelOrderRequest {
	return &CancelOrderRequest{
		client:  c,
		orderID: orderID,
	}
}

APIClient

The project does not provide an http client but defines two interfaces, PrivateClient and PublicClient.

You need to implement the methods in these interfaces in your own project.

// PrivateClient fot the signature private requests
type PrivateClient interface {
	NewSignRequest(ctx context.Context, method, endPoint string, params url.Values, payload interface{}) ([]byte, int, error)
	DecodeJSON(buffer []byte, statusCode int, resp interface{}) error
}

// PublicClient for the public requests
type PublicClient interface {
	NewRequest(ctx context.Context, method, endPoint string, params url.Values, payload interface{}) ([]byte, int, error)
	DecodeJSON(buffer []byte, statusCode int, resp interface{}) error
}

example:

type RestClient struct {
	client *http.Client
}

func NewClient() *RestClient {
	return &RestClient{
	client: http.DefaultClient,
}

func (c *RestClient) NewRequest(ctx context.Context, method, endPoint string, params url.Values, payload interface{}) ([]byte, int, error) {
	//TODO implement me
	panic("implement me")
}

func (c *RestClient) NewSignRequest(ctx context.Context, method, endPoint string, params url.Values, payload interface{}) ([]byte, int, error) {
	//TODO implement me
	panic("implement me")
}

func (c *RestClient) DecodeJSON(buffer []byte, statusCode int, resp interface{}) error {
	//TODO implement me
	panic("implement me")
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type PrivateClient

type PrivateClient interface {
	NewSignRequest(ctx context.Context, method, endPoint string, params url.Values, payload interface{}) ([]byte, int, error)
	DecodeJSON(buffer []byte, statusCode int, resp interface{}) error
}

PrivateClient fot the signature private requests

type PublicClient

type PublicClient interface {
	NewRequest(ctx context.Context, method, endPoint string, params url.Values, payload interface{}) ([]byte, int, error)
	DecodeJSON(buffer []byte, statusCode int, resp interface{}) error
}

PublicClient for the public requests

type Response

type Response struct {
	*http.Response

	// Body overrides the composited Body field.
	Body []byte
}

Response is wrapper for standard http.Response and provides more methods.

func NewResponse

func NewResponse(r *http.Response) (response *Response, err error)

NewResponse is a wrapper of the http.Response instance, it reads the response body and close the file.

func (*Response) DecodeJSON

func (r *Response) DecodeJSON(o interface{}) error

func (*Response) IsError

func (r *Response) IsError() bool

func (*Response) IsHTML

func (r *Response) IsHTML() bool

func (*Response) IsJSON

func (r *Response) IsJSON() bool

func (*Response) String

func (r *Response) String() string

String converts response body to string. An empty string will be returned if error.

type TypeSelector

type TypeSelector struct {
	Package string
	Member  string
	IsSlice bool
}

func ParseTypeSelector

func ParseTypeSelector(expr string) (*TypeSelector, error)

Directories

Path Synopsis
cmd
requestgen
requestgen generates the request builder methods.
requestgen generates the request builder methods.
example
api

Jump to

Keyboard shortcuts

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