Script do lado do servidor

Scripts do lado do servidor são executados em JavaScript como um script do Google Apps Script. Eles têm acesso às APIs Apps Script, além dos objetos e APIs do lado do servidor do App Maker. Observe que os serviços avançados do Google precisam estar ativados para que possam ser usados.

Noções básicas de script do lado do servidor

Você deve usar scripts do lado do servidor quando precisar executar alguns cálculos demorados (para evitar o bloqueio da IU) ou quando precisar acessar informações que preferiria não enviar ao cliente devido a problemas de tamanho ou segurança.

Chamar um script de servidor

Para chamar um script de servidor, use google.script.run. Consulte a documentação de script do lado do cliente para mais informações.

Parâmetros e valores de retorno

Os valores são retornados no método withSuccessHandler(function) em google.script.run. Parâmetros legais e valores de retorno são primitivos do JavaScript como Number, Boolean e String, além de objetos e matrizes de JavaScript que são compostos de primitivos, objetos e matrizes.

Uma solicitação falharia se você tentasse passar um objeto de Date, uma Function, um Record ou um widget do App Maker, por exemplo. Uma estratégia comum para passar objetos mais complexos é usar JSON.stringify e JSON.parse.

Ocultar scripts de servidor

É importante observar que qualquer função definida em um script de servidor está aberta a todos os usuários do aplicativo, mesmo que você não o exponha na IU. Se quiser escrever uma função de utilidade que pode ser chamada de outros scripts de servidor, é preciso acrescentar um sublinhado ao nome (por exemplo, o seguinte método seria público) e permitir que qualquer cliente receba o salário do usuário passado.

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

Em vez disso, deve ficar assim:

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

Segurança

Embora ocultar scripts de servidor seja útil, às vezes os scripts do seu servidor podem precisar expor dados confidenciais ao cliente. Nesse caso, é importante proteger seus scripts. Enquanto modelos e visualizações têm permissões, para scripts de servidor você precisa implementar as suas próprias. Usando o exemplo acima, vamos supor que você queira que seus usuários possam chamá-lo, mas queira apenas retornar o salário de um usuário se o próprio usuário ou um gerente o estiver solicitando.

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;
}

Como trabalhar com dados

Os scripts de servidor permitem que você interaja com qualquer um dos modelos do App Maker de maneira genérica. Eles permitem criar novos registros, consultar ou editar relações.

Como criar registros

// 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.

Como consultar registros

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);
}

Como trabalhar com relacionamentos

O exemplo a seguir mostra como criar e consultar registros relacionados. Suponha que tenhamos um modelo de "Endereço", com um relacionamento de muitos para um com um modelo de "País".

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.push(address1, address2);
app.saveRecords([country]); // Save updated relation.

Também é possível filtrar por campos relacionados, como no snippet de código abaixo:

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

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

Mais informações podem ser encontradas na seção Filtragem de relação.

Como controlar transações do CloudSQL

O exemplo a seguir mostra como usar um script de servidor para controlar transações do Cloud SQL. Use esta API para:

  • iniciar uma transação e bloquear registros relacionados;
  • confirmar novas alterações no banco de dados;
  • reverter uma transação.
function submitOrder(orderKey) {

  // Sets a rollback point and starts a new transaction.
  app.transaction.cloudSql.start();

   // Locks all records that are read in the transaction until the end of the transaction.
  app.transaction.cloudSql.setLockOnRead(app.transaction.cloudSql.lockOnRead.UPDATE);

  var orderQuery = app.models.Order.newQuery();
  orderQuery.filters._key._equals = orderKey;
  var order = orderQuery.run()[0];

  // Read related order items
  var orderItems = order.OrderItems;

  var products = [];
  for (var i = 0; i < orderItems.length; i++) {
    // Read related product
    var product  = orderItem.Product;

    if (product.InStockQuantity < orderItem.Quantity) {
      // Insufficient stock to complete an order; transaction is rolled back.
      app.transaction.cloudSql.rollback();
      throw new app.ManagedError("Not enough " + product.Name + " in stock. " +
                                 product.InStockQuantity + " Order: " +
                                 orderItem.Quantity + " can't be completed.");
    }

    // Reduce inStock quantity
    product.InStockQuantity = product.InStockQuantity - orderItem.Quantity;
    products.push(product);
  }

  order.Status = "Submitted";
  app.saveRecords(products);
  app.saveRecords([order]);

  // Order is successfully processed; database changes committed.
  app.transaction.cloudSql.commit();

  return "Order submitted: " + orderKey;
}

Solução de problemas

O App Maker expõe erros de sintaxe enquanto você digita e os destaca em vermelho. Ele também detecta problemas comuns (como variáveis não usadas) e os relata como avisos.

Às vezes, os scripts não estão funcionando como esperado. Nesse caso, o App Maker dispõe de um objeto de console que pode ser usado para registrar qualquer informação relevante. Por exemplo:

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;
};

Os registros podem ser visualizados separadamente para cada implantação de aplicativo.