泛化调用
阿里云V1.0 SDK支持一种通用的方式调用OpenAPI,此方式被称为泛化调用。本文将为您详细介绍如何使用泛化调用访问OpenAPI。
特点
轻量级:仅需安装
aliyun-python-sdk-core
即可调用所有OpenAPI,无需依赖各产品的独立SDK。快速迭代兼容性:当云产品尚未提供相应的SDK,或当新API发布但SDK未能及时更新时,可以使用泛化调用。这样,无需等待SDK的更新,即可及时调用最新发布的API接口。
更多介绍,请参见泛化调用与特化调用。
使用说明
在使用泛化调用之前,必须手动获取并配置OpenAPI的版本号、请求路径、参数类型等元数据信息。可以通过查看OpenAPI元数据来获取有关OpenAPI的API风格、请求参数、资源路径等相关信息。
安装核心SDK
在Terminal中执行以下命令安装核心SDK。
composer require alibabacloud/client
调用OpenAPI
初始化请求客户端
通过在AlibabaCloud
包中创建client
模块以初始化请求客户端,并通过该Client
发起OpenAPI
调用。此处仅列举使用AccessKey(简称:AK)
初始化客户端的方式,更多初始化方式请参见管理访问凭据。
为了避免凭据泄露,常见的方案是将其写入到环境变量中,具体操作请参见在Linux、macOS和Windows系统配置环境变量。
use AlibabaCloud\Client\AlibabaCloud;
// getenv代表从环境变量获取AK,初始化客户端
AlibabaCloud::accessKeyClient(
getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'),
getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET')
)
->regionId('cn-hangzhou') // 指定区域
->asDefaultClient(); // 设为默认客户端
配置OpenAPI信息及请求参数
通过AlibabaCloud
包中的client
模块来配置OpenAPI
所需的基本信息及请求参数。
request
的核心作用是通过标准化的请求配置流程,将原始API元数据(如版本号、路径、参数类型)和请求参数转化为有效的HTTP请求,最终返回原始响应数据。参数传递方式根据API风格和接口设计选择。
// 配置OpenAPI基本信息和请求参数
$result = AlibabaCloud::rpc() // 接口风格:支持RPC、ROA。
// 1.配置OpenAPI基本信息
->regionId('cn-hangzhou') // 地域ID
->product('Ecs') // 产品名称
->version('2014-05-26') // 注意版本号需要与API文档一致
->action('DescribeRegions') // API名称,当调用RPC风格API时,必须配置action()指定接口名称
// ->pathPattern() // API资源路径,当调用ROA风格API时,必须配置pathPattern()指定完整资源路径。
->method('GET') // 请求方法:GET、POST
->setProtocolType('https') // 请求协议:HTTPS或HTTP,建议使用HTTPS。
// 2.配置请求参数
->options([
// 方式一:设置查询参数(query,请求方式为 GET、POST
'query' => [
'InstanceChargeType' => 'PostPaid',
],
// 方式二:设置body参数,reqBodyType的值为formData,请求方式为 POST
// 'form_params' => [ // 表单参数
// 'InstanceChargeType' => 'PostPaid'
// ],
// 'headers' => [
// 'content-type' => 'application/x-www-form-urlencoded'
// ]
])
// 方式三:设置body参数,reqBodyType的值为byte,请求方式为 GET
// ->contentType('application/octet-stream')
// ->body(json_encode(['InstanceChargeType' => 'PostPaid']))
// 方式四:设置body参数,reqBodyType的值为json,请求方式为 GET
// ->contentType('application/json') // 参数类型
// ->jsonBody(['InstanceChargeType' => 'PostPaid']) // 参数类型的值为json
发起请求
通过client
调用request()
发起请求。
// 调用RPC风格API
$result = AlibabaCloud::rpc()
->request()
// 调用ROA风格API
// $result = AlibabaCloud::roa()
// ->request()
// 返回值是 bytes 类型,包含RequestId以及OpenAPI的返回参数
print_r($result->toArray());
代码示例
示例:调用RPC风格的API
以调用ECS的DescribeRegions
接口为例,展示如何使用泛化调用方式。
<?php
namespace AlibabaCloud\SDK\Sample;
require_once 'vendor/autoload.php';
use AlibabaCloud\Tea\Utils\Utils;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
class Sample
{
public static function main()
{
try {
$result = AlibabaCloud::rpc()
->regionId('cn-hangzhou')
->product('Ecs') // 产品名称
->version('2014-05-26') // API版本号,注意版本号需要与API文档一致
->action('DescribeRegions') // API名称,当调用RPC风格API时,必须配置action()指定接口名称
->method('GET') // 请求方法
// 请求参数
->options([
'query' => [
'InstanceChargeType' => 'PostPaid',
],
])
->request();
print_r($result->toArray());
} catch (ClientException | ServerException $e) {
echo $e->getErrorMessage();
} catch (ServerException $exception) {
print_r($exception->getErrorMessage());
}
}
}
Sample::main();
示例:调用 RESTful(ROA)风格的 API
以下代码展示了如何使用泛化调用的方式调用容器服务的 DescribeClustersV1 接口:
<?php
namespace AlibabaCloud\SDK\Sample;
require_once 'vendor/autoload.php';
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
class Sample
{
public static function main()
{
try {
$result = AlibabaCloud::roa()
->regionId('cn-hangzhou') // 指定请求的地域,不指定则使用客户端地域、默认地域。
->product('CS') // 指定产品。
->version('2015-12-15') // 指定产品版本。
->serviceCode('cs') // 设置 ServiceCode 以备寻址,非必须。
->endpointType('openAPI') // 设置类型,非必须。
->method('GET') // 指定请求方式。
->host('cs.aliyuncs.com') // 指定域名则不会寻址,如认证方式为 Bearer Token 的服务则需要指定。
->pathPattern('/api/v1/clusters') // API资源路径,当调用ROA风格API时,必须配置pathPattern()指定完整资源路径。从OpenAPI元数据中data.path获取资源路径。
->request(); // 发起请求并返回结果对象,请求需要放在设置的最后面。
print_r($result->toArray());
} catch (ClientException $exception) {
print_r($exception->getErrorMessage());
} catch (ServerException $exception) {
print_r($exception->getErrorMessage());
}
}
}
Sample::main();