Key Concepts
Understanding these fundamental concepts will help you write effective Cloud Code.
Understanding these fundamental concepts will help you write effective Cloud Code.
File Structure
A typical Cloud Code project has a simple structure:
your-cloud-code/
├── main.js # Main entry point (required)
├── lib/ # Optional: reusable modules
│ ├── helpers.js
│ └── validators.js
└── config/ # Optional: configuration files
└── constants.jsMain Entry Point
The main.js file is where you register all your Cloud Code handlers:
// main.js
// Register callbacks
Nimbu.Cloud.before('created', 'customers', validateCustomer);
// Register functions
Nimbu.Cloud.define('calculateTotal', calculateOrderTotal);
// Register routes
Nimbu.Cloud.get('/api/products', listProducts);
// Register jobs
Nimbu.Cloud.job('daily_cleanup', cleanupOldData);
// Schedule recurring jobs
Nimbu.Cloud.schedule('daily_cleanup', {}, {
every: '0 2 * * *' // Daily at 2 AM
});Organizing Your Code
For larger projects, split your code into multiple files:
// main.js
const validators = require('lib/validators');
const helpers = require('lib/helpers');
Nimbu.Cloud.before('created', 'orders', validators.validateOrder);
Nimbu.Cloud.define('formatPrice', helpers.formatPrice);// lib/validators.js
exports.validateOrder = (req, res) => {
// Validation logic
};// lib/helpers.js
exports.formatPrice = (req, res) => {
// Formatting logic
};Module System
Cloud Code uses a require() function to load modules. You can require:
- Native Nimbu modules - Built-in modules like
http,mail,crypto - Your own files - Custom JavaScript files in your project
Requiring Native Modules
Native modules are available through the require() function:
const HTTP = require('http');
const Mail = require('mail');
const Crypto = require('crypto');Requiring Your Own Files
Load your own JavaScript files using relative or absolute paths:
// Relative path from main.js
const helpers = require('lib/helpers');
// Files must export functions/objects
// lib/helpers.js:
exports.formatDate = (date) => {
// formatting logic
};Available Native Modules
Cloud Code provides many built-in modules for common tasks. Here's an overview organized by category:
Encoding & Data Formats
| Module | Purpose | Example |
|---|---|---|
atob | Base64 decode | atob.decode('SGVsbG8=') |
btoa | Base64 encode | btoa.encode('Hello') |
crypto | Cryptographic operations | Crypto.createHash('sha256') |
csv | Parse and generate CSV files | Csv.parse(csvString) |
xml | XML parsing and generation | Xml.parse(xmlString) |
zip | Create ZIP archives | Zip.create([{filename, contents}]) |
jwt | JSON Web Token operations | Jwt.encode(payload, secret) |
External Communication
| Module | Purpose | Example |
|---|---|---|
http | Make HTTP requests | HTTP.get(url) |
mail | Send emails | Mail.send({to, subject, text}) |
soap | SOAP web service calls | Soap.call(wsdl, operation, message) |
oauth2 | OAuth2 authentication | OAuth2.getToken(options) |
Cloud Storage
| Module | Purpose | Example |
|---|---|---|
s3 | AWS S3 operations | S3.generate_upload_url(options) |
azure | Azure Blob storage | Azure.generate_sas(options) |
Payment Integrations
| Module | Purpose | Example |
|---|---|---|
mollie | Mollie payment API | Mollie.createPayment(params) |
stripe | Stripe payment API | Stripe.createCheckoutSession(params) |
Content & Media
| Module | Purpose | Example |
|---|---|---|
pdf | Generate PDF files | Pdf.render(html, options) |
imgkit | Image manipulation | Image processing operations |
html | HTML sanitization | Html.strip_html(text) |
Nimbu-Specific
| Module | Purpose | Example |
|---|---|---|
site_variables | Access site environment variables | SiteVariables.get('API_KEY') |
order_helpers | Order processing utilities | OrderHelpers.queueAttachmentProcessing(order) |
i18n | Internationalization | I18n.t('key', variables) |
signer | HMAC signing | Signer.sign(data, secret) |
Utilities
| Module | Purpose | Example |
|---|---|---|
fs | Read bundled files | Fs.readFileSync('config/data.json') |
gc | Garbage collection | Gc.run() |
googleauth | Google service account auth | Googleauth.token(scope) |
Common Module Usage Examples
Making HTTP Requests
const HTTP = require('http');
// GET request
const response = await HTTP.get('https://api.example.com/data');
console.log(response.body);
// POST request
const result = await HTTP.post('https://api.example.com/submit', {
body: JSON.stringify({ name: 'John' }),
headers: { 'Content-Type': 'application/json' }
});Sending Emails
const Mail = require('mail');
// Simple email
await Mail.send({
to: '[email protected]',
subject: 'Welcome!',
text: 'Thanks for signing up!'
});
// Template-based email
await Mail.send({
to: '[email protected]',
template: 'welcome_email',
variables: {
name: 'John Doe',
confirmationUrl: 'https://...'
}
});Cryptographic Operations
const Crypto = require('crypto');
// Generate hash
const hash = Crypto.calculate_hash({
data: 'sensitive data',
algorithm: 'sha256',
digest: 'hex'
});
// Generate HMAC
const hmac = Crypto.calculate_hmac({
data: 'message',
key: 'secret',
algorithm: 'sha256',
digest: 'hex'
});Working with CSV
const Csv = require('csv');
// Parse CSV
const data = Csv.parse(csvString, {
headers: true,
delimiter: ','
});
// Generate CSV
const csv = Csv.to_csv([
['Name', 'Email'],
['John Doe', '[email protected]'],
['Jane Smith', '[email protected]']
]);Site Environment Variables
const SiteVariables = require('site_variables');
// Get a variable
const apiKey = SiteVariables.get('STRIPE_API_KEY');
// Check if a variable exists
if (SiteVariables.has('MAILCHIMP_KEY')) {
// Use the key
}
// Get all variable names
const keys = SiteVariables.keys();Console Logging
Use standard console methods for debugging:
console.log('Info message');
console.info('Information');
console.warn('Warning message');
console.error('Error occurred');
console.debug('Debug information');All console output is captured in the Cloud Code logs, which you can view in the Nimbu admin interface.
Logging Best Practices
// Log at the start of handlers
console.log('[Job: send_newsletter] Starting execution');
// Log important data
console.log('Processing order:', order.id);
// Log errors with context
try {
await someOperation();
} catch (error) {
console.error('Operation failed:', error.message);
throw error;
}
// Log completion
console.log('[Job: send_newsletter] Completed successfully');Runtime Environment
JavaScript Support
Cloud Code runs on a V8 JavaScript engine with full modern JavaScript support:
- ES6+ features - arrow functions, template literals, destructuring, etc.
- async/await - Full support for asynchronous operations
- Promises - Native Promise support
- Classes - ES6 class syntax
// Modern JavaScript is fully supported
const processOrder = async (order) => {
const { items, customer } = order;
const total = items.reduce((sum, item) => sum + item.price, 0);
await customer.set('total_spent', total);
await customer.save();
};Execution Limits
To ensure fair resource usage, Cloud Code has execution limits:
-
Timeout limits - Handlers must complete within allocated time
- Callbacks: ~5 seconds
- Functions: ~10 seconds
- Routes: ~30 seconds
- Jobs: ~5 minutes
-
Memory limits - Reasonable memory usage expected
-
Network timeouts - HTTP requests timeout after 30 seconds
What's NOT Available
Unlike Node.js, Cloud Code runs in a sandboxed environment. Some Node.js features are not available:
- ❌ File system access (except reading your own bundled files with
fsmodule) - ❌ Installing npm packages
- ❌ Direct database connections
- ❌ Child processes
- ❌ Most Node.js built-in modules
Instead, use:
- ✅ Nimbu SDK for data operations
- ✅ Built-in HTTP module for external APIs
- ✅ Built-in modules for common tasks
Best Practices
1. Keep Code Organized
// Good: Organized into modules
const validators = require('lib/validators');
Nimbu.Cloud.before('created', 'orders', validators.validateOrder);
// Avoid: Everything in main.js
Nimbu.Cloud.before('created', 'orders', (req, res) => {
// 100 lines of validation logic here...
});2. Use Environment Variables for Secrets
// Good: Use site variables
const SiteVariables = require('site_variables');
const apiKey = SiteVariables.get('STRIPE_API_KEY');
// Avoid: Hard-coded secrets
const apiKey = 'sk_live_abc123...'; // Never do this!3. Handle Errors Gracefully
// Good: Proper error handling
try {
await HTTP.post(webhookUrl, data);
res.success();
} catch (error) {
console.error('Webhook failed:', error.message);
res.error('Failed to send webhook');
}
// Avoid: Unhandled errors
await HTTP.post(webhookUrl, data); // Might crash4. Log Meaningful Information
// Good: Contextual logging
console.log('[Newsletter] Sending to', customer.get('email'));
// Avoid: Generic logging
console.log('Doing stuff'); // Not helpful for debugging5. Use Async/Await
// Good: Modern async/await
const customers = await query.collection().fetch();
for (const customer of customers.models) {
await sendEmail(customer);
}
// Avoid: Callback hell
query.collection().fetch().then(customers => {
customers.forEach(customer => {
sendEmail(customer).then(() => {
// nested callbacks...
});
});
});customers is a Nimbu.Collection, not a plain array. Iterate via .models or use .forEach/.map. See Queries for the difference between find() and collection().fetch().
Next Steps
Now that you understand the basics, explore specific Cloud Code features:
- Callbacks - React to data changes
- Cloud Functions - Create callable server-side functions
- Routes - Build custom HTTP endpoints
- Extensions - Add custom admin actions
- Background Jobs - Schedule automated tasks
- Available Modules - Complete module reference
Cloud Code Overview
Cloud Code allows you to run custom JavaScript code on Nimbu's servers. This enables you to add server-side logic to your Nimbu site without managing your own infrastructure.
Callbacks
Callbacks allow you to execute custom code before or after data operations. Use them to validate data, enforce business rules, or trigger side effects when objects are created,…