前言
在最近本人需要调用一些第三方服务,可是有些第三方服务并没有实现Go的官方SDK调用方法,本文将以一个实战案例教会你如何调用99%的第三方api
本文使用的API参考文档
Go如何调用请求
怎么创建一个请求?
在调用api方面Go提供了方便的http/net包方便我们调用请求,以下给出Go如何调用一个请求的做法
使用http包的NewRequest便可以创建一个请求,以下代码便创建了一个方法为Get,请求连接为空,调用参数为空的请求
代码语言:go复制urlReq, err := http.NewRequest(http.MethodGet, "", nil)
// post请求
// urlReq, err := http.NewRequest(http.MethodPost, "", nil)
当然也可以使用context包来对于调用连接进行一个时间上的限制,以下代码便创建了一个调用连接时间限制为5秒的请求
代码语言:go复制ctx, _ := context.WithTimeout(context.Background(), time.Second * 5)
urlReqWithContext, _ := http.NewRequestWithContext(ctx, http.MethodGet, "", nil)
怎么指定具体的Query参数
在观察第三方api文档的时候通常都有要求填写Query参数的地方
这种可以在url中自行添加,但是go有着更为方便的做法
代码语言:go复制func main() {
urlReq, _ := http.NewRequest(http.MethodGet, "https://oapi.dingtalk.com/gettoken", nil)
fmt.Println(urlReq.URL)
// 添加Query参数
accessToken := "123456"
params := urlReq.URL.Query()
// 添加参数 名字, 具体参数
params.Add("access_token", accessToken)
urlReq.URL.RawQuery = params.Encode()
fmt.Println(urlReq.URL)
}
调用一下我们可以发现成功为我们需要调用的连接添加上了Query参数
代码语言:http复制https://oapi.dingtalk.com/gettoken
https://oapi.dingtalk.com/gettoken?access_token=123456
怎么填写body参数
在第三方api调用中,更多要我们填写的往往都是body参数,我们只需使用go的json对于一个结构体进行正常的序列化即可填写
代码语言:go复制package main
import (
"encoding/json"
"fmt"
"net/http"
"bytes"
)
// 设置具体请求需要的结构体
type reqParmas struct {
Mobile string
}
func main() {
// 填写需要的参数
reqBody := reqParmas{
Mobile: "12345678910",
}
reqJson, _ := json.Marshal(&reqBody)
fmt.Println(string(reqJson))
urlReq, _ := http.NewRequest(http.MethodGet, "https://oapi.dingtalk.com/gettoken", bytes.NewReader(reqJson))
fmt.Println(urlReq)
}
调用一下
代码语言:json复制{"Mobile":"12345678910"}
我们发现请求已经按具体的格式处理好了,可是跟我们要求的mobile参数不一致,我们需要使用tag的方式来指定他进行json序列化之后的名字以及获取时填写的名字
代码语言:go复制type reqParmas struct {
Mobile string `json:"mobile"`
}
将结构体改成如上代码所示,让我们再次调用一下程序,会发现请求参数已经变成了我们想要的样子
代码语言:go复制{"mobile":"12345678910"}
怎么调用请求?
使用http中的client客户端便可以实现轻松调用,我们仅需传入我们刚刚封装好的请求即可,注意返回的参数为[]byte串,需要进行对应的处理才能使用
代码语言:go复制func HttpDo(req *http.Request) ([]byte, error) {
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
怎么获取具体的请求信息?
在调用接口后一般都会获得具体的请求信息,此时我们就应该使用json的反序列化方法来获取具体返回的信息,假设我们需要的信息如下图所示
代码语言:go复制package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
)
type resultParma struct {
Userid string `json:"userid"`
}
// 根据具体返回的值填写
type respParma struct {
RequestId string `json:"request_id"`
ErrCode int32 `json:"errcode"`
ErrMsg string `json:"errmsg"`
Result resultParma `json:"result"`
}
func HttpDo(req *http.Request) ([]byte, error) {
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
func main() {
// 假设已经封装好了请求,进行一下http调用
respJson, _ := HttpDo(urlReq)
var resp respParma
_ = json.Unmarshal(respJson, &resp)
fmt.Println(resp)
}
调用一下,发现成功获取
代码语言:json复制{15qxjud398o4o 40104 电话号码无效 {}}
结尾
使用的API参考文档
完整代码如下,如果想获取一个accessToken,可以按照本文的方式按照该文档练习获取AccessToken,或者可以通过官方的SDK调用方式进行调用获取。
希望我的文章能够帮助到你。
如果觉得本文对你有帮助可以点个赞让更多人看到!
代码语言:go复制package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
// 设置具体请求需要的结构体
type reqParmas struct {
Mobile string `json:"mobile"`
}
type resultParma struct {
Userid string `json:"userid"`
}
// 根据具体返回的值填写
type respParma struct {
RequestId string `json:"request_id"`
ErrCode int32 `json:"errcode"`
ErrMsg string `json:"errmsg"`
Result resultParma `json:"result"`
}
func HttpDo(req *http.Request) ([]byte, error) {
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
func main() {
// 填写需要的参数
accessToken := "填入自己的accessToken"
reqBody := reqParmas{
Mobile: "12345678910",
}
reqJson, _ := json.Marshal(&reqBody)
urlReq, _ := http.NewRequest(http.MethodPost, "https://oapi.dingtalk.com/topapi/v2/user/getbymobile", bytes.NewReader(reqJson))
parma := urlReq.URL.Query()
parma.Add("access_token", accessToken)
urlReq.URL.RawQuery = parma.Encode()
respJson, _ := HttpDo(urlReq)
var resp respParma
_ = json.Unmarshal(respJson, &resp)
fmt.Println(resp)
}