laf/docs/en/guide/function/function-sdk.md
nightwhite 16cc16f61f
doc: add international English section (#1308)
* doc: add international English section

* doc: del operator.md

* doc: some old error

* doc: fix path errors

* doc: modify the default readme language

* doc: Part of the internationalization of changes

* doc: keep English readme

* doc: delete readme_en.md
2023-06-25 16:36:23 +08:00

6.8 KiB

title
Cloud Function SDK

{{ $frontmatter.title }}

Introduction to Laf's Cloud SDK

For cloud functions, Laf provides a dedicated SDK @lafjs/cloud to support accessing networks, databases, object storage, and more.

::: danger @lafjs/cloud is a proprietary module that can only be used in cloud functions and cannot be installed via npm in other locations. :::

Importing the SDK

Each Laf application already has the SDK dependencies installed by default, so there is no need for additional installation. Simply import it at the top of your cloud function.

import cloud from "@lafjs/cloud";

Sending Network Requests

Use cloud.fetch() to send HTTP requests and call third-party APIs, such as payment interfaces, SMS verification codes, etc.

This interface is a wrapper for the axios request library, and its usage is identical to axios. You can refer to the axios documentation for the calling method.

You can think of cloud.fetch === axios, which means they can be used interchangeably.

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

Alternatively, you can write it like this:

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

Working with Databases

You can use cloud.database() to obtain a database object and perform database operations.

::: info For detailed database API operation methods, refer to the Cloud Database section. :::

The following example retrieves user information from the database:

import cloud from "@lafjs/cloud";

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

Invoking Other Cloud Functions

You can use cloud.invoke() to call other cloud functions within the same application.

::: info This method is no longer recommended. You can directly import cloud functions now. :::

import cloud from '@lafjs/cloud'

export async function main(ctx: FunctionContext) {
   // Call the hello cloud function
   await cloud.invoke('hello')
}

If the invoked cloud function needs to access something in the ctx object, you can pass it like this:

import cloud from '@lafjs/cloud'

export async function main(ctx: FunctionContext) {
   // Call the hello cloud function and pass the ctx object
   await cloud.invoke('hello', ctx)
}

Generating and Decrypting JWT Tokens

cloud.getToken(payload); // payload can refer to the example code below
cloud.parseToken(token); // token is the token in the authorization field of the request header from the frontend

Here is a simple implementation for generating and decrypting JWT tokens:

import cloud from "@lafjs/cloud";

export async function main(ctx: FunctionContext)  {
  const payload = {
    uid: 1,
    // The default expiration time of the token is 7 days. Please make sure to provide the `exp` field, see JWT documentation for more details.
    exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7,
  };
  // Generate the access_token
  const access_token = cloud.getToken(payload);
  console.log("Token generated by cloud function:", access_token)
  // ctx.user is automatically decrypted
  console.log(ctx.user)
  const authHeader = ctx.headers.authorization;
  const token = authHeader.split(' ')[1]; // Extract the JWT
  console.log("Token sent by frontend:", token)
  const parseToken = cloud.parseToken(token);
  console.log("Decrypted data from token:", parseToken)
};

getToken-parseToken

Here is a simple login function that generates a JWT token:

Note: For demonstration purposes, the password is queried in plain text and not hashed. This is not recommended in actual development.

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,
    // The default expiration time of the token is 7 days. Please make sure to provide the `exp` field, see JWT documentation for more details.
    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 Function Global Cache

The global memory singleton object of the cloud function allows sharing data across multiple invocations and different cloud functions.

cloud.shared is a standard Map object in JavaScript. You can refer to the MDN documentation to learn how to use it: Map

Use cases:

  1. Initialize global configurations into shared, such as WeChat development information, SMS sending configurations.
  2. Share common methods, such as checkPermission, to improve the performance of cloud functions.
  3. Cache hot data, such as caching WeChat access_tokens. (It is recommended to use it sparingly, as this object is allocated in the node vm heap and has memory limitations.)

::: info The cache will be cleared completely after the application restarts. It will be preserved if there is no restart. :::

import cloud from "@lafjs/cloud";

export async function main(ctx: FunctionContext) {
  cloud.shared.set(key, val); // Set a cache
  cloud.shared.get(key); // Get the value of a cache
  cloud.shared.has(key); // Check if a cache exists
  cloud.shared.delete(key); // Delete a cache
  cloud.shared.clear(); // Clear all caches
  // ... Other methods can be found in the MDN Map documentation above
};

Native MongoDriverObject Instance in Cloud Functions

It is recommended that those familiar with MongoDB use the native MongoDriverObject instance to manipulate databases.

You can refer to the MongoDB official CRUD documentation for learning how to use it: MongoDB

Here is a simple example:

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