G Suite Business customers can preview App Maker. Ask your domain admin to apply for early access.

Server-side scripting

Server-side scripts run in JavaScript as an Apps Script script. They have access to Apps Script APIs as well as App Maker's server-side objects and APIs. Note that Google Advanced Services must be enabled before they can be used.

Server-side scripting basics

You should use server-side scripts when you need to perform some time-consuming calculations (to avoid blocking the UI), or when you need to access information which you would rather not send to the client due to large size or security concerns.

Calling a server script

To call a server script, use google.script.run. See the client-side scripting documentation for more information.

Parameters and return values

Values are returned in the withSuccessHandler(function) method on google.script.run. Legal parameters and return values are JavaScript primitives like Number, Boolean, and String, as well as JavaScript objects and arrays that are composed of primitives, objects, and arrays.

A request would fail if you attempted to pass a Date object, a Function, a Record, or an App Maker widget, for example. One common strategy to pass more complex objects is to use JSON.stringify and JSON.parse.

Hiding server scripts

It is important to note any function you define in a server script is open to all users of your application, even if you do not expose it in the UI. If you want to write a utility function that can only be called from other server scripts, you must append an underscore to the name, for example the following method would be public, and allow any client to get the salary of the passed in user!

function calculateUserSalary(user) {
  // Gets the salary of the user...
  return salary;
}

Instead, it should look like this:

function calculateUserSalary_(user) {
  // Gets the salary of the user...
  return salary;
}

Security

While hiding server scripts is useful, sometimes your server scripts may need to expose sensitive data to the client. In this case, it's important to secure your scripts. While models and views have permissions, for server scripts you must implement your own. Using the example above, say you wanted your users to be able to call it, but only want to return a user's salary if the user herself is requesting it, or if a manager is requesting it.

function calculateUserSalary(user) {
  var currentUser = Session.getActiveUser().getEmail();
  if (currentUser !== user && !isManager(currentUser, user) {
    throw new Error(currentUser +
        " does not have access to salary for " + user);
  }

  // Gets the salary of the user...
  return salary;
}

Working with data

Server scripts allow you to interact with any of the App Maker models in a generic way, regardless of whether their underlying persistence store is Drive Tables or Google Cloud SQL. It lets you create new records, query or edit relations.

Creating records

// Assume a model called "Fruits" with a string field called "Name".
var newRecord = app.models.Fruits.newRecord();
newRecord.Name = "Kiwi";  // properties/fields can be read and written.
app.saveRecords([newRecord]);  // The changes won't be committed to the
                               // database unless you remember to save.

Querying records

var query = app.models.Person.newQuery();
query.filters.Name._equals = "John";

var records = query.run();
console.log("Found " + records.length + " Johns.");

for (var i in records) {
    var person = records[i];
    console.log("Found person named John " + person.FamilyName);
}

Working with relationships

The following example shows how to create and query related records. Suppose we have an "Address" model, with a many-to-one relationship with a "Country" model.

var address1 = app.models.Address.newRecord();
address1.zip = 94040;
var address2 = app.models.Address.newRecord();
address2.zip = 94041;
app.saveRecords([address1, address2]); // Save created records.

var query = app.models.Country.newQuery();
query.filters.Name._equals = countryName;
var country = query.run()[0];

country.Address = [address1, address2];
app.saveRecords([country]); // Save updated relation.

You can also filter by related fields like in the code snippet below:

function addressesForCountry(countryName) {
  var query = app.models.Address.newQuery();
  query.filters.Country.Name._equals = countryName;

  var records = query.run();
  return records;
};

More information can be found in the Relation filtering section.

Troubleshooting

App Maker exposes syntax errors as you type, and highlights them in red. It also detects common problems (such as unused variables) and reports them as warnings.

Sometimes your scripts aren't working as expected, in this case, App Maker provides a console object which can be used to log any relevant information. For example:

function getRecordsForCurrentUser() {
  var currentUser = Session.getActiveUser().getEmail();
  var query = app.models.Person.newQuery();
  query.filters.Email._equals = currentUser;

  var records = query.run();
  console.log("Found " + records.length + " records for " + currentUser);
  return records;
};

Logs can be viewed separately for each application deployment.