Categorygithub.com/illidaris/rest
repository
1.4.4
Repository: https://github.com/illidaris/rest.git
Documentation: pkg.go.dev

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# README

rest

strong constraint api client

Sender

Sender is a http client package, decouple Request(which you send) and Send HTTP(how you send). an agreed request_param need implementate this interface IRequest

type IRequest interface {
	GetContentType() core.ContentType // Content-Type
	GetResponse() interface{}         // Response
	GetMethod() string                // HTTP Method Get,POST,PUT...
	GetAction() string                // URL api/v1/product
	GetUrlQuery() url.Values          // URL Query params
	Encode() ([]byte, error)          // IRequest Marshal to []byte
	Decode([]byte) error              // []byte Marshal to Response
}

type Request struct {
	Response interface{}
}

send http request

	result, err := sender.HttpSend(ctx, req, host) // normal

	result, err := sender.HttpSendWithSign(ctx, req, host, "aa", sender.WithAppID("test_app"), sender.WithTimeConsume(true)) // with sign

define your request param. You should know what you send, example:

type StudentGetRequest struct {
	StudentReq
	Response *StudentResponse `json:"-"`
}

func (r *StudentGetRequest) GetContentType() string {
	return "application/json"
}

func (r *StudentGetRequest) GetResponse() interface{} {
	return r.Response
}

func (r *StudentGetRequest) GetMethod() string {
	return http.MethodPost
}

func (r *StudentGetRequest) GetAction() string {
	return "student"
}

func (r *StudentGetRequest) Encode() ([]byte, error) {
	return json.Marshal(r)
}

func (r *StudentGetRequest) Decode(bs []byte) error {
	if r.Response == nil {
		r.Response = &StudentResponse{}
	}
	return json.Unmarshal(bs, r.Response)
}

or

type StudentGetRequest struct {
	sender.JSONRequest // json post
	StudentReq
	Response *StudentResponse `json:"-"`
}

func (r *StudentGetRequest) GetResponse() interface{} {
	return r.Response
}

func (r *StudentGetRequest) GetAction() string {
	return "student"
}

func (r *StudentGetRequest) GetUrlQuery() url.Values {
	return url.Values{}
}

func (r *StudentGetRequest) Encode() ([]byte, error) {
	return json.Marshal(r)
}

func (r *StudentGetRequest) Decode(bs []byte) error {
	if r.Response == nil {
		r.Response = &StudentResponse{}
	}
	return json.Unmarshal(bs, r.Response)
}

define your sender. You should know how you send, example:

// StudentGetInvoke
func StudentGetInvoke(ctx context.Context, host string, student StudentReq) (*Student, error) {
	req := &StudentGetRequest{
		StudentReq: student,
		Response:   &StudentResponse{},
	}

	s := sender.NewSender(
		sender.WithHeader(sender.HeaderKeyContentType, req.GetContentType()),
		sender.WithHost(host),
	)

	_, err := s.Invoke(ctx, req)
	if err != nil {
		return nil, err
	}
	if req.Response.Code != 0 {
		return nil, fmt.Errorf("[%d]%s", req.Response.Code, req.Response.Message)
	}
	return req.Response.Data, err
}

or

func StudentGetInvoke(ctx context.Context, host string, student StudentReq) (*Student, error) {
	req := &StudentGetRequest{
		StudentReq: student,
		Response:   &StudentResponse{},
	}

	_, err := sender.HttpSendWithSign(ctx, req, host, "aa", sender.WithAppID("test_app"), sender.WithTimeConsume(true))
	if err != nil {
		return nil, err
	}
	if req.Response.Code != 0 {
		return nil, fmt.Errorf("[%d]%s", req.Response.Code, req.Response.Message)
	}
	return req.Response.Data, err
}

Signature

signature is use HMac function to sign your request. make sure your request is whole and untampered one.

signature = hamc( [HTTP.Method: POST] + URLEncode([URL.Path: api/v1/product]) + URLEncode([content]) )

 const (
	SignAppID        string = "app"
	SignKeySign      string = "sign"
	SignKeyTimestamp string = "ts"
	SignKeyNoise     string = "noise"
	SignBody         string = "bs_body"
)

content

  • query params append Timestamp and Noise:
  • sort asc by string ASCII
  • encode with &
  1. method == GET:
    app=&begin=1662911996&country_id=-1&game_id=6&noise=abcdef&page=1&page_size=10&region_id=-1&ts=1665214465
  1. method !=GET && json-content:
    app=&bs_body={\"a1\":1,\"z1\":1}&noise=aXf2dc&ts=1664523204
  1. method !=GET && url-content:
    app=&begin=1662911996&country_id=-1&game_id=6&noise=abcdef&page=1&page_size=10&region_id=-1&ts=1665214465

example:

  1. application/x-www-form-urlencoded
api/report/third/daily

app=&begin=1662911996&country_id=-1&game_id=6&noise=abcdef&page=1&page_size=10&region_id=-1&ts=1665214465
  1. URL Encode
api%2Freport%2Fthird%2Fdaily


app%3D%26begin%3D1662911996%26country_id%3D-1%26game_id%3D6%26noise%3Dabcdef%26page%3D1%26page_size%3D10%26region_id%3D-1%26ts%3D1665214465
  1. Link with &
POST&api%2Freport%2Fthird%2Fdaily&app%3D%26begin%3D1662911996%26country_id%3D-1%26game_id%3D6%26noise%3Dabcdef%26page%3D1%26page_size%3D10%26region_id%3D-1%26ts%3D1665214465
  1. HMac, use secret key BYwS-pnuOSY7GbVy2FzGljh5HZA9ZIk1ecVgJWpfRdY
2F6D85481F1647A87EBD575851ABEAF1B8121CB5