laf/docs/guide/function/function-sdk.md

7.4 KiB
Raw Blame History

title
云函数 SDK

{{ $frontmatter.title }}

引入 Laf 的 Cloud SDK

在云函数上Laf 提供了专门的 SDK @lafjs/cloud 让云函数支持访问网络、数据库、对象存储等。

::: danger @lafjs/cloud 是一个专有的模块,只能在云函数上使用,不支持通过 npm 安装到其他位置。 :::

导入 SDK

每个 Laf 应用默认已经安装了 SDK 依赖,不需要额外安装了。直接在云函数顶部 import 即可。

import cloud from "@lafjs/cloud";

SDK 属性

cloud 具有下面的一些参数:

属性 介绍
cloud.appid 当前 Laf 应用的 appid
cloud.database() 当前应用的数据库对象
cloud.env 当前应用的环境变量,也可用 process.env
cloud.fetch 可在云函数中发起 HTTP 请求,基于axios封装
cloud.getToken 生成 JWT Token
cloud.parseToken 解密 JWT Token
cloud.invoke 请求其他云函数
cloud.shared 当前应用的全局缓存
cloud.mongo 当前应用的原生 MongoDB 实例
cloud.sockets 当前应用的socket实例

发送网络请求

使用 cloud.fetch() 可发起 HTTP 请求,调用三方接口,可完成如支付接口、短信验证码等等三方接口操作。

该接口是对 axios 请求库的封装,其调用方法与 axios 完全一致。调用方法可参考:axios 文档

可以理解为 cloud.fetch === axios,可以做到互相替换。

import cloud from "@lafjs/cloud";

export async function main(ctx: FunctionContext) {
  const ret = await cloud.fetch({
    url: "http://api.github.com/",
    method: "post",
  });
  console.log(ret.data);
  return ret.data;
};

还可以这么写

// get 请求
const getRes = await cloud.fetch.get("http://api.github.com/");
// post 请求
const postRes = await cloud.fetch.post("http://api.github.com/",{
  name: 'laf'
});

操作数据库

通过cloud.database() 可以获取数据库对象,进而对数据库进行操作。

::: info 数据库 API 的详细操作方法可以参考 云数据库 章节 :::

下面的例子可以获取数据库中的用户信息:

import cloud from "@lafjs/cloud";

export async function main(ctx: FunctionContext) {
  const { username } = ctx.body;
  // 数据库操作
  const db = cloud.database();
  const ret = await db.collection("users").where({ username }).get();
  console.log(ret);
};

调用其他云函数

通过cloud.invoke() 调用本应用内的其他云函数。

::: info 该方法已不推荐使用,现可直接引入云函数) :::

import cloud from '@lafjs/cloud'

export async function main(ctx: FunctionContext) {
   // 调用 hello 云函数
   await cloud.invoke('hello')
}

如果调用的云函数需要用到 ctx 里面的东西,我们可以通过这样的方式传入。

import cloud from '@lafjs/cloud'

export async function main(ctx: FunctionContext) {
   // 调用云函数 hello 并传入 ctx
   await cloud.invoke('hello',ctx)
}

生成和解密 JWT token

cloud.getToken(payload); // payload 可参考下方的示例代码
cloud.parseToken(token); // token 为前端请求时 header 里的 authorization 中的 token

以下实现简单的生成和解密 JWT token

import cloud from "@lafjs/cloud";

export async function main(ctx: FunctionContext)  {
  const payload = {
    uid: 1,
    // 默认 token 有效期为 7 天,请务必提供此 `exp` 字段,详见 JWT 文档。
    exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7,
  };
  // 生成 access_token
  const access_token = cloud.getToken(payload);
  console.log("云函数生成的 token", access_token)
  // ctx.user 会自动解密
  console.log(ctx.user)
  const authHeader = ctx.headers.authorization;
  const token = authHeader.split(' ')[1]; // 提取 JWT
  console.log("前端请求带的 token", token)
  const parseToken = cloud.parseToken(token);
  console.log("解密 token 后的数据:", parseToken)
};

getToken-parseToken

以下实现简单登录函数,并生成 JWT token

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

import cloud from "@lafjs/cloud";

export async function main(ctx: FunctionContext)  {
  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,
  };
};

云函数全局缓存

云函数全局内存单例对象,可跨多次调用、不同云函数之间共享数据

cloud.shared是 JS 中标准的 Map 对象,可参照 MDN 文档学习使用:Map

使用场景:

  1. 可将一些全局配置初始化到 shared 中,如微信开发信息、短信发送配置
  2. 可共享一些常用方法,如 checkPermission 等,以提升云函数性能
  3. 可做热数据的缓存。如:缓存微信 access_token。建议少量使用此对象是在 node vm 堆中分配,因为 node vm 堆内存限制)

::: info 应用重启后缓存会全部清空,不重启会一直保留 :::

import cloud from "@lafjs/cloud";

export async function main(ctx: FunctionContext) {
  cloud.shared.set(key, val); // 设置一个缓存
  cloud.shared.get(key); // 获取缓存的值
  cloud.shared.has(key); // 判断缓存是否存在
  cloud.shared.delete(key); // 删除缓存
  cloud.shared.clear(); // 清空所有缓存
  // ... 其他方法可访问上方 MDN 的 Map 文档查看
};

云函数原生 MongoDriverObject 实例

熟悉 MongoDB 的同学建议优先使用原生 MongoDriverObject 实例去操作数据库。

可参照 mongodb 官方 crud 文档学习使用:mongodb

下面是一个简单的使用实例:

import cloud from "@lafjs/cloud";

export async function main(ctx: FunctionContext) {
  const db = cloud.mongo.db
  const data = { 
    name : "张三"
  }
  const res = await db.collection('test').insertOne(data)
  console.log(res)
};