Writing Regular Cloud Functions
Basic Code Example
Here's a simple Node.js cloud function example showing how to handle input parameters and return results:
// index.js - Cloud function entry file
exports.main = async (event, context) => {
// 1. Parse cloud function input parameters
const { a, b } = event;
// 2. Execute business logic
const sum = a + b;
// 3. Return result
return {
sum,
timestamp: Date.now(),
requestId: context.requestId,
};
};
Async Processing Best Practices
Since instance management is handled automatically by the platform, it's recommended to use the async/await pattern in cloud functions and avoid Promise chaining:
exports.main = async (event, context) => {
// ❌ Not recommended: Promise chaining
getList().then((res) => {
// do something...
});
// ✅ Recommended: Use async/await
const res = await getList();
// do something...
};
Function Input Parameters
Each cloud function invocation receives two important objects: event and context.
event Object
The event object contains event data that triggers the cloud function, with content varying based on the trigger method:
- Mini Program invocation: Contains parameters passed from the mini program
- HTTP request invocation: Contains HTTP request information (such as request headers, request body, etc.)
- Scheduled trigger: Contains information related to scheduled triggers
context Object
The context object provides invocation context information, helping you understand the function's runtime environment and invocation method:
- Request ID: Unique identifier for the current invocation
- Invocation source: Information about the service or client that triggered the function
- Execution environment: Runtime information of the function
- User identity: Identity information of the caller (if available)
Function Return Values
Cloud functions support two response methods: simple response and integration response. The system automatically recognizes the response type based on the return value format.
Simple Response
Return data directly, and the system automatically generates a standard HTTP response.
- Return String
- Return JSON
exports.main = async () => {
return "Hello CloudBase";
};
HTTP Response:
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Hello CloudBase
exports.main = async () => {
return {
success: true,
data: { id: 123, name: "CloudBase" },
timestamp: Date.now()
};
};
HTTP Response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{"success":true,"data":{"id":123,"name":"CloudBase"},"timestamp":1699999999999}
Integration Response (Advanced)
Use the integration response format when you need precise control over HTTP status codes, response headers, etc.:
{
statusCode: number, // HTTP status code (required)
headers: { // HTTP response headers (optional)
"headerName": "headerValue"
},
body: string, // Response body content (optional)
isBase64Encoded: boolean // Whether body is Base64 encoded (optional)
}
💡 Recognition Rule: The system recognizes it as an integration response when the return value contains the
statusCodefield.
Integration Response Examples
- Return HTML Page
- Page Redirect
- Return Image
- Error Response
- Return JavaScript
exports.main = async () => {
return {
statusCode: 200,
headers: {
"Content-Type": "text/html; charset=utf-8"
},
body: `
<!DOCTYPE html>
<html>
<head><title>CloudBase</title></head>
<body>
<h1>Welcome to CloudBase</h1>
<p>This is an HTML page returned through cloud function</p>
</body>
</html>
`
};
};
The browser will directly render this HTML page when accessed.
exports.main = async (event) => {
const { path } = event;
return {
statusCode: 302,
headers: {
"Location": `https://docs.cloudbase.net${path}`
}
};
};
Accessing the cloud function will automatically redirect to the specified URL.
const fs = require('fs');
const path = require('path');
exports.main = async () => {
// Read image file and convert to Base64
const imagePath = path.join(__dirname, 'image.png');
const imageBuffer = fs.readFileSync(imagePath);
const base64Image = imageBuffer.toString('base64');
return {
statusCode: 200,
headers: {
"Content-Type": "image/png"
},
body: base64Image,
isBase64Encoded: true
};
};
⚠️ Note: Binary files (images, audio/video, etc.) must set
isBase64Encoded: true.
exports.main = async (event) => {
const { queryStringParameters } = event;
// Parameter validation
if (!queryStringParameters?.userId) {
return {
statusCode: 400,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
error: "Bad Request",
message: "userId parameter cannot be empty"
})
};
}
// Business logic
const userId = queryStringParameters.userId;
try {
// ... Process business logic
return {
statusCode: 200,
body: JSON.stringify({ success: true })
};
} catch (error) {
return {
statusCode: 500,
body: JSON.stringify({
error: "Internal Server Error",
message: error.message
})
};
}
};
exports.main = async () => {
return {
statusCode: 200,
headers: {
"Content-Type": "application/javascript"
},
body: `
console.log("Hello from CloudBase!");
window.cloudbaseConfig = {
envId: "your-env-id",
region: "ap-shanghai"
};
`
};
};
Can be used to dynamically generate JavaScript configuration files.
Installing Third-Party Dependencies
When cloud functions need to use third-party npm packages, you must first install the corresponding dependency packages. The CloudBase online editor provides convenient dependency management functionality.
Open Terminal
In the CloudBase online editor, you can open the terminal in the following ways:
- Keyboard shortcut: Use
Ctrl + J (Windows/Linux)orcommand + J (macOS) - Menu operation: Click the "Terminal" button at the top of the editor and select "New Terminal"
Install Dependencies
Use the npm add command in the terminal to install required dependency packages.
Taking the CloudBase Node.js SDK as an example:
npm add @cloudbase/node-sdk
Install other commonly used dependency packages:
# Timezone handling library
npm add moment-timezone
# HTTP request library
npm add axios
# Utility library
npm add lodash
Use Dependencies
After installation, you can reference these dependencies in your code:
The Node.js environment in cloud functions cannot directly use ES Module specification to write code. The main reason is that the default entry file (index.js) supported by cloud functions must follow the CommonJS specification. If you need to use ES Module specification, please refer to Using ES Module Specification
const cloudbase = require('@cloudbase/node-sdk');
exports.main = async (event, context) => {
// Initialize CloudBase
const app = cloudbase.init({
env: 'your-envid', // Replace with your environment ID
});
const db = app.database();
const collection = db.collection('users');
// Query data
const { data } = await collection.get();
return {
success: true,
count: data.length,
};
};
Upload and Deploy
After completing code writing and dependency installation, choose the appropriate upload method based on your project:
- With third-party dependencies: Click the "Save and Install Dependencies" button
- The system will automatically upload code files and
package.json - Automatically execute
npm installin the cloud environment to install dependencies - Ensure the cloud function runtime can correctly load all dependency packages
- The system will automatically upload code files and
- Without third-party dependencies: Click the "Save" button
- Only upload code files
- Suitable for cloud functions that don't use third-party dependencies
- Avoid installing too many unnecessary dependencies to reduce function package size and startup time
Environment Variables Usage
Cloud functions can access environment variables through process.env, which is a best practice for managing configuration information:
Get Environment Variables
exports.main = async (event, context) => {
// Get environment variables
const dbUrl = process.env.DATABASE_URL;
const apiKey = process.env.API_KEY;
const nodeEnv = process.env.NODE_ENV || 'development';
// Use environment variables for configuration
const config = {
database: dbUrl,
apiKey: apiKey,
debug: nodeEnv === 'development',
};
return {
message: 'Environment variables retrieved successfully',
environment: nodeEnv,
};
};
Environment Variables Best Practices
exports.main = async (event, context) => {
// Check required environment variables
const requiredEnvVars = ['DATABASE_URL', 'API_KEY'];
const missingVars = requiredEnvVars.filter((varName) => !process.env[varName]);
if (missingVars.length > 0) {
throw new Error(`Missing required environment variables: ${missingVars.join(', ')}`);
}
// Safely use environment variables
const config = {
dbUrl: process.env.DATABASE_URL,
apiKey: process.env.API_KEY,
timeout: parseInt(process.env.TIMEOUT) || 5000,
};
return { success: true, config };
};
- Sensitive information (such as API keys, database connection strings) should be passed through environment variables, not hardcoded in code
- Environment variable values are always string type, perform type conversion when needed
- It's recommended to set default values for environment variables to improve code robustness
Timezone Settings
The runtime environment of cloud functions maintains UTC time, which is timezone 0, with an 8-hour time difference from Beijing time.
You can use time processing libraries or packages (such as moment-timezone) to recognize UTC time and convert it to +8 zone Beijing time.
Timezone Handling Example
const moment = require('moment-timezone'); // Need to specify and install dependency in package.json
exports.main = async (event, context) => {
// javascript date
console.log(new Date()); // 2021-03-16T08:04:07.441Z (UTC+0)
console.log(moment().tz('Asia/Shanghai').format()); // 2021-03-16T16:04:07+08:00 (UTC+8)
// Get current Beijing time
const beijingTime = moment().tz('Asia/Shanghai');
return {
utcTime: new Date().toISOString(),
beijingTime: beijingTime.format(),
timestamp: beijingTime.valueOf(),
};
};
Timezone Handling Best Practices
const moment = require('moment-timezone');
exports.main = async (event, context) => {
// Unified timezone handling function
const getBeijingTime = (date = new Date()) => {
return moment(date).tz('Asia/Shanghai');
};
// Format time output
const formatTime = (date, format = 'YYYY-MM-DD HH:mm:ss') => {
return getBeijingTime(date).format(format);
};
// Use in business logic
const currentTime = getBeijingTime();
const formattedTime = formatTime();
console.log('Current Beijing time:', formattedTime);
return {
success: true,
currentTime: formattedTime,
timestamp: currentTime.valueOf(),
};
};
Using ES Module Specification
The Node.js environment in cloud functions cannot directly use ES Module specification to write code. The main reason is that the default entry file (index.js) supported by cloud functions must follow the CommonJS specification, and the filename must be "index.js". However, Node.js requires module files that conform to ES Module specification to have the .mjs extension.
Using ES Module in cloud functions requires creating three core files, forming a complete call chain: index.js → entry.mjs → util.mjs
Project Structure
cloud-function/
├── index.js # Cloud function entry file (CommonJS)
├── entry.mjs # ES Module entry file
└── src
└── util.mjs # Business logic module, name can be customized
1. Create Cloud Function Entry File index.js
// index.js - Cloud function entry file
exports.main = async (event, context) => {
try {
// Dynamically import ES Module entry file
const { entry } = await import('./entry.mjs');
return await entry(event, context);
} catch (error) {
console.error('Cloud function execution failed:', error);
return {
success: false,
error: error.message,
requestId: context.request_id
};
}
};
2. Create ES Module Entry File entry.mjs
// entry.mjs - ES Module entry file
import { getUserList } from './src/util.mjs';
/**
* ES Module entry function
* @param {Object} event - Event object
* @param {Object} context - Context object
* @returns {Promise<Object>} Processing result
*/
export const entry = async (event, context) => {
return getUserList(event, context);
};
3. Create Business Logic Module util.mjs
// src/util.mjs - Business logic module
import cloudbase from '@cloudbase/node-sdk';
const app = cloudbase.init({
env: 'your-envid', // Replace with your environment ID
});
const models = app.models;
export const getUserList = async (event) => {
const res = await models.user.list({});
return {
success: true,
data: res,
};
};
💡 Note: ES Module files must use the
.mjsextension so Node.js can correctly recognize and process ES Module syntax.
Error Handling and Logging
Error Handling Best Practices
exports.main = async (event, context) => {
try {
// Parameter validation
if (!event.userId) {
throw new Error('Missing required parameter: userId');
}
// Business logic processing
const result = await processUserData(event.userId);
return {
success: true,
data: result,
};
} catch (error) {
// Log error
console.error('Function execution failed:', {
error: error.message,
stack: error.stack,
event,
requestId: context.requestId,
});
// Return friendly error message
return {
success: false,
error: error.message,
requestId: context.requestId,
};
}
};
Performance Optimization Recommendations
Execution Time Optimization
exports.main = async (event, context) => {
const startTime = Date.now();
try {
// Use parallel processing to improve performance
const promises = event.items.map((item) => processItem(item));
const results = await Promise.all(promises);
const duration = Date.now() - startTime;
console.log(`Function execution time: ${duration}ms`);
return {
success: true,
data: results,
duration,
};
} catch (error) {
console.error('Execution error:', error);
throw error;
}
};
Memory Usage Optimization
exports.main = async (event, context) => {
// Process large data in batches to avoid memory overflow
const batchSize = parseInt(process.env.BATCH_SIZE) || 100;
const results = [];
for (let i = 0; i < event.data.length; i += batchSize) {
const batch = event.data.slice(i, i + batchSize);
const batchResult = await processBatch(batch);
results.push(...batchResult);
// Clean up unnecessary variables promptly
batch.length = 0;
// Log processing progress
console.log(`Processed ${Math.min(i + batchSize, event.data.length)}/${event.data.length} records`);
}
return results;
};