Skip to main content

Adding Custom API Methods

Some user-level APIs support adding custom methods.

Method Input Parameters

Input parameters are used to describe the structure of the above function params`. If the function has no parameters, then do not fill it in.

caution

If the function has parameters, they must be an object. The field structure described in the input parameters should match the structure of the params actually used by the function; otherwise, errors may occur when used in the Weida application editor.

When using data sources in the Weida application editor, the structure information described in the input parameters of data source methods will be utilized, for example:

  1. In the definition of data source variables, the configuration form for variables is generated based on the structure indicated by the input parameters (displaying the Chinese names of fields and showing different form controls based on field types).
  2. After associating the form container with the data source method, a complete form is generated based on the input parameter structure. For example: the field name in the input parameters becomes the field label in the form input box; the data type of the field may determine different input field types (phone number input/email input/toggle switch, etc.); and enumeration information is used to generate multi-select input fields or dropdown selectors, and so on.

The above is only an example. Data source method input parameters have numerous usage scenarios in the Weida application editor. Therefore, the more complete the information provided when filling in the input parameters, the more convenient it will be to use in the Weida application editor.

Common Variables

Common variables provide a method for cross-method variable invocation, supporting references across multiple APIs. They are generally suitable for static variables such as APIToken, ClientID, and other constant values, and can be referenced using the template {{ }} syntax. For example, to set a common variable ClientId, reference it using the form {{vars.ClientId}}.

Method Types

Data source methods are divided into two types based on their implementation approach:

  • HTTP Request: This method type is only provided in external data sources, enabling simple integration with third-party http interfaces. Methods can be configured by simply setting the HTTP request URL, method, parameters, etc.
  • Cloud Function: Achieves more flexible functionality by writing JavaScript code, including initiating HTTP requests.

HTTP Request

HTTP requests are encapsulated based on the underlying cloud function capabilities of Cloud Development, providing visual and rapid integration features for third-party HTTP APIs.

The HTTP configuration sets the underlying request parameters for HTTP requests. When configuring the URL, Query, Headers' value, and Body (only when the request Method is POST or PUT), you can use the template {{ }} to reference the following fields:

  • Reference fields defined in input parameters using the form {{ params.field_identifier }}
  • Reference environment variable information using the form {{ env.field_identifier }}, such as {{ env.openId }}
  • Reference common variable information using the form {{ vars.field_identifier }}
About the Body in http Configuration

When configuring the Body, the content entered will be treated as a complete string template. Ensure the processed template result complies with the Body type requirements (JSON/FORM/XML), otherwise the request will fail directly.

Example:

The input parameter params is { age: 12, name: 'Saurus', tags: ['aaa', 'bbb'] }, and the Body type in the HTTP configuration is JSON.

Correct Body example, the request can be sent normally:

  • If the Body content is { "age": {{params.age}} }, the result will be { "age": 12 }
  • If the Body content is { "age": "{{params.age}}" }, the result will be { "age": "12" }. Note that the value of age is a string.
  • If the Body content is { "tags": {{params.tags}} }, the result will be { "tags": ["aaa", "bbb"] }

Incorrect Body example, the request will fail directly:

  • If the Body content is { age: {{params.age}} }, the result will be { age: 12 }. The age key lacks double quotes " wrapping
  • If the Body content is { "name": {{params.name}} }, the result will be { "name": Saurus }. The Saurus value lacks double quotes " wrapping
  • If the Body content is { "tags": "{{params.tags}}" }, the result will be { "tags": "["aaa", "bbb"]" }. The value of tags has a syntax error

Cloud Function

A Cloud Function is a special type of Javascript function. It is built upon the capabilities of CloudBase Cloud Functions and ultimately runs in a Node.js 10.15 runtime environment on the server side. You can access all features of the CloudBase Node.js sdk via the function's context parameter.

When writing Cloud Functions, note the following points:

  • Cloud Functions must use module.exports for export
  • Cloud Functions accept only two parameters:
    • params: Parameters accepted by the function, corresponding to the structure described in Method Input Parameters. Ensure params remains consistent with the structure described in Method Input Parameters during actual usage.
    • context: Cloud Function context object, which facilitates the implementation of various functionalities within Cloud Functions. For its specific structure, refer to Cloud Function context
  • The result returned by the Cloud Function, i.e., the content returned by the return statement, should be an object and must be consistent with the structure described in Method Output Parameters
  • If an error is encountered in a Cloud Function, you can directly throw new Error('xxxx') to throw an error, or use throw new TCBError(code, 'msg') to throw an error with a custom error code.
  • During Cloud Function development, you can output logs via console.log('xxxx'), then use Method Testing to test and view the logs
  • The runtime environment for Cloud Functions is Node.js 10.15. Avoid using JavaScript features unsupported in the current version, such as optional chaining.

Below is the sample code for adding a custom creation method to a self-built data source:

Assuming the self-built data source has two custom data source fields, name and email, the following code will validate the parameters, restrict usage to qq email addresses only, and finally return the ID of the new record

module.exports = async function (params, context) {
// Output logs for debugging purposes; logs can be viewed in [Method Testing](#method-testing)
console.log('params', params);
if (!params.name || !params.email) throw new TCBError(1, 'name or email cannot be empty');
if (!/@qq\.com$/i.test(params.email)) throw new TCBError(2, 'Only QQ email addresses are supported');
const now = Date.now();
// Add creation time, update time
const newParams = Object.assign({}, params, {
createdAt: now,
updatedAt: now,
});

// Use CloudBase collection-related APIs to add records
const result = await context.collection.add(newParams);
// Return the ID of the new record
return { _id: result.id };
}

Custom Code context

context is a context object provided by the low-code platform to Cloud Functions, which includes objects for database operations, CloudBase Cloud Function invocations, and some useful environment variables.

ParameterTypeRequiredDescription
cloudbasetcbYesCloudBase node sdk object, i.e., the tcb imported via import tcb from '@cloudbase/node-sdk';, Usage Documentation
apptcb.CloudBaseYesThe app object returned after initializing the CloudBase node sdk, i.e., the app obtained from const app = tcb.init({...}). By default, initialization uses the CloudBase environment parameters of the current low-code platform. You can use app to directly invoke CloudBase cloud functions and storage-related capabilities (e.g., app.callFunction({...}), app.uploadFile({...})). Usage Documentation
authCloudBase Authentication ObjectYesThe auth object obtained from app.auth() mentioned above, which can be used to directly invoke authentication-related capabilities (e.g., auth.getUserInfo(), auth.getEndUserInfo(), etc.). Usage Documentation
databaseCloudBase Database ObjectYesThe database object of the CloudBase node sdk, i.e., the object returned by app.database(). You can use database to get a reference to a collection (database.collection('<collection-name>')), access the command object (database.command), etc. Usage Documentation
collectionCloudBase Database Collection ObjectNoReference object for the database table associated with the current data source (CloudBase node sdk collection reference object). This property is only available for self-built data sources, i.e., the object returned by context.database.collection(context.env.dataSourceFullName). You can directly use this object to perform read/write operations on the database table of the current data source. Usage Documentation
envEnvironment variablesYesFor details, refer to Environment Variables
httpAuthauth handling objectNoThis object is only available for third-party data sources created using non-blank templates. For specific usage, refer to How to integrate new methods for third-party data sources created using templates
varsObjectYesPublic variables of the current data source

Environment Variables

ParameterTypeRequiredDescription
openIdstringNoWeChat openId, empty if not logged in via WeChat authorization
fromOpenIdstringNoIn WeChat, when multiple Mini Programs share the same environment (i.e., one WeDa environment bound to multiple Mini Programs), the user openId of the source Mini Program. This value should be prioritized in actual use.
currentOpenIdstringNoWhen multiple Mini Programs share the same environment (i.e., one WeDa environment bound to multiple Mini Programs), if the request comes from a shared Mini Program, currentOpenId will be the aforementioned fromOpenId; otherwise it will be openId
appIdstringNoWeChat appId, empty if not logged in via WeChat authorization
fromAppIdstringNoIn WeChat, when multiple Mini Programs share the same environment (i.e., one WeDa environment bound to multiple Mini Programs), the appId of the source Mini Program. This value should be prioritized in actual use.
currentAppIdstringNoWhen multiple Mini Programs share the same environment (i.e., one WeDa environment bound to multiple Mini Programs), if the request comes from a shared Mini Program, currentAppId will be the aforementioned fromAppId; otherwise it will be appId
uidstringNotcb user unique ID
customUserIdstringNoDeveloper-defined user unique id, empty if not logged in via custom authentication
isAnonymousbooleanYesWhether the user is anonymous
dataSourceNamestringYesData source identifier. Only data sources created in Data Source Management have this attribute.
dataSourceFullNamestringNoFull name of the data source, which serves as the actual identifier used in the underlying infrastructure after deployment (cloud function name/database table name)
envIdstringYesCloudBase environment ID
isPreviewbooleanYesWhether it is a trial environment. Developers generally do not need to use this information. See below Environment Description
envTypeprod preYesEnvironment type, pre: trial environment, prod: production environment; Developers generally do not need to use this information. See below Environment Description

Environment Description

WeDa generated applications fall into two categories:

  • Trial Application: Used for developing and testing applications within WeDa. Applications obtained through the Real-time Preview toggle in the preview area of the application editor, the Preview button at the top of the editor, or by selecting the Trial publishing method in the top publish dialog are all categorized as Trial Applications.
  • Production Application: Used for official release to end users. Applications obtained by selecting the Production publishing method in the top publish dialog of the application editor are categorized as Production Applications.

The data sources and WeDa backend support services invoked by Trial ApplicationsandProduction Applications` are isolated from each other and do not interfere with each other, as they call different backend environments respectively.

  • Trial Environment: Invoked by Trial Applications.
  • Production Environment: Invoked by Production Applications.

When users create/edit and save data sources in WeDa's data source management, the data sources in the Trial Environment are automatically updated. After the data source passes testing and verification, clicking the Publish Now button in data source management will update the data source to the Production Environment.

Method Testing

After configuring the methods (http requests and cloud functions) of the data source, use Method Testing for validation. Fill in the test parameters in "Submit Parameters", then click "Run Test" to execute the test. The test output results display the method's operational log information. After successful testing, click Output Parameter Mapping to quickly populate Method Output Parameters.

When writing cloud functions, you can use console.log in the code to output logs. The log information can be viewed in the "Logs" section of Method Testing.

caution

The Method Testingfeature cannot simulate different end-user identities. If method processing varies under different user identities and permissions, it cannot be validated throughMethod Testing`. It is recommended to use data sources in applications and leverage the preview feature to test applications, enabling comprehensive testing of data sources in real-world scenarios.

Method Output Parameters

The result returned by the cloud function code is the function output parameters.

caution

The structure described in Output Parameters` must match the method's return result structure and must be an object; otherwise, errors may occur when used in the Weida application editor.

When using data sources in the Weida application editor, the structural information described in the output parameters of data source methods will be utilized, for example:

  1. Data source variables will use the output parameters of associated data source methods to generate sample data.
  2. After the table is bound to the data source method, the table header information will be generated based on the output parameter structure information.

The above is only an example. Data source method output parameters have numerous usage scenarios in the Weida application editor. Therefore, the more complete the information provided when filling in the output parameters, the more convenient it will be to use in the Weida application editor.

Quickly populate output parameters

You can use Method Testing. After clicking Run Test and then Output Parameter Mapping, the platform will analyze the structure of the returned result and automatically populate the output parameters.

Field Mapping in HTTP Method Output Parameters

In HTTP methods, after using Method Testing for output parameter mapping, the populated output parameter structure will match the structure of the original HTTP response.

The output parameters of HTTP methods provide the field mapping feature, which allows adjusting the data structure that the frontend application ultimately receives:

  • You can delete unnecessary fields in the output parameters. After deletion, the corresponding fields will not be returned when the frontend application calls this method.
  • You can edit the fields in the output parameters. The field identifier is the field name obtained by the frontend application when using the data source, while the field mapping is the field path in the original HTTP response corresponding to this field. That is, the value at the field mapping path is assigned to the field named field identifier.
    • Modify the field identifier. After modification, the frontend application will receive the field under the modified name.
    • Modify the field mapping. After modification, the current field will retrieve its value from the path described by the field mapping in the original response.

Modifying field mapping requires attention to the following points:

  • The value of field mapping is an object path string, such as: abc, abc.ed, abc.ed.cf[0].g. Ensure the path exists during use, otherwise mapping will fail and cause the method to throw an error
  • You can use the special string $root representing the root of the original response. When filling in field mappings, $root.abc is equivalent to abc, so $root can generally be omitted.
  • When mapping an array of objects, you can use $item (representing the current element in the loop; $item.xxx can be used to specify a field of the object) and $index (the loop index, starting from 0). Note: the array field must be mapped to the corresponding array of objects in the original response.

Frequently Asked Questions

How to Use Third-Party Dependencies in Cloud Functions

Currently, the built-in libraries request and @cloudbase/js-sdk are available in cloud functions. Using other dependencies is not supported at this time.

Simply use the node.js function require to import the relevant dependencies, for example:

const request = require('request');

module.exports = function (params, context) {
return new Promise(function (resolve, reject) {
request('xxxxx', ...)
})
};

How to Make an HTTP Request in Cloud Functions

You can use the npm package request to achieve this. For specific usage, refer to the code below:

/**
* Use the npm package `request` to send HTTP requests. For detailed usage documentation, refer to
* https://github.com/request/request#readme
*/
const request = require('request');

/** Determine if the request was successful based on the http status code */
function isSuccessStatusCode(code) {
return code >= 200 && code < 300;
}

module.exports = function (params, context) {
// `params` is the structure defined for input parameters and can be used in the request configuration
return new Promise(function (resolve, reject) {
request(
{
url: 'https://reqres.in/api/users?page=1&per_page=3',
method: 'GET',
// Set json to true, and the response body will be automatically converted to an object
// In POST requests, the Content-Type will also be automatically set to application/json
json: true
},
function (err, response, body) {
if (err) return reject(err);
if (!isSuccessStatusCode(response.statusCode))
return reject(new Error('request failed: ' + response.statusCode));
return resolve(body);
}
);
});
};

How to Integrate New Methods for Third-Party Data Sources Created Using Templates

When creating an external data source, if a non-blank template is used, the cloud function's context will have an additional httpAuth object. Through context.httpAuth, you can access the authentication information for this type of external data source.

context.httpAuth` is defined as follows:

ParameterTypeRequiredDescription
getAuthDataFunctionRequiredFunction to obtain authentication information, defined as (requestConfig: IRequestConfig) => Promise<IAuthData>. requestConfig is the parameter configuration for the request library, which must include at least the uri and method fields. IAuthData authentication information
transformResponseFunctionNoTransforms the response result, defined as (body: any, response: RequestResponse) => Promise<Record<string, any>>. This method may not exist and should be checked before use. Some third-party data sources return responses wrapped in structures like {code, data, message} (e.g., Tencent Docs) where the actual business result (including success/failure) is encapsulated, or return non-standard formats. In such cases, transformResponse can be used to uniformly convert the returned result: throwing errors for business failures and returning the final result for successful business calls

IAuthData

The following fields, except for authInfo, are constructed using authInfo and encapsulated for ease of use. You can also refer to third-party official API documentation to construct them.

ParameterTypeRequiredDescription
authInfoobjectRequiredThe raw authentication information returned by the backend token interface. The structure of authentication information varies across different types of external data sources. For details, refer to Tencent Meeting Authentication Information and Tencent Docs Authentication Information
uristringNoThe converted request address URI. If this field is returned, it should be used as the final request URL
headersobjectNoCommon request headers, including other public headers required for authentication such as accessToken (may vary across different data sources). If this field is returned, it should be merged with the original headers
bodyobjectNoCommon body parameters, such as the userid field in Tencent Meeting. If this field is returned, it should be merged with the original body
qsobjectNoCommon query string. If this field is returned, it should be merged with the original qs

Tencent Meeting Authentication Information

ParameterTypeRequiredDescription
AccessTokenstringRequiredTencent Meeting access_token
OpenIdstringRequiredTencent Meeting openid, which is the userid used in the API

Tencent Docs Authentication Information

ParameterTypeRequiredDescription
AccessTokenstringRequiredTencent Docs access_token
ClientIdstringRequiredTencent Docs application id
OpenIdstringRequiredUser's openid
TokenTypestringRequiredUser's token type
ScopestringRequiredUser authorization scope

Custom Cloud Function Example:

/**
* Create a Tencent Meeting, official API documentation https://cloud.tencent.com/document/product/1095/42417
*/
const request = require('request');

/** Determine if the request was successful based on the http status code */
function isSuccessStatusCode(code) {
return code >= 200 && code < 300;
}

module.exports = async function (params, context){
const { subject, type, start_time, end_time, password } = params;
// request request configuration information
const requestConfig = {
uri: 'https://api.meeting.qq.com/v1/meetings',
method: 'POST',
body: {
instanceid: 1,
subject,
type,
start_time: `${Math.floor(start_time / 1000)}`,
end_time: `${Math.floor(end_time / 1000)}`,
password,
},
// Set json to true, and the response body will be automatically converted to an object
// In POST requests, the Content-Type will also be automatically set to application/json
json: true
};
// Get authentication information
const authData = await context.httpAuth.getAuthData(requestConfig);
// Merge configuration information
const finalRequestConfig = mergeAuthData(requestConfig, authData);
// `params` is the structure defined for input parameters and can be used in the request configuration
return new Promise(function (resolve, reject) {
// Note: The callback function of request is an async function because there is an await call inside the function
request(finalRequestConfig, async function (err, response, body) {
if (err) return reject(err);
if (!isSuccessStatusCode(response.statusCode)) {
// When the request fails, the body will contain detailed error information
return reject(new Error(`request failed: code: ${response.statusCode}, msg: ${JSON.stringify(body)}`));
}
let result = body
// The data source does not actually provide transformResponse for Tencent Meeting, and the following code can also be removed
if (context.httpAuth.transformResponse) {
result = await context.httpAuth.transformResponse(body, response);
}
// When successful, the body is empty
return resolve(result);
}
);
});
}

/**
* Merge the request configuration with that in IAuthData
*/
function mergeAuthData(requestConfig, authData) {
const newConfig = Object.assign({}, requestConfig);
if (authData.uri) {
newConfig.uri = authData.uri;
}
if (authData.body) {
if (requestConfig.form) {
newConfig.form = Object.assign(newConfig.form || {}, authData.body);
} else if (!newConfig.body || typeof newConfig.body === 'object') {
newConfig.body = Object.assign(newConfig.body || {}, authData.body);
// Set contentType to json again to avoid the issue of contentType not being set when requestConfig.body is empty
newConfig.json = true;
}
}
if (authData.headers) {
newConfig.headers = Object.assign(newConfig.headers || {}, authData.headers);
}

if (authData.qs) {
newConfig.qs = Object.assign(newConfig.qs || {}, authData.qs);
}
return newConfig;
}

Official API Documentation for Built-in Third-Party Data Sources

Tencent Docs:

Currently, WeDa has only integrated sheet-related interfaces, and other APIs can be integrated according to the API documentation.

Tencent Meeting:

WeDa integrates Tencent Meeting using OAuth2.0. Currently, only meeting management related APIs support OAuth2.0 invocation, and all meeting management related APIs have been built into the meeting data source template.
The meeting management related APIs have very rich parameters. For user convenience, WeDa only provides common required parameters in its encapsulation. If you need to use parameters not supported in the WeDa template, you can refer to the official Tencent Meeting API documentation to modify the encapsulation of corresponding methods in the meeting data source.