简介

saas 服务一般提供了一个文档来描述提供的 OpenAPI,然会每个用户根据文档自己实现签名、调用等功能的封装,这部分会出现各种各样的问题,因此用户更希望平台直接提供一个 SDK。

darabonba

darabonba 是阿里云开源的用于 OpenAPI 的 DSL 语言,编写 darabonba 就可以生成多语言的 SDK 等等。本文不介绍入门(README 比较全)。

编写 SDK

首先是 Config 类,一般包括 appKey 和 secretKey,并定义模块变量,定义如下:

// 引入的依赖见最后的推荐依赖
import Util;
import SignatureUtil;
import OpenApiUtil; type @host = string
type @appKey = string
type @secretKey = string model Config {
appKey: string(description = "appKey"),
secretKey: string(description = "secretKey")
}

接着是 Client 类的初始化方法里初始化:

init(config: Config) {
@host = "www.aliyun.com";
@appKey = config.appKey;
@secretKey = config.secretKey;
}

接着定义请求方法:

// 请求的通用参数封装为一个 model
model Request {
// GET/POST
method: string,
// 请求路径
pathname: string,
// 拼接参数字符串,作为签名的一部分
param: string,
// 参数是否是 Json 格式
isJson?: boolean
} // http 请求,返回一个任意类型的结果
api _requestRAny(request: Request, body: any): any {
__request.pathname = request.pathname;
__request.method = request.method;
// 获取时间戳
var date: string = OpenApiUtil.getTimestamp();
// 计算签名
__request.headers = _header(@appId, date, _sign(request.param, date));
if (request.isJson) {
__request.headers.accept = 'application/json';
__request.body = Util.toJSONString(body);
} else {
__request.query = Util.stringifyMapValue(Util.assertAsMap(body));
}
} returns {
// 处理 http response
return _handle(__response);
} runtime {
// 超时时间 10 s,你也可以配成模块参数
timeout = 10000
} // 调用 api 的函数必须用 async 关键字修饰
async function _requestRObj(request: Request, body: any): object {
// object 等价 map[string]any 等价 $Model,它们之间可以直接转换
return Util.assertAsMap(_requestRAny(request, body));
} // 处理 http response,返回任意类型的结果
function _handle(response: $Response): any {
// 读取响应的数据,通常是一个包含 code、status 和 data 的 Json 串
var result = Util.assertAsMap(Util.readAsJSON(response.body));
if (!Util.equalNumber(response.statusCode, 200) || !Util.assertAsBoolean(result.ok)) {
// 抛异常,通过 throw 关键字仅能抛出一种异常
throw {
message = `httpCode: ${response.statusCode}, serverCode: ${result.code}, reason: ${result.message}`,
code = `${result.code}`
};
}
return result.data;
} // 构建请求头
function _header(appKey: string, signedAt: string, sign: string): map[string]string {
var headers: map[string]string = {
host = @endpoint_host,
app_key = appKey,
signed_at = signedAt,
sign = sign
};
return headers;
} // 签名
function _sign(param: string, date: string): string {
// 模式字符串拼接参数,计算 md5 摘要做签名
var sign: string = OpenApiUtil.hexEncode(SignatureUtil.MD5Sign(`app_key${@appKey}secret_key${@secretKey}signed_at${date}${param}));
return sign;
}

比如一个接入用户接口

model UserRequest {
userId: string(description = "userId", name = "userId", required = true),
nickName?: string(description = "nickName", name = "nickName")
} async function createUser(userRequest: UserRequest): void {
// 校验参数,UserRequest 的 nickName 使用了 ?:,? 表示不会进行校验,如果不调用这个方法那就没有区别
Util.validateModel(userRequest);
// 构建通用参数
var request = new Request {
method = @get,
pathname = "/user/createUser",
// 模式字符串拼接参数做签名
param = `nickName${userRequest.nickName}userId${userRequest.userId}`
};
// 发起 http 请求,如果返回值是基本类型比如数字,那么可以这样:
_requestRAny(request, accessThirdPartyUserRequest);
}

其他

  1. Model 和 Object 和 map[string]any

它们三个是等价的,可以直接转换,不用转换,其他的都需要调用工具类转换,这点很重要

  1. 接口参数很少,不想定义 Model?

直接使用 map[string]any。

_requestRAny(request, {
// 和前面 _header 函数一样构建 map 一样
thirdPartyUserId = thirdPartyUserId
})
  1. 接口参数包含数组,签名怎么计算?

调用 OpenApiUtil.arrayToStringWithSpecifiedStyle() 方法转为为字符串

// 风格自己选,和服务端保持一直就可以
var arrayString: string = OpenApiUtil.arrayToStringWithSpecifiedStyle(null, null, null);
  1. 返回值类型怎么转换?

_requestRAny 函数返回的是任意类型。

  • 基本类型使用 Util.assertAsXXX() 转换
  • 数组类型需要定义一个 model,在 model 里定义一个数组,然后用 map 设置数组再转换为 model
model Response {
items: [ string ](description = "items")
} // 返回 Response 类型,函数其余部分不展示了
return {
items = _requestRAny(request, modelRequest)
};

推荐依赖

saas 服务多语言 SDK的更多相关文章

  1. 一文了解腾讯云数据库SaaS服务

    本文由云+社区发表 作者:邵宗文,2009年加入腾讯,现为腾讯云数据库专家产品经理.之前曾负责为OMG事业群构建数据库平台,部署,规划及运维支持,为腾讯网,新闻客户端,快报,视频,财经,体育等提供了稳 ...

  2. 下一个亿万市场:企业级SaaS服务谁能独领风骚

    注:SaaS是Software-as-a-Service(软件即服务)的简称,一种完全创新的软件应用模式,简单来说SaaS即为提供商基于互联网为企业提供软件服务. ​对中小型企业来说:SaaS是采用先 ...

  3. 编译包含Google Play服务App的SDK版本问题

    编译包含Google Play服务App的SDK版本问题   错误信息:No Resouce identifier found for attribute 'touchscreen BlocksFoc ...

  4. 【阿里云产品公测】消息队列服务MQS java SDK 机器人应用初体验

    [阿里云产品公测]消息队列服务MQS java SDK 机器人应用初体验 作者:阿里云用户啊里新人   初体验 之 测评环境 由于MQS支持外网访问,因此我在本地做了一些简单测试(可能有些业余),之后 ...

  5. [在线Demo]使用Hibernate多租户实现SaaS服务

    上一篇文章 基于Hibernate实现多租户(Multi-Tendency)功能简单介绍了利用Hibernate的多租户功能提供SaaS服务的方法,但其中有很多不足,后来都得到了解决. 我尝试过抽取实 ...

  6. WSDL(Web服务描述语言)详细解析(全文转载学习用)

    WSDL (Web Services Description Language,Web服务描述语言)是一种XML Application,他将Web服务描述定义为一组服务访问点,客户端可以通过这些服务 ...

  7. 基于云端的通用权限管理系统,SAAS服务,基于SAAS的权限管理,基于SAAS的单点登录SSO,企业单点登录,企业系统监控,企业授权认证中心

    基于云端的通用权限管理系统 SAAS服务 基于SAAS的权限管理 基于SAAS的单点登录SSO 基于.Net的SSO,单点登录系统,提供SAAS服务 基于Extjs 4.2 的企业信息管理系统 基于E ...

  8. saas服务提供商

    这段时间接触了不少行业的东西,这里谈几点肤浅的看法.从市场行情上讲,SaaS风口还在,不过热度明显向大数据.物联网.人工智能.区块链等转移. 做得比较好的有这些SaaS提供商,每个领域的都有那么几家的 ...

  9. Traefik 控制面板 SaaS 服务 Pilot

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247485572&idx=1&sn=8ffa2bc7 ...

随机推荐

  1. 递归概念&分类&注意事项和练习_使用递归计算1-n之间的和

    递归:方法自己调用自己 递归的分类: 递归分为两种,直接递归和间接递归 直接递归称为方法自身调用自己 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法 注意事项: 递归一定要有条件限定 ...

  2. rust实战系列-base64编码

    前言 某些只能使用ASCII字符的场景,往往需要传输非ASCII字符的数据,这时就需要一种编码可以将数据转换成ASCII字符,而base64编码就是其中一种. 编码原理很简单,将原始数据以3字节(24 ...

  3. AI写代码! 神器copilot介绍+安装+使用

    !郑重提示!!!!!!!: 正在学编程.算法的同学请千万不要依赖此插件,否则你可能甚至无法手写出一个for循环 AI帮我写代码?我帮AI写代码?庄周梦蝶?蝶梦庄周?十分梦幻. copilot在VSco ...

  4. 总结几个简单好用的Python人脸识别算法

    原文连接:https://mp.weixin.qq.com/s/3BgDld9hILPLCIlyysZs6Q 哈喽,大家好. 今天给大家总结几个简单.好用的人脸识别算法. 人脸识别是计算机视觉中比较常 ...

  5. Excel用户如何打破内卷?只需要一个新软件,就能突破excel天花板

    还在死磕Excel吗?到底值不值得? 你看看,现在有多少excel培训班和培训课?网上各种EXCEL使用技巧教程也是满天飞.很多人为了提升Excel技能,不遗余力学习各种函数用法.VBA用法等等,最近 ...

  6. Thread类的常用方法_sleep和创建多线程程序的第二种方式实现Runnable接口

    public static void sleep(long millis);//使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行). 毫秒数结束后线程继续执行 package com.yang.T ...

  7. C#里如何简单的校验时间格式

    前言: 晚上打算睡觉的时候,群里反馈订单接收失败,开工排查问题,日志显示验签失败,发现一个蛮有意思的BUG,总算有了一个写作的素材 场景描述 本次的场景属于比较常见的收单API,对第三方的订单进行签名 ...

  8. SmartIDE v1.0.23 一个非常不敏捷的发布

    SmartIDE v1.0版本(CLI Build v1.0.23.4650,Server Build v1.0.23.4646)已经发布,在超过4000 个 Builds 之后,我们终于发布了v1. ...

  9. CF242E XOR on Segment

    CF242E XOR on Segment codeforces 洛谷 关于异或,无法运用懒标记实现区间异或: 可以像trie树一样拆位,将每个值拆成二进制数,对此建相应个数的线段树. 0 1与 0异 ...

  10. 运筹帷幄决胜千里,Python3.10原生协程asyncio工业级真实协程异步消费任务调度实践

    我们一直都相信这样一种说法:协程是比多线程更高效的一种并发工作方式,它完全由程序本身所控制,也就是在用户态执行,协程避免了像线程切换那样产生的上下文切换,在性能方面得到了很大的提升.毫无疑问,这是颠扑 ...