Skip to main content
Technology & EngineeringBaas273 lines

Backendless

Backendless BaaS with real-time database, user authentication, Cloud Code,

Quick Summary30 lines
You are an expert in Backendless for rapid backend development, including its real-time database, user authentication and role management, Cloud Code (serverless business logic), real-time messaging, and file storage.

## Key Points

* @param {Object} order
* @returns {Object}
- Use the Backendless Console data viewer to define schemas and set column types explicitly rather than relying solely on auto-schema creation, which can infer incorrect types.
- Store sensitive configuration (API keys, secrets) in environment variables; never hardcode them in client-side bundles.
- Use Cloud Code event handlers (`beforeCreate`, `afterUpdate`) for validation and enrichment instead of trusting client-supplied data.
- Leverage data relations and the `setRelated()` query builder method to load related objects in a single request rather than making multiple round trips.
- Enable and configure user roles and permissions through the Console to enforce data access control at the API level.
- Use `setPageSize()` and `setOffset()` on `DataQueryBuilder` for pagination; never fetch unbounded result sets.
- Prefer real-time database listeners (`rt().addCreateListener`) over polling for live data updates.
- **Skipping schema design**: Letting auto-schema infer all column types leads to mismatched types (e.g., strings where numbers are expected) and silent data corruption.
- **Client-side-only validation**: Relying on the frontend to validate data without Cloud Code hooks allows malicious or malformed requests to bypass checks.
- **Ignoring relation depth**: Loading deeply nested relations without controlling `setRelationsDepth()` can trigger excessive queries and slow responses.

## Quick Example

```bash
npm install backendless
```

```
BACKENDLESS_APP_ID=<your-application-id>
BACKENDLESS_API_KEY=<your-javascript-api-key>
BACKENDLESS_SERVER_URL=https://api.backendless.com   # default; change for Backendless Pro
```
skilldb get baas-skills/BackendlessFull skill: 273 lines
Paste into your CLAUDE.md or agent config

Backendless — Backend as a Service

You are an expert in Backendless for rapid backend development, including its real-time database, user authentication and role management, Cloud Code (serverless business logic), real-time messaging, and file storage.

Core Philosophy

Backendless is a full-featured mobile Backend-as-a-Service platform that abstracts away server infrastructure so developers can focus on client-side logic and user experience. It provides a visual console for managing data schemas, user tables, Cloud Code handlers, and API services alongside programmatic SDKs for JavaScript, Android, iOS, and Flutter. The platform supports both cloud-hosted and self-hosted (Backendless Pro) deployments.

You choose Backendless when you need a managed backend with a rich data modeling console, built-in user management with roles and permissions, codeless and coded serverless logic, and real-time messaging channels — all accessible through a single dashboard and unified SDK. Its data table approach feels closer to relational databases than document stores, making it a natural fit for developers coming from SQL backgrounds who still want the convenience of a BaaS.

Setup & Configuration

SDK Installation

npm install backendless

Client Initialization

import Backendless from 'backendless';

const APP_ID = process.env.BACKENDLESS_APP_ID;
const API_KEY = process.env.BACKENDLESS_API_KEY;

Backendless.initApp(APP_ID, API_KEY);

Environment Variables

BACKENDLESS_APP_ID=<your-application-id>
BACKENDLESS_API_KEY=<your-javascript-api-key>
BACKENDLESS_SERVER_URL=https://api.backendless.com   # default; change for Backendless Pro

For self-hosted Backendless Pro instances, set a custom server URL before calling initApp:

Backendless.serverURL = process.env.BACKENDLESS_SERVER_URL;
Backendless.initApp(APP_ID, API_KEY);

Key Techniques

Data Persistence (Backendless Database)

Backendless uses a table-based data model. You can define schemas in the console or let the SDK auto-create columns on first save.

// Save a new object
const order = {
  product: 'Widget',
  quantity: 3,
  price: 29.99,
  status: 'pending',
};

const savedOrder = await Backendless.Data.of('Order').save(order);
console.log('Created:', savedOrder.objectId);

// Find with a where clause
const queryBuilder = Backendless.DataQueryBuilder.create()
  .setWhereClause("status = 'pending'")
  .setSortBy(['created DESC'])
  .setPageSize(10);

const pendingOrders = await Backendless.Data.of('Order').find(queryBuilder);

// Find by ID
const single = await Backendless.Data.of('Order').findById(savedOrder.objectId);

// Update
single.status = 'shipped';
await Backendless.Data.of('Order').save(single);

// Delete
await Backendless.Data.of('Order').remove(single.objectId);

// Bulk delete
await Backendless.Data.of('Order').bulkDelete("status = 'cancelled'");

// Load related objects (1:N relation)
const qb = Backendless.DataQueryBuilder.create()
  .setRelated(['items']);
const orderWithItems = await Backendless.Data.of('Order').findById(orderId, qb);

User Authentication and Management

Backendless includes a built-in Users table with registration, login, roles, and password recovery.

// Register a new user
const user = new Backendless.User();
user.email = 'alice@example.com';
user.password = 'securePassword123';
user.name = 'Alice';

const registeredUser = await Backendless.UserService.register(user);

// Login
const loggedInUser = await Backendless.UserService.login(
  'alice@example.com',
  'securePassword123',
  true // stayLoggedIn
);

// Get current user
const currentUser = await Backendless.UserService.getCurrentUser();

// Check if user is logged in
const isValid = await Backendless.UserService.isValidLogin();

// Logout
await Backendless.UserService.logout();

// Password recovery (sends reset email)
await Backendless.UserService.restorePassword('alice@example.com');

// OAuth login (e.g., Google)
const googleUser = await Backendless.UserService.loginWithOauth2(
  'google',
  accessToken,
  null,    // fieldsMappings
  true     // stayLoggedIn
);

// Assign a role
await Backendless.UserService.assignRole(
  registeredUser.email,
  'Admin'
);

Real-Time Messaging

Backendless Messaging provides pub/sub channels for real-time communication.

// Subscribe to a channel
const channel = Backendless.Messaging.subscribe('chat-room');

channel.addMessageListener((message) => {
  console.log('Received:', message.data);
});

// Publish a message
await Backendless.Messaging.publish('chat-room', {
  text: 'Hello, world!',
  sender: currentUser.objectId,
});

// Real-time database listeners (event-driven)
const rtHandler = Backendless.Data.of('Order').rt();

rtHandler.addCreateListener((createdOrder) => {
  console.log('New order:', createdOrder);
});

rtHandler.addUpdateListener("status = 'shipped'", (updatedOrder) => {
  console.log('Order shipped:', updatedOrder);
});

rtHandler.addDeleteListener((deletedOrder) => {
  console.log('Order removed:', deletedOrder);
});

// Cleanup
rtHandler.removeCreateListeners();
channel.removeAllMessageListeners();

Cloud Code (Serverless Business Logic)

Cloud Code lets you run server-side JavaScript, Java, or Codeless logic triggered by API events, timers, or custom endpoints.

// Deploy via Backendless Console or the CodeRunner CLI
// npm install -g backendless-coderunner

// Event handler: beforeCreate hook for the Order table
Backendless.ServerCode.Persistence.beforeCreate('Order', function (req) {
  const order = req.item;

  // Validate before saving
  if (!order.product || order.quantity < 1) {
    throw new Error('Invalid order: product and quantity are required');
  }

  // Enrich with server-side data
  order.totalPrice = order.quantity * order.price;
  order.createdBy = req.context.userId;

  return order;
});

// Custom API service (exposed as a REST endpoint)
class ShippingService {
  /**
   * @param {Object} order
   * @returns {Object}
   */
  calculateRate(order) {
    const baseRate = 5.99;
    const perItem = 1.50;
    return {
      rate: baseRate + (order.quantity * perItem),
      estimatedDays: order.quantity > 10 ? 7 : 3,
    };
  }
}

Backendless.ServerCode.addService(ShippingService);
# Run CodeRunner locally for development
npx backendless-coderunner --app-id $APP_ID --app-key $API_KEY debug

# Deploy to production
npx backendless-coderunner --app-id $APP_ID --app-key $API_KEY deploy

File Storage

// Upload a file
const filePath = '/avatars/alice.png';
const uploadedFile = await Backendless.Files.upload(file, filePath, true);
console.log('File URL:', uploadedFile.fileURL);

// Upload from a data URL or text
await Backendless.Files.saveFile('/reports', 'summary.txt', 'Report contents here');

// List files in a directory
const files = await Backendless.Files.listing('/avatars');

// Get file count in a directory
const count = await Backendless.Files.getFileCount('/avatars');

// Delete a file
await Backendless.Files.remove('/avatars/alice.png');

// Delete a directory
await Backendless.Files.removeDirectory('/old-reports');

Best Practices

  • Use the Backendless Console data viewer to define schemas and set column types explicitly rather than relying solely on auto-schema creation, which can infer incorrect types.
  • Store sensitive configuration (API keys, secrets) in environment variables; never hardcode them in client-side bundles.
  • Use Cloud Code event handlers (beforeCreate, afterUpdate) for validation and enrichment instead of trusting client-supplied data.
  • Leverage data relations and the setRelated() query builder method to load related objects in a single request rather than making multiple round trips.
  • Enable and configure user roles and permissions through the Console to enforce data access control at the API level.
  • Use setPageSize() and setOffset() on DataQueryBuilder for pagination; never fetch unbounded result sets.
  • Prefer real-time database listeners (rt().addCreateListener) over polling for live data updates.

Anti-Patterns

  • Skipping schema design: Letting auto-schema infer all column types leads to mismatched types (e.g., strings where numbers are expected) and silent data corruption.
  • Client-side-only validation: Relying on the frontend to validate data without Cloud Code hooks allows malicious or malformed requests to bypass checks.
  • Fetching without pagination: Calling find() with no page size limit returns only the default 100 records and gives no indication that more exist — always set explicit page sizes and handle paging.
  • Ignoring relation depth: Loading deeply nested relations without controlling setRelationsDepth() can trigger excessive queries and slow responses.
  • Hardcoding the server URL for cloud: The default https://api.backendless.com is correct for cloud-hosted apps; only override it for Backendless Pro self-hosted instances.

Install this skill directly: skilldb add baas-skills

Get CLI access →