laf/docs/guide/function/cloud-sdk.md
2021-12-16 16:13:06 +08:00

180 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 云函数 Cloud SDK
---
### 云函数 Cloud SDK
在云函数中,`laf.js` 提供了一个 `cloud-sdk` 以方便开发者访问一些应用接口,如数据库、文件、网络等接口。
#### 数据库访问
在云函数中数据库操作 与客户端 SDK 的数据库操作的接口是一致的,前端人员也可以无缝的编写云函数,或者复用代码。
```ts
// 引入 cloud-sdk注意以 `@/` 开头
import cloud from "@/cloud-sdk";
exports.main = async function (ctx) {
const { username } = ctx.body;
// 数据库操作
const db = cloud.database();
const ret = await db.collection("users").where({ username }).get();
console.log(ret);
return ret.data;
};
```
#### HTTP 请求
使用 `cloud.fetch()` 可发起 HTTP 请求,调用三方接口,可完成如支付接口、短信验证码等等三方接口操作。
该接口是对 `axios` 请求库的封装,其调用方法与 `axios` 完全一致。
```ts
import cloud from "@/cloud-sdk";
exports.main = async function (ctx) {
const ret = await cloud.fetch({
url: "http://www.baidu.com/",
method: "post",
});
console.log(ret.data);
return ret.data;
};
```
#### 文件操作
虽然 `laf.js` 内置提供了文件上传与下载接口,但云函数中也支持文件操作,以便开发者更灵活的实现自己的业务逻辑。
```ts
import cloud from "@/cloud-sdk";
exports.main = async function (ctx) {
if (!ctx.files?.length) {
return "no file uploaded";
}
const file = ctx.files[0];
const storage = cloud.storage("public");
const saved = await storage.save(file.path, file.filename, {
contentType: file.mimetype,
original_name: file.originalname,
// ... other metadatas
});
return saved.toString();
};
```
### 生成 JWT token
以下实现简单登录函数,以演示 标准 JWT token 的生成,预期开发者已熟悉 JWT 相关知识。
可查看[JSON Web Token 入门教程](https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html)
> 注意:出于演示目的,对 password 以明文方式查询,并未做 hash 处理考虑,不建议实际开发过程中如此使用。
```ts
import cloud from "@/cloud-sdk";
exports.main = async function (ctx) {
const { username, password } = ctx.body;
const db = cloud.database();
const { data: user } = await db
.collection("users")
.where({ username, password })
.getOne();
if (!user) {
return "invalid username or password";
}
// payload of token
const payload = {
uid: user._id,
// 默认 token 有效期为 7 天,请务必提供此 `exp` 字段,详见 JWT 文档。
exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7,
};
const access_token = cloud.getToken(payload);
return {
access_token,
uid: user._id,
username: user.username,
expired_at: payload.exp,
};
};
```
#### 附SDK 接口定义
`Cloud SDK` 还提供了其它能力,可参考其内部定义,同时在开发控制台中编写时,亦有代码提示、类型、注释提示,可根据代码提示使用。
````ts
export interface CloudSdkInterface {
/**
* 发送 HTTP 请求,实为 Axios 实例,使用可直接参考 axios 文档
*/
fetch: AxiosStatic;
/**
* 获取一个文件存储管理器
* @param bucket 文件 Bucket 名字,默认为 'public'
*/
storage(bucket?: string): FileStorageInterface;
/**
* 获取 less api database ORM 实例
*/
database(): Db;
/**
* 调用云函数
*/
invoke: InvokeFunctionType;
/**
* 抛出云函数事件,其它云函数可设置触发器监听此类事件
*/
emit: EmitFunctionType;
/**
* 云函数全局内存单例对象,可跨多次调用、不同云函数之间共享数据
* 1. 可将一些全局配置初始化到 shared 中,如微信开发信息、短信发送配置
* 2. 可共享一些常用方法,如 checkPermission 等,以提升云函数性能
* 3. 可做热数据的缓存,建议少量使用(此对象是在 node vm 堆中分配,因为 node vm 堆内存限制)
*/
shared: Map<string, any>;
/**
* 获取 JWT Token若缺省 `secret`,则使用当前服务器的密钥做签名
*/
getToken: GetTokenFunctionType;
/**
* 解析 JWT Token若缺省 `secret`,则使用当前服务器的密钥做签名
*/
parseToken: ParseTokenFunctionType;
/**
* 当前应用的 MongoDb Node.js Driver 实例对象。
* 由于 Laf database ORM 对象只有部分数据操作能力,故暴露此对象给云函数,让云函数拥有完整的数据库操作能力:
* 1. 事务操作
* ```js
* const session = mongo.client.startSession()
* try {
* await session.withTransaction(async () => {
* await mongo.db.collection('xxx').updateOne({}, { session })
* await mongo.db.collection('yyy').deleteMany({}, { session })
* // ...
* })
* } finally {
* await session.endSession()
* }
* ```
* 2. 索引管理
* ```js
* mongo.db.collection('admins').createIndex('username', { unique: true })
* ```
* 3. 聚合操作
*/
mongo: MongoDriverObject;
}
````