1、api方法
package api
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"reflect"
"strings"
)
const (
GET = "GET"
POST = "POST"
PUT = "PUT"
DELETE = "DELETE"
JSON = "json"
FORM = "form"
)
var (
ErrMethodNotSupported = errors.New("method is not supported")
ErrMIMENotSupported = errors.New("mime is not supported")
)
// InvokeHTTPAPI 调用远程http接口
func InvokeHTTPAPI(method, mime, api string, param interface{}) (response []byte, err error) {
client := new(http.Client)
var req *http.Request
req, err = MakeRequest(method, mime, api, param)
if err != nil {
return
}
// send request
var rsp *http.Response
rsp, err = client.Do(req)
if err != nil {
return
}
defer rsp.Body.Close()
response, err = ioutil.ReadAll(rsp.Body)
return
}
// InvokeHTTPAPIWithHeader 调用远程http接口
func InvokeHTTPAPIWithHeader(method, mime, api string, param interface{}, header map[string]string) (response []byte, err error) {
client := http.Client{}
// make request
var req *http.Request
req, err = MakeRequest(method, mime, api, param)
if err != nil {
return
}
if header != nil {
for key, val := range header {
req.Header.Add(key, val)
}
}
// send request
var rsp *http.Response
rsp, err = client.Do(req)
if err != nil {
return
}
defer rsp.Body.Close()
response, err = ioutil.ReadAll(rsp.Body)
return
}
// MakeRequest make request
func MakeRequest(method, mime, api string, param interface{}) (request *http.Request, err error) {
method = strings.ToUpper(method)
mime = strings.ToLower(mime)
switch mime {
case JSON:
var (
contentBuffer *bytes.Buffer
jsonBytes []byte
)
jsonBytes, err = json.Marshal(param)
if err != nil {
return
}
contentBuffer = bytes.NewBuffer(jsonBytes)
request, err = http.NewRequest(string(method), api, contentBuffer)
if err != nil {
return
}
request.Header.Set("Content-Type", "application/json;charset=utf-8")
case FORM:
queryStr := MakeQueryStrFrom(param)
var buffer io.Reader
if (method == DELETE || method == GET) && queryStr != "" {
api += "?" + queryStr
} else {
buffer = bytes.NewReader([]byte(queryStr))
}
logging.Debugf("api:%v, queryStr:%v\n", api, queryStr)
request, err = http.NewRequest(string(method), api, buffer)
if err != nil {
return
}
request.Header.Set("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
default:
err = ErrMIMENotSupported
return
}
return
}
// MakeQueryStrFrom make query string from params
func MakeQueryStrFrom(params interface{}) (result string) {
if params == nil {
return
}
value := reflect.ValueOf(params)
switch value.Kind() {
case reflect.Struct:
var formName string
for i := 0; i < value.NumField(); i++ {
if formName = value.Type().Field(i).Tag.Get("form"); formName == "" {
// don't tag the form name, use camel name
formName = GetCamelNameFrom(value.Type().Field(i).Name)
}
result += "&" + formName + "=" + fmt.Sprintf("%v", value.Field(i).Interface())
}
case reflect.Map:
for _, key := range value.MapKeys() {
result += "&" + fmt.Sprintf("%v", key.Interface()) + "=" + fmt.Sprintf("%v", value.MapIndex(key).Interface())
}
default:
return
}
if result != "" {
result = result[1:]
}
return
}
// GetCamelNameFrom get the Camel name of the original name
func GetCamelNameFrom(name string) string {
result := ""
i := 0
j := 0
r := []rune(name)
for m, v := range r {
// if the char is the capital
if v >= 'A' && v < 'a' {
// if the prior is the lower-case || if the prior is the capital and the latter is the lower-case
if (m != 0 && r[m-1] >= 'a') || ((m != 0 && r[m-1] >= 'A' && r[m-1] < 'a') && (m != len(r)-1 && r[m+1] >= 'a')) {
i = j
j = m
result += name[i:j] + "_"
}
}
}
result += name[j:]
return strings.ToLower(result)
}
2、api调用
-- get 方式
type MsgReq struct {
Name string `json:"name"`
}
func OnlineDataInfo(date string) (MsgReq, error) {
api := fmt.Sprintf(OnlineUrl, date)
msg := MsgReq{}
body, err := api.InvokeHTTPAPI(api.GET, api.JSON, api, nil)
if err != nil {
return msg, fmt.Errorf("获取出错")
}
if err = json.Unmarshal(body, &msg); err != nil {
return msg, err
}
return msg, nil
}
-- post
|