Home›Developer docs›Cloud code

Cloud code

Updated Nov 13, 20264 min read

Write and deploy server-side code for your SashiDo app. The GitHub repository, functions, triggers, background jobs, webhooks, your own Express routes and static files, npm packages, environment variables, logs and local development.

Cloud code is the JavaScript that runs inside your app's Parse Server: functions your clients call, triggers on saves and deletes, background jobs, and your own HTTP routes.

The repository

Every app has a private GitHub repository. In Core › Cloud Code, link your GitHub account and accept the invitation, then clone it:

cloud/
  main.js        ← loaded by Parse Server: require your other files from here
  functions.js
  app.js         ← your own Express routes ("Advanced Cloud Code")
public/          ← static files, served at your app's public URL
package.json     ← npm dependencies, installed on every build
index.js         ← runs the app locally (see below)

Keep cloud/main.js as the entry point: SashiDo loads that path.

Deploy

Push to the repository's master branch. SashiDo builds the code (installing the dependencies in package.json) and deploys it, one deployment at a time. Follow it in Runtime › Builds and Runtime › Deployments; a failed build keeps the previous version running, and its log says why.

From a terminal or CI: POST /apps/{id}/build and /deploy with the Management API, or ask your AI assistant to deploy and wait (deploy_app, wait_for_deployment).

Functions

// cloud/functions.js
Parse.Cloud.define('averageRating', async (request) => {
  const { movie } = request.params;
  if (!movie) throw new Parse.Error(Parse.Error.INVALID_QUERY, 'movie is required');
  const reviews = await new Parse.Query('Review').equalTo('movie', movie).find();
  return reviews.reduce((sum, r) => sum + r.get('stars'), 0) / (reviews.length || 1);
});
// a client
const rating = await Parse.Cloud.run('averageRating', { movie: 'Arrival' });

request.user is the logged-in caller (or undefined), request.master says whether the master key was used. Queries in a function run with the caller's permissions unless you pass { useMasterKey: true }.

Triggers

Trigger Runs Typical use
beforeSave Before an object is saved Validate, normalize, set the ACL
afterSave After it's saved Counters, notifications, sync to other systems
beforeDelete / afterDelete Around a delete Refuse, clean up related objects
beforeFind / afterFind Around a query Limit what a query may return
Parse.Cloud.beforeSave('Review', (request) => {
  const stars = request.object.get('stars');
  if (!(stars >= 1 && stars <= 5)) {
    throw new Parse.Error(Parse.Error.VALIDATION_ERROR, 'stars must be 1 to 5');
  }
});

Throwing refuses the operation, and the client gets the error. Triggers run on every matching request, so keep them fast: see Performance.

Background jobs

Long or periodic work (cleanups, reports, imports) goes in a job:

Parse.Cloud.job('cleanupOldSessions', async (request) => {
  const { message } = request;
  message('Starting');
  // ... work in batches
  return 'Done';
});

Schedule it in Core › Jobs (once, or repeating), or run it from the dashboard. Each run's status and message are kept, and through MCP your assistant can run a job and wait for its result.

Your own routes and static files

cloud/app.js exports an Express app, mounted at the root of your app's public URL (https://pg-app-<id>.scalabl.cloud/):

// cloud/app.js
const express = require('express');
const app = express();

app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), async (req, res) => {
  // verify the signature, then handle the event
  res.sendStatus(200);
});

module.exports = app;

cloud/main.js keeps the line module.exports.app = require('./app');. Files in public/ are served as they are, e.g. public/index.html at the public URL. With a custom domain (App Settings › Emails & Hosting › Host Name, with a free SSL certificate) both answer on your domain.

Webhooks

Functions and triggers can also run on your own server: Core › Webhooks points a function name or a class trigger at a URL. Parse calls it with the request and checks the answer; your server verifies the X-Parse-Webhook-Key header (the Webhook Key in App Settings › Security & Keys).

Secrets and configuration

Set API keys and settings as environment variables (dashboard Runtime › Environment Variables) and read them with process.env.STRIPE_KEY. Never commit them to the repository.

Logs

console.log and console.error in cloud code go to Core › Logs, next to Parse's own errors (e.g. a function that threw). Your assistant can read them with get_logs and get_error_logs.

Run it locally

Run your cloud code on your machine with a local Parse Server, and test functions and triggers automatically before you push: see Local development and testing.

Write code for your version

The Parse Server version is in Runtime › Parse Server Version. Since Parse Server 3, functions and triggers are async and return or throw; response.success() and response.error() are gone. plan_parse_server_upgrade through MCP lists, file by file, what your code needs before a version upgrade.

Reading this with an AI assistant? This page as Markdown.