在調用OpenAPI時,建議採用在專案中整合SDK的方式。使用SDK可以簡化開發流程,實現功能的快速整合,同時有效降低維護成本。整合阿里雲SDK主要包括三個步驟:引入阿里雲SDK、設定訪問憑據以及編寫調用代碼。本文將詳細介紹SDK整合的具體流程。
環境要求
1. 引入SDK
登入SDK Center,選擇將要使用產品,例如您將要調用Short Message Service (SMS)的API。
在安裝頁面,所有語言選擇Go。然後在快速入門頁簽中,您可以擷取Short Message Service (SMS)的SDK安裝方式。
2. 設定訪問憑據
調用阿里雲OpenAPI通常需要設定訪問憑據,常見憑據類型為AccessKey(簡稱:AK)
和臨時安全性權杖STS Token
。為防止憑據泄露,常用的方案是將其儲存到環境變數中,更多安全方案請參見訪問憑據的安全使用方式情節。本文以設定環境變數ALIBABA_CLOUD_ACCESS_KEY_ID
和ALIBABA_CLOUD_ACCESS_KEY_SECRET
為例:
Linux和macOS系統配置方法
Windows系統配置方法
通過export命令配置環境變數
重要
使用export命令配置的臨時環境變數僅當前會話有效,當會話退出之後所設定的環境變數將會丟失。若需長期保留環境變數,可將export命令配置到對應作業系統的啟動設定檔中。
通過圖形化使用者介面GUI
通過命令列提示符CMD
通過Windows PowerShell
操作步驟
以下為Windows 10中通過圖形化使用者介面設定環境變數的步驟。
在案頭按右鍵此電腦,選擇屬性>進階系統設定>環境變數>系統變數/使用者變數>建立,完成以下配置:
變數 | 樣本值 |
AccessKey ID | |
AccessKey Secret | |
測試設定是否成功
單擊開始(或快速鍵:Win+R)> 運行(輸入 cmd)> 確定(或按 Enter 鍵),開啟命令提示字元,執行echo %ALIBABA_CLOUD_ACCESS_KEY_ID%
、echo %ALIBABA_CLOUD_ACCESS_KEY_SECRET%
命令。若返回正確的AccessKey,則說明配置成功。
操作步驟
以管理員身份開啟命令提示字元,並使用以下命令在系統中新增環境變數。
setx ALIBABA_CLOUD_ACCESS_KEY_ID yourAccessKeyID /M
setx ALIBABA_CLOUD_ACCESS_KEY_SECRET yourAccessKeySecret /M
其中/M
表示系統級環境變數,設定使用者級環境變數時可以不攜帶該參數。
測試設定是否成功
單擊開始(或快速鍵:Win+R)> 運行(輸入 cmd)> 確定(或按 Enter 鍵),開啟命令提示字元,執行echo %ALIBABA_CLOUD_ACCESS_KEY_ID%
、echo %ALIBABA_CLOUD_ACCESS_KEY_SECRET%
命令。若返回正確的AccessKey,則說明配置成功。
在PowerShell中,設定新的環境變數(對所有新會話都有效):
[System.Environment]::SetEnvironmentVariable('ALIBABA_CLOUD_ACCESS_KEY_ID', 'yourAccessKeyID', [System.EnvironmentVariableTarget]::User)
[System.Environment]::SetEnvironmentVariable('ALIBABA_CLOUD_ACCESS_KEY_SECRET', 'yourAccessKeySecret', [System.EnvironmentVariableTarget]::User)
為所有使用者佈建環境變數(需要管理員權限):
[System.Environment]::SetEnvironmentVariable('ALIBABA_CLOUD_ACCESS_KEY_ID', 'yourAccessKeyID', [System.EnvironmentVariableTarget]::Machine)
[System.Environment]::SetEnvironmentVariable('ALIBABA_CLOUD_ACCESS_KEY_SECRET', 'yourAccessKeySecret', [System.EnvironmentVariableTarget]::Machine)
設定臨時的環境變數(僅當前會話有效):
$env:ALIBABA_CLOUD_ACCESS_KEY_ID = "yourAccessKeyID"
$env:ALIBABA_CLOUD_ACCESS_KEY_SECRET = "yourAccessKeySecret"
在PowerShell中,執行Get-ChildItem env:ALIBABA_CLOUD_ACCESS_KEY_ID
、Get-ChildItem env:ALIBABA_CLOUD_ACCESS_KEY_SECRET
命令。若返回正確的AccessKey,則說明配置成功。
3. 編寫調用代碼
本文以調用Short Message Service (SMS)的SendMessageToGlobe介面為例,關於SendMessageToGlobe介面的API文檔,請參見SendMessageToGlobe。
3.1 初始化請求用戶端
在SDK中,所有的OpenAPI均通過SDK提供的請求用戶端(Client)發起調用。因此,在調用OpenAPI之前,需要先對請求用戶端進行初始化。請求用戶端支援多種方式初始化,本樣本以使用AK進行初始化為例,更多初始化方式請參見管理訪問憑證。
func CreateClient () (_result *dysmsapi20180501.Client, _err error) {
config := &openapi.Config{
AccessKeyId: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
}
config.Endpoint = tea.String("dysmsapi.aliyuncs.com")
_result = &dysmsapi20180501.Client{}
_result, _err = dysmsapi20180501.NewClient(config)
return _result, _err
}
3.2 建立請求對象
在調用OpenAPI進行參數傳遞時,需使用SDK提供的請求對象來實現參數的傳遞。OpenAPI請求對象的命名方式為:<OpenAPI名稱>Request
,例如SendSms該介面的請求對象為SendSmsRequest。有關請求參數的詳細資料,請查閱相應的API文檔,本樣本API文檔請參見SendMessageToGlobe。
sendMessageToGlobeRequest := &dysmsapi20180501.SendMessageToGlobeRequest{
To: tea.String("<YOUR_VALUE>"),
Message: tea.String("<YOUR_VALUE>"),
}
說明
針對部分需要上傳檔案的OpenAPI,可以通過建立<OpenAPI名稱>AdvanceRequest
請求對象傳遞檔案流。以視覺智能開放平台-人臉人體的DetectBodyCount介面為例:
filePath := `<FILE_PATH>`
file, err := os.Open(filePath)
if err != nil {
return fmt.Errorf("開啟檔案失敗: %v", err)
}
defer file.Close()
detectBodyCountAdvanceRequest := &facebody20191230.DetectBodyCountAdvanceRequest{
ImageURLObject: file,
}
3.3 發起請求
通過請求用戶端調用OpenAPI時,建議使用的函數名稱為<介面名稱>WithOptions
。該函數包含兩個參數:一個為請求對象,另一個為運行時參數。請求對象為上一步建立的請求對象;運行時參數用於配置請求的行為,例如逾時設定、代理配置等。更多資訊,請參見進階配置。
runtime := &util.RuntimeOptions{}
tryErr := func()(_e error) {
defer func() {
if r := tea.Recover(recover()); r != nil {
_e = r
}
}()
_, _err = client.SendMessageToGlobeWithOptions(sendMessageToGlobeRequest, runtime)
if _err != nil {
return _err
}
說明
針對部分需要本地上傳檔案的OpenAPI,需調用函數<介面名稱>Advance
發起請求。以調用視覺智能開放平台-人臉人體的DetectBodyCount介面為例:
var response *facebody20191230.DetectBodyCountResponse
response, _err = client.DetectBodyCountAdvance(detectBodyCountAdvanceRequest, runtime)
fmt.Println(response)
if _err != nil {
return _err
}
3.4 異常處理
V2.0 Go SDK將異常進行了細緻的分類,主要劃分為error和SDKError。
更多關於異常處理的介紹,請參見異常處理。
重要
建議採取合理的措施來處理異常,比如合理地傳播異常、記錄日誌、嘗試恢複等,以確保系統的健壯性和穩定性。
完整程式碼範例
package main
import (
"encoding/json"
"strings"
"fmt"
"os"
dysmsapi20180501 "github.com/alibabacloud-go/dysmsapi-20180501/v2/client"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
)
func CreateClient () (_result *dysmsapi20180501.Client, _err error) {
config := &openapi.Config{
AccessKeyId: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
}
config.Endpoint = tea.String("dysmsapi.aliyuncs.com")
_result = &dysmsapi20180501.Client{}
_result, _err = dysmsapi20180501.NewClient(config)
return _result, _err
}
func _main (args []*string) (_err error) {
client, _err := CreateClient()
if _err != nil {
return _err
}
sendMessageToGlobeRequest := &dysmsapi20180501.SendMessageToGlobeRequest{
To: tea.String("<YOUR_VALUE>"),
Message: tea.String("<YOUR_VALUE>"),
}
runtime := &util.RuntimeOptions{}
tryErr := func()(_e error) {
defer func() {
if r := tea.Recover(recover()); r != nil {
_e = r
}
}()
_, _err = client.SendMessageToGlobeWithOptions(sendMessageToGlobeRequest, runtime)
if _err != nil {
return _err
}
return nil
}()
if tryErr != nil {
var error = &tea.SDKError{}
if _t, ok := tryErr.(*tea.SDKError); ok {
error = _t
} else {
error.Message = tea.String(tryErr.Error())
}
fmt.Println(tea.StringValue(error.Message))
var data interface{}
d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
d.Decode(&data)
if m, ok := data.(map[string]interface{}); ok {
recommend, _ := m["Recommend"]
fmt.Println(recommend)
}
_, _err = util.AssertAsString(error.Message)
if _err != nil {
return _err
}
}
return _err
}
func main() {
err := _main(tea.StringSlice(os.Args[1:]))
if err != nil {
panic(err)
}
}
package main
import (
"encoding/json"
"fmt"
"os"
"strings"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
facebody20191230 "github.com/alibabacloud-go/facebody-20191230/v5/client"
util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
)
func CreateClient() (_result *facebody20191230.Client, _err error) {
config := &openapi.Config{
AccessKeyId: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
}
config.Endpoint = tea.String("facebody.cn-shanghai.aliyuncs.com")
_result = &facebody20191230.Client{}
_result, _err = facebody20191230.NewClient(config)
return _result, _err
}
func _main(args []*string) (_err error) {
client, _err := CreateClient()
if _err != nil {
return _err
}
filePath := `<FILE_PATH>`
file, err := os.Open(filePath)
if err != nil {
return fmt.Errorf("開啟檔案失敗: %v", err)
}
defer file.Close()
detectBodyCountAdvanceRequest := &facebody20191230.DetectBodyCountAdvanceRequest{
ImageURLObject: file,
}
runtime := &util.RuntimeOptions{}
tryErr := func() (_e error) {
defer func() {
if r := tea.Recover(recover()); r != nil {
_e = r
}
}()
var response *facebody20191230.DetectBodyCountResponse
response, _err = client.DetectBodyCountAdvance(detectBodyCountAdvanceRequest, runtime)
fmt.Println(response)
if _err != nil {
return _err
}
return nil
}()
if tryErr != nil {
var error = &tea.SDKError{}
if _t, ok := tryErr.(*tea.SDKError); ok {
error = _t
} else {
error.Message = tea.String(tryErr.Error())
}
fmt.Println(tea.StringValue(error.Message))
var data interface{}
d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
d.Decode(&data)
if m, ok := data.(map[string]interface{}); ok {
recommend, _ := m["Recommend"]
fmt.Println(recommend)
}
_, _err = util.AssertAsString(error.Message)
if _err != nil {
return _err
}
}
return _err
}
func main() {
err := _main(tea.StringSlice(os.Args[1:]))
if err != nil {
panic(err)
}
}
常見問題
調用OpenAPI時報錯,提示“You are not authorized to perform this operation”。
問題原因:您所使用的AccessKey對應的RAM使用者沒有許可權調用該API。
解決方案:請為該RAM使用者授予相應OpenAPI許可權。關於如何為RAM使用者進行授權,請參見為RAM使用者授權。
例如,當您在調用SendMessageToGlobe時提示“You are not authorized to perform this operation”,您可以建立如下所示的自訂權限原則,並為該RAM使用者授予相應的許可權。
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": "dysms:SendMessageToGlobe",
"Resource": "*"
}
]
}
調用OpenAPI時報錯,提示 "SDKError:Message:Post "https://ecs-cn-XX.aliyuncs.com": dial tcp: lookup ecs-cn-XX.aliyuncs.com: no such host"。
問題原因:您所調用的OpenAPI不支援在初始化請求用戶端時填寫的Endpoint。
解決方案:請查看Endpoint配置,修改Endpoint後重新調用OpenAPI。
調用OpenAPI時報錯,提示:“SDKError: StatusCode: 404 Code:InvalidAccessKeyId.NotFound Message: code: 404, Specified access key is not found. ”。
問題原因:您的AccessKey未正確傳遞。
解決方案:在初始化請求用戶端時,檢查是否正確傳遞AccessKey。請注意os.Getenv("XXX")
表示從環境變數中擷取XXX
的值。
更多SDK使用過程中的報錯問題解決方案,請參見常見問題。