go调用第三方API通用做法

2024-07-18 20:33:24 浏览数 (1)

前言

在最近本人需要调用一些第三方服务,可是有些第三方服务并没有实现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)
}

0 人点赞