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

5.1 KiB
Raw Blame History

title
云函数 Cloud SDK

云函数 Cloud SDK

在云函数中,laf.js 提供了一个 cloud-sdk 以方便开发者访问一些应用接口,如数据库、文件、网络等接口。

数据库访问

在云函数中数据库操作 与客户端 SDK 的数据库操作的接口是一致的,前端人员也可以无缝的编写云函数,或者复用代码。

// 引入 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 完全一致。

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 内置提供了文件上传与下载接口,但云函数中也支持文件操作,以便开发者更灵活的实现自己的业务逻辑。

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 入门教程

注意:出于演示目的,对 password 以明文方式查询,并未做 hash 处理考虑,不建议实际开发过程中如此使用。

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 还提供了其它能力,可参考其内部定义,同时在开发控制台中编写时,亦有代码提示、类型、注释提示,可根据代码提示使用。

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;
}