泛化调用

更新时间:

阿里云V1.0 SDK支持一种通用的方式调用OpenAPI,此方式被称为泛化调用。本文将为您详细介绍如何使用泛化调用访问OpenAPI。

特点

  1. 轻量级:仅需安装Core包即可调用所有OpenAPI,无需依赖各产品的独立SDK。

  2. 快速迭代兼容性:当云产品尚未提供相应的SDK,或当新API发布但SDK未能及时更新时,可以使用泛化调用。这样,无需等待SDK的更新,即可及时调用最新发布的API接口。

更多介绍,请参见泛化调用与特化调用

使用说明

在使用泛化调用之前,必须手动获取并配置OpenAPI的版本号、请求路径、参数类型等元数据信息。可以通过查看OpenAPI元数据来获取有关OpenAPIAPI风格、请求参数、资源路径等相关信息。

安装核心SDK

Terminal中执行以下命令安装核心SDK。

go get -u github.com/aliyun/alibaba-cloud-sdk-go/sdk

调用OpenAPI

初始化请求客户端

通过在aliyunsdkcore包中创建client模块以初始化请求客户端,并通过该Client发起OpenAPI调用。此处仅列举使用AccessKey(简称:AK)初始化客户端的方式,更多初始化方式请参见管理访问凭据

说明

为了避免凭据泄露,常见的方案是将其写入到环境变量中,具体操作请参见Linux、macOSWindows系统配置环境变量

import (
	"fmt"
	"os"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
)

// 使用 AccessKey 直接初始化。os.Getenv表示从环境变量中获取访问密钥
client, err := sdk.NewClientWithAccessKey("cn-hangzhou", os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
	if err != nil {
		panic(err)
	}

配置OpenAPI信息及请求参数

通过CommonRequest来配置OpenAPI所需的公共请求参数及接口请求参数。关于更多公共请求参数的介绍及使用请参见进阶配置

说明

CommonRequest的核心作用是通过标准化的请求配置流程,将原始API元数据(如版本号、路径、参数类型)和请求参数转化为有效的HTTP请求,最终返回原始响应数据。参数传递方式根据API风格和接口设计选择。

接口请求参数说明

请求参数应该如何传参需要查看接口对应的OpenAPI元数据,例如DescribeInstanceStatus的请求参数RegionId元数据中信息为{"name":"RegionId","in":"query",...}},其中"in":"query"表示RegionId通过QueryParams["key"] = "value"传递。

描述

传参方式

请求参数显示"in":"query"时。

QueryParams["key"] = "value"

说明

如果请求参数的类型是集合,那么参数应该按照QueryParams["key.1"] = "value1",

QueryParams["key.2"] = "value2",...格式传参。

请求参数显示"in":"body""in": "formData"时。

FormParams["key"] = "value"

说明

如果请求参数的类型不是字符串类型,需要将参数值转为JSON字符串,并赋值给变量value。

        // 2.创建CommonRequest对象并配置OpenAPI基本信息和请求参数。
        request := requests.NewCommonRequest()
        // 2.1 配置OpenApi基本信息
	request.Domain = "ecs-cn-hangzhou.aliyuncs.com" // API服务地址
	request.Version = "2014-05-26" // API版本号
	request.ApiName = "DescribeInstanceStatus" // API名称,当调用RPC风格API时,必须配置ApiName()指定接口名称
	request.Method = "POST" // 请求方式。
	request.Scheme = "https" // 请求协议:HTTPS或HTTP,建议使用HTTPS。
	// request.PathPattern = "/"   // 资源路径,ROA接口必传。RPC接口禁止设置该参数。

        // 2.2 配置请求参数
	// 场景一:query参数通过QueryParams["key"] = "value"设置
	instanceIds := []string{
		"i-bp1axhql4dqXXXXXXXX",
		"i-bp124uve8zqXXXXXXXX",
	}
	request.QueryParams["RegionId"] = "cn-hangzhou"
	for i, id := range instanceIds {
	request.QueryParams[fmt.Sprintf("InstanceId.%d", i+1)] = id
	}

	// 场景二:body参数通过FormParams["key"] = "value"设置
	// request.FormParams["key1"] = "value1"
	// request.FormParams["key2"] = "value2"
	// request.FormParams["key3"] = "value3"

发起请求

通过client调用ProcessCommonRequest发起请求。

// 发起请求
response, err := client.ProcessCommonRequest(request)
	if err != nil {
		panic(err)
	}
	// 解析响应内容(JSON 格式),包含RequestId以及OpenAPI的返回参数。
	fmt.Print(response.GetHttpContentString())

代码示例

示例:调用RPC风格的API

以调用ECSDescribeRegions接口为例,展示如何使用泛化调用方式。

package main

import (
	"fmt"
	"os"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
)
func main() {
	client, err := sdk.NewClientWithAccessKey("cn-hangzhou", os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
	if err != nil {
		panic(err)
	}
	request := requests.NewCommonRequest()
	request.Domain = "ecs-cn-hangzhou.aliyuncs.com"
	request.Version = "2014-05-26"
	request.ApiName = "DescribeInstanceStatus"
	request.Method = "POST"
	request.Scheme = "HTTPS"

	instanceIds := []string{
		"i-bp1axhql4dqXXXXXXXX",
		"i-bp124uve8zqXXXXXXXX",
	}
	request.QueryParams["RegionId"] = "cn-hangzhou"
	for i, id := range instanceIds {
		request.QueryParams[fmt.Sprintf("InstanceId.%d", i+1)] = id
	}
	request.QueryParams["PageNumber"] = "1"
	request.QueryParams["PageSize"] = "30"
	response, err := client.ProcessCommonRequest(request)
	if err != nil {
		panic(err)
	}
	fmt.Print(response.GetHttpContentString())
}

示例:调用RESTful(ROA)风格的API

以调用容器服务查询集群列表信息DescribeClustersV1接口为例,展示如何使用泛化调用。

package main

import (
	"fmt"
	"os"

	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
)

func main() {
	client, err := sdk.NewClientWithAccessKey("cn-hangzhou", os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
	if err != nil {
		panic(err)
	}
	request := requests.NewCommonRequest()
	request.Domain = "cs.aliyuncs.com" // API服务地址
	request.Version = "2015-12-15" // API版本号
	// 因为是Restful接口,因此需指定PathPattern
	request.PathPattern = "/api/v1/clusters" // API资源路径,当调用ROA风格API时,必须配置set_uri_pattern()指定完整资源路径。从OpenAPI元数据中data.path获取资源路径。
	request.Method = "GET" // 请求方式
	request.Scheme = "https"  // 请求协议:HTTPS或HTTP,建议使用HTTPS。

	response, err := client.ProcessCommonRequest(request)
	if err != nil {
		panic(err)
	}
	fmt.Print(response.GetHttpContentString())
}

常见问题

报错提示“SDK.ServerError MissingParameter The input parameter "AccessKeyId" that is mandatory for processing this request is not supplied.”。

问题原因:AK未正确配置。

解决方案:

  1. 执行以下命令,检查您的环境变量中是否配置有ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET:

    Linux/macOS

    echo $ALIBABA_CLOUD_ACCESS_KEY_ID
    echo $ALIBABA_CLOUD_ACCESS_KEY_SECRET

    Windows

    echo %ALIBABA_CLOUD_ACCESS_KEY_ID%
    echo %ALIBABA_CLOUD_ACCESS_KEY_SECRET%

    若返回正确的AccessKey,则说明配置成功。如果返回为空或错误,请尝试重新设置,具体操作请参见Linux、macOSWindows系统配置环境变量

  2. 检查代码中AK相关内容是否存在错误。

    常见错误示例:

    client, err := sdk.NewClientWithAccessKey("<RegionId>",
    		os.Getenv("yourAccessKeyID"),
    		os.Getenv("yourAccessKeySecret"))
    	if err != nil {
    		panic(err)
    	}
    说明

    此错误示例将os.Getenv()的入参视为需要填入的AK,然而实际上该函数的功能是读取环境变量。当您在机器上设置环境变量名称为ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET时,os.Getenv将能够获取其对应的值。

    正确示例

    client, err := sdk.NewClientWithAccessKey("<RegionId>",
    		os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
    		os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
    	if err != nil {
    		panic(err)
    	}