NAV Navbar
cURL javascript Response
  • Documentation Overview
  • Backand Features
  • Backand Dashboard
  • Vanilla SDK
  • Platform-specific SDKs
  • Common Use cases
  • Integrations
  • The Backand Lambda Launcher
  • Documentation Overview

    What is Backand?

    Backand's goal is to free up the front end development of web applications by providing a rich, robust, and scalable back end with minimal impact on the development process. The key feature offered by Backand is the ORM, but most application back ends require more than just object management. Backand provides you with most of what your application needs automatically, offering features like tracking data changes, logging, role-based security, back-office connectivity, and much more. You can even create your own server side actions with JavaScript, running custom server side queries and easily integrating with third party services.

    Backand ORM

    Backand ORM automatically provides you with a REST API to perform CRUD operations against your database. You can connect an existing database you already have, or create a new database with the Backand dashboard. When you create a database at Backand it is automatically populated in Amazon's AWS Relational Database Service (AWS RDS), providing an isolated database server that you can scale automatically, or even use in other applications entirely independent of Backand. Even though Backand focuses on software services as opposed to platform services, when you register a database with Backand it is truly your database.

    SQL and NoSQL - The Best of Both Worlds

    Through the flexibility of Backand's API, you have the ability to work with your data at whatever level you desire. You can perform basic CRUD operations in a couple ways. In one way you can mimic a SQL database by simply returning a shallow representation of the object, with foreign key references remaining as simple IDs in the response data. However, you can also perform deep queries that resolve all of the underlying data objects into a single set of response data, giving you the level of object detail that you often see with NoSQL databases. With a simple parameter change, you can switch between the two patterns at will!

    Using cURL with Backand

    # Retrieve a list of items from your app
    # This call stores the MASTER_KEY and USER_KEY into environment variables
    # Following this pattern will enhance the security and reliability of any console
    # calls made to the API
    curl https://api.backand.com/1/objects/items -u $MASTER_KEY:$USER_KEY
    
    # You can perform the same task using URL parameters:
    curl https://api.backand.com/1/objects/items?authorization=basic+$MASTER_KEY:$USER_KEY
    

    All calls made by our API can also be made on the command line using cURL. You simply need to either obtain a token to authenticate as a user with your application, provide a token allowing anonymous access to your app, or use your app's master key to override the authentication mechanism. Review our information on authentication for more info on the specific endpoints to use for each approach.

    Using our SDK with Backand

    // Initialize the SDK
    backand.init({
      appName: 'APP_NAME',
      anonymousToken: 'ANONYMOUS_TOKEN'
    });
    
    // Retrieve a list of records from the server
    backand.object.getList('users')
      .then((response) => {
          console.log(response);
      })
      .catch(function(error){
          console.log(error);
      });
    

    We also offer a full-featured SDK that you can use to communicate with your Backand application. Getting started with the SDK is as simple as configuring your application access details, initializing the SDK, and calling a getList() function for one of the objects in your system. You configure the SDK with your application's APP_NAME and ANONYMOUS_TOKEN. Once you've called init() with these values, the SDK will use this data to automaticaly manage authentication headers for API requests to your app's REST API. See our Vanilla SDK documentation for more details.

    Response format

    // Sample response
    {
      "totalRows": 2,
      "data": [
        {
          "__metadata": {
            "id": "1",
            "fields": {
              "id": {
                "type": "int",
                "unique": true
              },
              "items": {
                "collection": "items",
                "via": "user"
              },
              "email": {
                "type": "string"
              },
              "firstName": {
                "type": "string"
              },
              "lastName": {
                "type": "string"
              }
            },
            "descriptives": {
    
            },
            "dates": {
    
            }
          },
          "id": 1,
          "items": null,
          "email": "matt@backand.com",
          "firstName": "Matt",
          "lastName": "Billock"
        },
        {
          "__metadata": {
            "id": "2",
            "fields": {
              "id": {
                "type": "int",
                "unique": true
              },
              "items": {
                "collection": "items",
                "via": "user"
              },
              "email": {
                "type": "string"
              },
              "firstName": {
                "type": "string"
              },
              "lastName": {
                "type": "string"
              }
            },
            "descriptives": {
    
            },
            "dates": {
    
            }
          },
          "id": 2,
          "items": null,
          "email": "start@backand.io",
          "firstName": "Start",
          "lastName": "Backand"
        }
      ]
    }
    

    Our SDK will always respond to your requests with well-formed JSON representing the results of an action taken. We include metadata that can be used to parse the response where applicable, and this metadata is provided with each object in your system. Responses from the SDK wrap the HTTP response in a promise, allowing you to handle the results in an asynchronous manner.

    Backand Features

    This section contains documentation on the features offered by Backand. We will cover the following functional areas:

    The User Object and Security

    This section describes how to manage your app's users within Backand's user security paradigm. An important element to note up front is that, by default, Backand provides two independent user objects. One user object is handled entirely by Backand, and is responsible for authentication and role-based security. The data for this user object is stored in Backand's database, and as such cannot partake of your app's custom logic. The second user object is offered in the default data model for a Backand application, and is titled 'users'. This object represents a user of your application, as opposed to a generic Backand user, and allows you to associate the user with various other objects in your application. Backand provides sync actions that allow you to keep these two user object lists up-to-date (see Link your app's users with Backand's registered users for more info). We highly recommend running the todos-with-users app in addition to reading this documentation. This simple app covers most of the user management use cases for a Backand application, such as allowing users to read all of your app's data but only allowing them to create and update their own objects, or restricting anonymous users to read-only access, or creating an Admin role that has full read-write-update-delete access to your application's objects.

    Authentication with OAuth 2.0

    # To obtain an access token using a username and password, use the following
    # command. This uses environment variables to ease presentation of the
    # information, and supplies the fields as data arguments to the cURL command.
    # $USERNAME - user name (email address) to authenticate
    # $PASSWORD - password for the user
    # $APP_NAME - the name of the backand application you are connecting to
    curl https://api.backand.com/token -d username=$USERNAME -d password=$PASSWORD -d grant_type=password -d appName=$APP_NAME
    
    # To obtain an access token using a Social Media master key (for connecting via
    # social media providers, like Facebook in the example below), use the following
    # command with parameter values as follows:
    # $SOCIAL_MEDIA_KEY - your app's social media access token
    # $APP_NAME - your Backand app's name
    curl -X GET https://api.backand.com/1/user/facebook/token?accessToken=$SOCIAL_MEDIA_KEY&appName=$APP_NAME&signupIfNotSignedIn=true
    
    # You can then use the access token returned by this call to call any Backand API
    # for your application:
    # $ACCESS_TOKEN - the token obtained via a call to the token endpoint
    curl https://api.backand.com/1/objects/items -H "Authorization: Bearer $ACCESS_TOKEN"
    

    The default authentication setup for Backand applications relies on OAuth2 to provide tokenized authentication. By logging in with your username (your email address), your password, and your app name, you receive an authentication token that is valid for 24 hours. This token is required for all communication with Backand, and as such we highly recommend that you use Backand's SDK to help you manage the access token. You can change the default expiration of 24 hours by using a refresh token, which allows you to reuse the authentication token indefinitely. The refresh token is an encrypted hash of the master and user keys. You can revoke one (or all) of your user's refresh tokens by changing the refresh token and requiring users to re-authenticate. For more information, see the API Description.

    Parameters: --signupIfNotSignedIn - (Optional, default false) - If the user tries to sign in without first registering for the application, the user will receive an error message ("The user is not signed up to {appName}"). If this value is set to true, then the user will be automatically registered with the app if they have not yet been signed up

    Sample response

    // Sample response
    {
      "access_token": "ThuuBiuTS9grkzbPW-yL5z3dd_Q48-Ml4oHCffgbWRUDr1rFIY_nYIqaL-he09sCicEVNE_wJCxZ4QS0E3SlG-fZOSOOHDlzORrVagcGvBtZoqTByvhiXgcwXPOkmeD8U1bZaAi8vLEr_wUY6f_rse9o8GKs5cjRpBZENurSytsXhXsv6XpSFcZUr5n7Za_nu5HDth2bOuM_2e-Kn3yOc2GDz9qXjZm_UQ9oMfvJnzjY16Qsw7_ynZAbRa4m6lRtXwsHunqv_R_8uhMGNwTxyg",
      "token_type": "bearer",
      "expires_in": 86399,
      "appName": "bkndkickstart",
      "username": "start@backand.io",
      "role": "User",
      "firstName": "Backand",
      "lastName": "Start",
      "fullName": "Backand Start",
      "regId": 950007,
      "userId": "2"
    }
    

    The call to the token endpoint returns all of the information you need to use a token to connect to your backand application. The access_token provided is authenticated with a signle user in your app, and is provided an expiration time in seconds. You are also given details of the authenticated user, including their username, first and last name, user ID, and their security role.

    Basic authentication

    # Perform basic authentication via header
    curl https://api.backand.com/1/objects/items -u <master key>:<user key>
    # Perform basic authentication using URL parameters
    curl https://api.backand.com/1/objects/items?authorization=basic+<master key>:<user key>
    

    You can use basic auth to ease working with other servers - simply enter the master key as the username, and the user key as the password. You can use this approach to obtain a list of Items by using the following API call:

    You can also send the basic authorization token through as a query string.

    Anonymous authentication

    # Perform anonymous authentication through headers
    curl https://api.backand.com/1/objects/items -H "AnonymousToken: <anonymous token>"
    # You can also send the anonymous token through in a query string:
    curl https://api.backand.com/1/objects/items?AnonymousToken=<anonymous token>
    

    Backand also offers Anonymous Access, which allows you to access your application without the need to authenticate via username and password. By passing this value in a request header (e.g. AnonymousToken=) you can perform api actions for your application

    User Registration

    Registering with Backand, and creating an application, automatically sets you as a user with an 'Admin' role in your new project (see roles for more info). By default your application is marked public which mean any user can register to your application.

    These users are assigned a default role 'User', which has full CRUD access to your app. Your roles will need to be configured when you enable public usage of your app (see roles for more details).

      //Create new Security Action in Before Create trigger with the following
      //code (this will update the role to 'Public'):
      userInput.Role = 'Public';
    

    Saving Additional Parameters During Sign-up

    In many cases, we would like to collect additional information from the user during sign up. We can automatically populate the related fields on the Users object as a part of the sign-up request by using the parameters parameter for the sign-up call. The server, during the 'Create My App User' action, will translate these key-value pairs into the appropriate fields on the 'Users' object - as such, it is important that all fields provided already exist on the Users object. The following example demonstrates specifying a user's "company" name as a part of the sign-up:

        Backand.signup(firstName, lastName, username, password, password, {"company": self.company}).then(...);
    
    1. Update the Model and add the field company to the users object:
      1. Go to Objects --> Model
      2. Add this line as a data field in the users object model: "company": {"type": "string"}
      3. Click on Validate & Update
    2. When calling Backand.signup(), send the parameters object through as the last input parameter for the request. The code will resemble the following:
    3. There's no need for server-side modifications - values for "parameters" are handled automatically by the action 'Create My App User' (found in the Security Actions section).
    4. Modify the UI to collect the company name for the user.

    Now, when sign-up is completed, you can see the company name in the users object's Data tab.

    Private app

    You can change your app, which is public by default, to be private. This can be changed in the dashboard by setting the Public flag for your application to 'false' in the Security & Auth --> Configuration menu. For a private app, the registration steps are as follow:

    Email verification process

    The user enters his/her email, name and password on your registration page:

    For more information, see our Vanilla SDK documentation

    SSO (Single Sign On)

    Many organizations make use of tools like Active Directory in order to provide a central source of user-based authentication. This system is often used to drive a Single Sign On (SSO) feature in the organization, allowing users to simply use one set of credentials for all of the apps that they need to work with. Backand provides a method to incorporate SSO functionality using an override server-side action. This action allows you to perform your own authentication (via web-service calls to the domain controller, for example), and lets you return one of three actions.

    You can configure this action in the Backand dashboard, under Security & Auth => Security Actions.

    Remove user from the app

    There are two ways to remove a user from the application. You can permanently remove a user from the application by deleting a user from the Registered Users grid. This requires the user to register again if they wish to continue using your app. Alternatively, you can un-check the 'approved' checkbox in the user's row on the Security & Auth --> Users page. This allows you to reinstate the user simply by re-checking the 'approved' column.

    Anonymous Access

    By default the anonymous access is turned on with 'User' role access, which mean any one can register to your app and make CRUD actions on any object. If you wish to disable anonymous access to your application, go to Security & Auth --> Configuration and set 'Anonymous Access' to off.

    // Validate Backand Registered User Action
    function backandCallback(userInput, dbRow, params, userProfile) {
      var validEmail = function(email)
        {
            var re = /\\S+@\\S+\\.\\S+/;
            return re.test(email);
        }
    
        // write your code here
      if (!userInput.email){
            throw new Error("Backand user must have an email.");
        }
    
        if (!validEmail(userInput.email)){
            throw new Error("The email is not valid.");
        }
        if (!userInput.firstName){
            throw new Error("Backand user must have a first name.");
        }
        if (!userInput.lastName){
            throw new Error("Backand user must have a last name.");
        }
    }
    
    // Create Backand Registered User Action
    function backandCallback(userInput, dbRow, params, userProfile) {
    
      var randomPassword = function(length){
          if (!length) length = 10;
          return Math.random().toString(36).slice(-length);
      }
        if (!parameters.password){
            params.password = randomPassword();
        }
    
        var backandUser = {
            password: params.password,
            confirmPassword: params.password,
            email: userInput.email,
            firstName: userInput.firstName,
            lastName: userInput.lastName
        };
    
        // uncomment if you want to debug
        //console.log(params);
        var x = $http({method:"POST",url:CONSTS.apiUrl + "1/user" ,data:backandUser, headers: {"Authorization":userProfile.token, "AppName":userProfile.app}});
    
        // uncomment if you want to return the password and sign in as this user
        //return { password: params.password };
        return { };
    }
    

    Backand maintains an internal registered users object which is used to manage your app's security. However, most apps will have their own 'users' object, which is used when implementing the app's business logic. Recognizing this, we have created automatic and custom trigger actions that can be used to synchronize the two objects. If you have an object in your system named 'users', and if that object has the fields 'email', 'firstName', and 'lastName', then every user that is registered with Backand for your app will automatically have an entry created in your custom 'users' object. This takes place no matter how the user is added - both the sign-up API and the Backand dashboard will create an automated user record! Additionally, every time you add a user instance to your users object, a new user is created in Backand's internal registered users object. This new user will be given a randomized password, which can then be provided to the user for access to your application.

    Below we'll look more in-depth at how this process is managed. Additionally, we'll explore what happens when the users object has an unexpected name (i.e. something other than 'users'), or if the fields of the users object are named differently.

    There are 3 sync actions located in Configuration -> Security & Auth that are triggered by Backand user registration:

    1. Create My App User
    2. Update My App User
    3. Delete My App User

    You can directly modify those JavaScript actions if needed.

    If you have a users object in your model, Backand adds the following actions, which run before and during user creation

    This action implements the other side of the relationship - after creating an instance in your custom 'users' object, this code creates the corresponding entry in Backand's internal users object. If have named your custom user object anything other than 'users', you can add the above action into that object manually to achieve the same functionality. You will need to adjust the backandUser object creation to use the columns in your specific object, as the userInput object may have a different structure than that assumed above.

    Roles & Security Templates

    Each user has a role. When you created your app, you were automatically assigned with an 'Admin' role. The 'Admin' role is a special role that allows you to make configuration changes in your app with Backand's administration tools. Non-admin roles, which should be used to secure your application, are used to define the permissions for each of the CRUD actions for your objects and queries. Each Object and Query in your application is associated with a Security Template. In the security template, you assign different permissions for the possible CRUD actions to each user role, allowing you to control your user's access to the system's create, read, update and delete actions for your objects. Template configuration is found on the Security & Auth --> Security Template page.

    While Security Templates provide reusable permissions platforms that can be spread across a number of roles, you can also override security template settings and provide specific permissions for each individual role. This allows you to have more granular control over the CRUD actions that can be performed by the users in your system. When a user with insufficient security access tries to perform an action for which they do not have permission, a 403 (Forbidden) error response is returned.

    Backand Storage

    Backand provides you with the ability to upload and delete files to and from Backand's robust storage. This is done on the server-side through Backand's Actions. It doesn't require any additional authentication and it is up to you to decide if and under what restrictions to expose this functionality to the client side. For example, you can restrict certain roles, handle the name of the files, associate the files with objects and manage counts of the amount of files per user.

    The files.upload command returns a url that links to the file you uploaded. This is a public url. The storage is managed per Backand app.

    Custom Server-Side Action Code

    //Use the following JavaScript as the basis for your file upload action.
    //Refer to the template function for information on global variables offered.
    'use strict';
    function backandCallback(userInput, dbRow, parameters, userProfile) {
      console.log(userProfile); // gets the current user role and id that enables you to perform security restrictions
        // upload file
        if (request.method == "POST"){
            var url = files.upload(parameters.filename, parameters.filedata);
            return {"url": url};
        }
        // delete file
        else if (request.method == "DELETE"){
            files.delete(parameters.filename);
            return {};    
        }
    
    }
    

    Both upload and delete are written in the same action and the method you use to call it determines the functionality. When the method is POST then the action performs upload and when it is DELETE the action performs delete. You can use the userProfile for restrictions or file name manipulations. You do not need to copy this code. It is ready for you when you click on the Backand File Storage action template.

    Angular Client-Side Code

    <!-- Angular HTML -->
    <body class="container" ng-app="app" ng-controller="DemoCtrl" ng-init="initCtrl()">
      <h2>Backand Simple Upload File</h2>
      <br/>
      <form role="form" name="uploadForm">
        <div class="row">
            <img ng-src="{{imageUrl}}" ng-show="imageUrl" />
            <input id="fileInput" type="file" accept="*/*" ng-model="filename" />
            <input type="button" value="x" class="delete-file" title="Delete file" ng-disabled="!imageUrl" ng-click="deleteFile()" />
    
        </div>
      </form>
    </body>
    
    // Client-side JavaScript
    var myApp = angular.module('app', ['backand']);
    
    // Backand security configuration for your app
    myApp.config(function(BackandProvider) {
      // enter your app name here
      BackandProvider.setAppName('YourAppName');
      // enter your app anonymous token here
      BackandProvider.setAnonymousToken('YourAnonymousToken');
    })
    
    myApp.controller('DemoCtrl', ['$scope', '$http', 'Backand', DemoCtrl]);
    
    function DemoCtrl($scope, $http, Backand) {
    
      // Create a server side action in backand
      // Go to any object's actions tab
      // and click on the Backand Storage icon.
      // Backand consts:
      var baseUrl = '/1/objects/';
      var baseActionUrl = baseUrl + 'action/'
      var objectName = 'YourObjectName';
      var filesActionName = 'YourServerSideActionName';
    
      // Display the image after upload
      $scope.imageUrl = null;
    
      // Store the file name after upload to be used for delete
      $scope.filename = null;
    
      // input file onchange callback
      function imageChanged(fileInput) {
    
        //read file content
        var file = fileInput.files[0];
        var reader = new FileReader();
    
        reader.onload = function(e) {
          upload(file.name, e.currentTarget.result).then(function(res) {
            $scope.imageUrl = res.data.url;
            $scope.filename = file.name;
          }, function(err){
            alert(err.data);
          });
        };
    
        reader.readAsDataURL(file);
      };
    
      // register to change event on input file
      function initUpload() {
        var fileInput = document.getElementById('fileInput');
    
        fileInput.addEventListener('change', function(e) {
          imageChanged(fileInput);
        });
      }
    
       // call to Backand action with the file name and file data  
      function upload(filename, filedata) {
        // By calling the files action with POST method in will perform
        // an upload of the file into Backand Storage
        return $http({
          method: 'POST',
          url : Backand.getApiUrl() + baseActionUrl +  objectName,
          params:{
            "name": filesActionName
          },
          headers: {
            'Content-Type': 'application/json'
          },
          // you need to provide the file name and the file data
          data: {
            "filename": filename,
            "filedata": filedata.substr(filedata.indexOf(',') + 1, filedata.length) //need to remove the file prefix type
          }
        });
      };
    
      $scope.deleteFile = function(){
        if (!$scope.filename){
          alert('Please choose a file');
          return;
        }
        // By calling the files action with DELETE method in will perform
        // a deletion of the file from Backand Storage
        $http({
          method: 'DELETE',
          url : Backand.getApiUrl() + baseActionUrl +  objectName,
          params:{
            "name": filesActionName
          },
          headers: {
            'Content-Type': 'application/json'
          },
          // you need to provide the file name
          data: {
            "filename": $scope.filename
          }
        }).then(function(){
          // Reset the form
          $scope.imageUrl = null;
          document.getElementById('fileInput').value = "";
        });
      }
    
      $scope.initCtrl = function() {
        initUpload();
      }
    }
    

    We created a simple example in Angular to experience the upload functionality. You can see the code in action at codepen. The relevant parts of the code are available in the JavaScript pane to the right.

    Backand Hosting

    Backand offers high-performance, reliable, and secure hosting for AngularJS applications through the hosting and deployment tool. Built off of AWS, Backand Hosting gives you an effortless way to deploy your Angular project to a hosted server.

    Your project files will be available on https://hosting.backand.io/Your-App-Name, providing you an easy way to see what gets deployed for your project.

    First Time Installation

      $ npm install -g backand
      # or use sudo (with caution)
    

    The hosting and deployment functionality is provided with the Backand node package. Simply install the package from the command line as follows:

    Updating a Prior Version

      $ npm update -g backand
      # or use sudo (with caution)
    

    If you've installed the Backand node package before, you will need to perform an update to get the new hosting and deployment functionality. Follow these steps to update your locally-installed version of Backand

    Deploying the Angular Project

      backand sync --app {{appName}} --master {{master-token}} --user {{user-token}} --folder /path/to/project/folder
    

    The Backand CLI, which we installed using NPM, provides the capability to deploy your project, as well as sync your local project folder. To deploy and sync, use the following command from the command line:

    The parameters for this call are:

    --app: The current app name

    --master: The master token of the app (get it from Social & Keys)

    --user: The token of the current user (get it from Team and click on key icon)

    --folder: The path of the local Angular folder to sync and deploy

    Browsing to your app

    Your app is now on air, just browse to https://hosting.backand.com/YourAppName and see it live.

    Configuring Sync in Gulp

      # Install the backand hosting gulp plugin with NPM
      npm install backand-hosting-s3
    
      // Include the sync module in your project
      var backandSync = require('../sync-module');
    
      // add your app's credentials to the sts task
      gulp.task('sts', function(){
          var masterToken = "your master backand token";
          var userToken = "your user backand token";
          return backandSync.sts(masterToken, userToken);
      });
    
      //Configure the task to sync to the 'src' folder
      gulp.task('dist',['sts'], function() {   
          var folder = "./src";
          return backandSync.dist(folder, appName); //appName - if you have only one app you don't need this parameter
      });
    
      // Add a task to clean the cache
      gulp.task('clean', function() {
          return backandSync.clean();
      });
    

    Backand can integrate with your existing gulpjs configuration, allowing you to easily control deployment as you would the rest of your project. Below, we'll create a Gulp task to perform the deployment. This can then be used to deploy your application as a part of your standard build process.

    To create the new Gulp deployment task:

    1. Install the Backand hosting gulp plugin using NPM

    2. At the top of gulpfile.js add the require call

    3. Set your Backand credentials for the task. Credentials will be stored in file .backand-credentials.json:

    4. Configure the task to Sync folder './src':

    5. Syncing is performed via a local cache file named '.awspublish-'. This file cache can become corrupted after multiple uses, so we need to create one more task to perform cleanup after the deployment has completed:

    Realtime Database Communications

    Backand's real-time communication functionality is based on the popular open-source Socket.io framework, which lets you add real-time functionality to your application. Backand’s Real-Time Database Communication sends events and JSON-formatted data to any authorized connected client. With Real-Time Communication from Backand, you can send real-time information to your application based on server-side logic in your application's custom actions. With this new feature events are picked up as they happen, rather than having to wait for a user-driven event to trigger a data reload.

    Backand’s real-time database communications are completely secure. They provide you with total control over data access, allowing you to restrict transmission of sensitive data to only authorized roles. And since all communication is SSL-encrypted, you don’t have to worry about the security of your data as it is transmitted across the web.

    Using the real-time capability can enhance your app with instant updates to any Angular page, including updating charts, counters, logs, and other data-driven elements.

    Setup

    <!-- Backand Socket Client -->
    <script src="lib/socket.io-client/dist/socket.io.js"></script>
    <!-- Backand SDK -->
    <script src="//cdn.backand.net/vanilla-sdk/1.0.9/backand.js"></script>
    <script src="//cdn.backand.net/angular1-sdk/1.9.5/backand.provider.js"></script>   
    
      // Configure the SDK to run the socket
      BackandProvider.runSocket(true);
    
    1. Upgrade to Backand SDK 1.9.5 or above.
    2. Include the Backand SDK and Socket.io in your index.html file
    3. Update Angular configuration section

    Angular client code - Sockets

    Backand.on('items_updated', function (data) {
      //Get the 'items' object that have changed
      console.log(data);
    });
    

    Backand's SDK already includes all the code needed for the client-side Socket.IO JavaScript integration. All you need to do is add a listener in your Angular controller or service. In the event that you need to implement your client on a platform other than JavaScript, review the relevant iOS or Android documentation.

    Using Backand's SDK, you can add event listening to your application with a simple function. You don't even need to provide an emit event to track changes - Backand will automatically update you whenever you change data using Backand's REST API out of the box.

    Server side code - Sockets

    // Emit to users
    function backandCallback(userInput, dbRow, parameters, userProfile) {
      socket.emitUsers("items_updated",userInput, ["user2@gmail.com","user1@gmail.com"]);
    }
    
    // Emit to a role
    function backandCallback(userInput, dbRow, parameters, userProfile) {
      socket.emitRole("items_updated",userInput, "Role");
    }
    
    // Emit to all
    function backandCallback(userInput, dbRow, parameters, userProfile) {
      socket.emitAll("items_updated", userInput);
    }
    

    When working with a Custom JavaScript Action in the Backand dashboard, you can add the "emit" command to notify the client of updates based upon events and sent data that are important to your use case. The actions can be based on database triggers (Create, Update or Delete), or in an on-demand action called from client-side logic.

    There 3 type of emit commands you can use in order to notify consuming applications of event data:

    This command sends event only to users specified in the second argument, which should be formatted as an array. To make this array dynamic, you'll need to use a Backand Query action. First call the Query to obtain the users, then convert the JSON into an array of user IDs (email addresses).

    This command sends the event to all the users in a specified role. Be aware that this command will override any data security filter you may have configured for your application.

    This command sends event to all connected users, regardless of their role or permission settings. Be aware that this command vertices any data security filters you may have configured for your application. Use this emit type for general event broadcasting.

    Custom Actions

    In Backand's system, you can create server-side activity called Actions. These actions can be used for the purpose of security, integration, performance, notification and data integrity, among others, providing you with more flexibility in your app's design. There are two types of Actions that can be created. The first are initiated via a direct web request. These are known as "On Demand" actions. Additionally, you can create automated actions that take place based upon a data interaction event. These automated actions can occur whenever you create, update, or delete an item in your system. On Demand actions are associated with a specific object, and can be found on the Object --> {name} page in the Actions tab. The automated Create, Update and Delete actions are associated with a specific object that is compatible with a specific row in a table, while On Demand actions make association with a specific role optional.

    There are 4 kinds of actions that can be created:

    All 4 types of actions use the following common parameters:

    Server-side JavaScript Code

    function backandCallback(userInput, dbRow, parameters, userProfile) {
        // write your code here
        return {};
    }
    

    You can run standard JavaScript on the server. It runs on the V8 engine. To execute the JavaScript action, put your code into the following function:

    The function parameters are:

    Making HTTP Requests from a custom action

    // GET example:
    var response = $http({method:"GET",url:CONSTS.apiUrl + "/1/objects/objectexample",
                           params:{filter:[{fieldName:"fieldexample", operator:"contains", value:"somestring"}]},
                          headers: {"Authorization":userProfile.token}});
    
    // POST example:
    var response = $http({method:"POST",url:CONSTS.apiUrl + "/1/objects/objectexample",
                          data:{fieldexample1:"somevalue",fieldexample2:"somevalue"},
                          headers: {"Authorization":userProfile.token}});
    
    // PUT example:
    var response = $http({method:"PUT",url:CONSTS.apiUrl + "/1/objects/objectexample/5",
                          data:{fieldexample1:"somevalue",fieldexample2:"somevalue"},
                          headers: {"Authorization":userProfile.token}});
    
    // DELETE example:
    var response = $http({method:"DELETE",
                          url:CONSTS.apiUrl + "/1/objects/objectexample/5",
                          fieldexample2:"somevalue"},
                          headers: {"Authorization":userProfile.token}});
    

    In addition to the above parameters, you're also given access to $http. $http is a service for HTTP calls, similar to Angular's $http without the promise (since it is a server side function it always runs in sync). See the full API description for more details.

    To make a request, simply feed a parameter hash into the $http object. The available parameters are:

    A Note About The Authorization Header:

    Sending the authorization header to the $http function is optional. When you make a $http request with an authorization header and the value of the userProfile.token (as in the examples above), the request will run in the context of the current user and with his assigned role. Alternatively, if you choose not to send an authorization header, the action will run in the context of an admin role. Send the authorization header with the request if you are going to use information about the current user in the action, otherwise you do not need to do so.

    Debugging

    Debugging should be done using either console.log or console.error. For example, to dump the contents of variable object:

    console.log(object)

    console.error(object)

    These are sent to the Logging section of the Backand dashboard, under Log -> Console.

    Error Handling

    If your code results in an error (for example, if you write the following: throw new Error("An error occurred!")), the request will return HTTP status 417, and the response body will contain the associated error message.

    These are also sent to the Logging section of the Backand dashboard, under Log -> Server Side Exceptions.

    Return values

    Triggered actions will have a response that matches the format expected by the triggering call (such as the return value of a CREATE call).

    On Demand actions, though, will return whatever value is returned by the custom server code, which can be any properly-formatted JSON string.

    Server-Side Node.js Code

    Using Backand, you can develop distributed Node.js actions and host them with your Backand application - no additional servers needed! You can use the Server-Side Node.js action to work with any NPM package, build sophisticated action behaviors, perform complex coding tasks, and more.

    For Server-Side Node.js Code actions, you develop the code on your local machine. The code is then deployed to, and runs on, Backand's server. It functions just like any other Node.js project and can be fully debugged locally and, once you've finished making changes, you can use the "deploy" command to publish the changes to your Backand application.

    Follow these steps to create and run a Server-Side Node.js Code Action:

    You are now ready to develop your code locally, and test the action on the Backand Dashboard for your application!

    Backand CLI

        $ npm install -g backand
        # or use sudo (with caution)
    

    Backand uses the Backand CLI to control deployment and initialization. The CLI requires that Node.js and NPM are both installed. You can install them on your local machine by following the instructions at https://nodejs.org/.

    Once you've set up Node and NPM, use NPM to install the Backand CLI as a global package.

    Initialize action

        $ backand action init --app <app name> --object <object name> --action <action name>  --master <master token> --user <user token>
    

    To initialize the node.js code for the action on your local machine, use the action command on the command line in the folder that will host your action's code

    The parameters for this call are:

    Deploy action

        $ backand action deploy --app <app name> --object <object name> --action <action name>  --master <master token> --user <user token>
    

    To deploy your local Node.js code to Back&, use the deploy command with the Backand CLI

    The parameters for this call are:

    Add Backand SDK to Node.js

        $ npm install backandsdk --save
    

    To work with objects or other actions in Backand, you need to install the Backand SDK for Node.js. The Backand SDK ships with several code samples that demonstrate how to access other Backand functionality.

    Transactional Database Scripts

    Transactional database scripts are SQL scripts that run within the same transaction context as the triggering action, provided that the event occurs during the object event "During the data save before the object is committed". This means that if the Create, Update or Delete request fails then your script will be rolled back like any other transaction.

    Send Emails

    Send Email actions, in addition to common parameters, allow you to also supply the usual email fields: To, Cc, Bcc, From, Subject and Message. You can additionally provide an object ID to obtain a deep object to use in the action.

    External Lambda Functions

    With the release of the Lambda Launcher, Backand also added the capability to connect with arbitrary Amazon Web Services (AWS) accounts. These are managed in the Functions & Integrations -> Functions section of the Backand App dashboard, on the "External Functions" tab. Below is an overview of the UI elements that support this in the Backand app dashboard. If you would like help using the utility itself, navigate to the Backand Lambda Launcher section of this documentation below.

    Connecting your AWS account

    Upon first navigating to this page, you'll be presented with a dialog requesting your AWS account connection details. Provide the API Secret Key ID, the Secret Key, and the AWS Regions you wish to connect to Backand, and we will use these credentials to fetch a list of the AWS Lambda functions located in each connected region.

    Importing Lambda Functions

    Once an accounts AWS credentials have been entered and confirmed, a list of external Lambda functions are imported. These Lambda functions exist exclusively on the connected account, and are not owned or managed by Backand. However, we allow you to easily import these functions into the Backand platform. This allows you to then call these functions using the Backand SDK, easily integrating your application's vital Lambda functions with the rest of your application's back end. These calls are additionally subject to your application's security settings, giving you more tools to restrict access to your vital company infrastructure.

    To import an external AWS Lambda function, first navigate to Functions & Integrations -> Functions -> External Functions. Enter the requested connection details, and press the "Connect with AWS" button. Once this is complete, you are presented with a list of functions that resembles the following:

    image

    All functions not yet imported to your Backand application are located next to an orange "Link" button. Simply press this button, and the external Lambda function is connected to your Backand application. Once this is done, the "Link" button changes into a two button set that allows you to either test the function using our user interface, or unlink the function and prevent it from being called again over our API.

    Accessing the Lambda Launcher

    Once you've imported your desired external functions, you can access the Lambda Launcher from the "Lambda Launcher" tab in the External Functions user interface. This provides instructions on security the application, and a link to the Lambda Launcher application itself.

    Queries

    You can create and call your own custom queries in your application. You can use parameters as tokens that will be replaced with the actual parameter values, similar to how custom actions work. You can create your own filters, sorting, and paging, as well as use aggregation to summarize information.

    Click NOSQL Query Language for instruction on how to build queries with noSQL language or use common MySQL syntax.

    NoSQL Query Language

    This query language is inspired by MongoDB.

    A query consists of these parts:

    1. fields to be extracted
    2. table to extract the records from
    3. expression for filtering the table rows
    4. groupby - fields to group the data under
    5. aggregate functions to be applied to columns in fields
    6. orderby - fields to order the return data by
    7. limit - an integer number of records to return.

    Only the table and expression parameters are mandatory.

    Construction and Translation

      SELECT fields with aggregation
      FROM table
      WHERE expression
      GROUP BY groupby
      ORDER BY orderby
      LIMIT limit
    

    The NoSQL queries are then constructed into a SQL query. Each component of a NoSQL query hash corresponds to a different portion of the SQL query that ends up being run against your database. See the example query to the right to get a feeling of how the query translates into SQL statements.

    Format

    {
      "object": "String",
      "q": "Expression",
      "fields": "Array of String",
      "groupBy": "Array of String",
      "aggregation": "Object mapping fields to aggregate functions"
    }
    

    NoSQL queries are constructed using JSON objects. The keys are mapped into their respective SQL keywords in the back-end before interacting with your database.

    For example, the shortest query you can write would be { "object": "table", "q": "query expression" }

    This NoSQL object is converted into the following SQL

    SELECT * FROM table WHERE query

    Example - String Comparison

    {
        "object": "employees",
        "q": {
            "position" : "Sales Manager"  
        },
        "fields": ["name", "salary"]
    }
    

    A simple query can pluck the name and salary fields from an object named employees. The query sample to the right executes this query for all employees with a position of "Sales Manager"

    Example - Constant Value Comparison

    {
        "object": "employees",
        "q": {
            "age": { "$lt" : 25 }
        }  
    }
    

    Queries can also be used to compare an object's fields to constant values using common comparison operators. For example, to retrieve all fields for all employees under the age of 25, you can use the query to the right.

    Example - Range-based comparison

    {
      "object": "employees",
      "q": {
        "age": {
          "$between": [25, 40]
        }
      }  
    }
    

    You can use the $between operator to retrieve all records with values that lie between two specified endpoints. For example, the query to the right retrieves all employees with an age between 25 and 40.

    Example - Geographic Data Comparison

    {
        "object": "city",
        "q": {
            "location" : { "$within" : [[32.0638130, 34.7745390], 25000]
        }
      }
    }
    

    You can use the $within operator to locate all records within a geographic range. The parameters for this comparison are provided as an array of two elements. The first element is a tuple containing latitude and longitude, e.g. [32.0638130, 34.7745390], while the second is a distance in meters. To retrieve all cities within 25 km (25000m) of a given latitude and longitude, you can use a query like the one to the right.

    Expressions

    An expression can be either an AND expression, an OR expression, or a UNION query.

    AND expressions

    { "position": "Sales Manager", "age" : { "$lt" : 25 }, "city": "Boston" }
    

    An AND expression is a conjunction of conditions on fields. An AND expression is JSON of the form { A: condition, B: condition, ... }

    For example, to retrieve all employees that are 25-years-old, a Sales manager, AND live in Boston, you could use the query on the right.

    OR expressions

    { "$or": [ { "num_employees": { "$gt": 30 } }, { "location": "Palo Alto" }  ]  }
    

    An OR expression is a disjunction of conditions, { $or: [ Expression1, Expression2, ... ] }

    For example, use the query to the right to find all offices that are either larger than 30 employees, or located in Palo Alto.

    UNION queries

    {
        "$union":   [
            {
                "object" : "Employees",
                "q" : {
                    "$or" : [
                        {
                            "Budget" : {
                                "$gt" : 20
                            }
                        },
                        {
                            "Location" : {
                                "$like" :  "Palo Alto"
                            }
                        }
                    ]
                },
                "fields": ["Location", "country"]
            },
            {
                "object" : "Person",
                "q" : {
                    "name": "john"
                },
                "fields": ["City", "country"],
                "limit": 11
            }
        ]
    }
    

    A UNION query is a union of the results of queries, and will have the general format of { $union: [ Query1, Query2, ... ] }. The query to the right, for example, combines a query looking for employees with a budget of 20 OR a location like Palo Alto with a query that retrieves the city and country fields for all entries in the Person table with the name "john", limiting the results to 11 records. The end result will combine both queries into a single response object.

    Conditions on Fields

    Formally, a condition on a field is a key-value expression of the form { Key : ValueExpression }, where the fields are defined as follows:

    You can perform a number of different tests on objects using conditions. Using conditions, you can:

    1. Test equality of field to a constant value, e.g. { A: 6 } => Is A equal to 6?
    2. Compare a field using a comparison operator, e.g. { A: { $gt: 8 }} => Is A greater than 8? The set of comparison operators is quite extensive and includes: $lte, $lt, $gte, $gt, $eq, $neq, $not, $within, $between
    3. Test if the value of the field is IN or NOT IN the result of a sub-query.
    4. Test for the negation of a comparison. For example, to test if the location field is not Boston, we can use{ "location": { "$not" : "Boston" }}
    5. Test for presence of a value. For example, if we want to test if a middle name field exists, we can do use { "middleName": {"$exists": true} }

    Negation may sometimes be swapped for comparison. For example, to test if the location field is not equal to Paris, we can use negation: { "location": { "$not" : {"$eq": "Paris" } } }

    Another option is to use a not-equal operator: { "location": { "$neq": "Paris" } }

    Sub Queries

    This JSON can be used as a sub-query to retrieve the ID of all departments in the city of New York.

    { "object": "department", "q": { "city" : "New York" }, "fields" : ["id"]}
    

    Using the above sub-query, we can now test a new field - dept_id - with respect to the results of the sub-query. We simply use the $in operator, and the query, as seen below.

    {
      "dept_id": {
        "$in": {  
          "object": "department",
          "q": { "city" : "New York" },
          "fields" : ["id"]
        }
      }
    }
    

    In this example, the 'deptId field is a reference field referring the employees table to the department table. We can now use this sub-query as a part of a larger query retrieving all employees employed in departments that are located in New York.

    {
      "object": "employees",
      "q" : {
        "deptId" : {
          "$in": {
            "object": "department",
            "q": {
              "city" : "New York"
            },
            "fields" : ["id"]
          }
        }
      }
    }
    

    If we wanted to look at a more complex query, we could modify this a bit. Let's say we wanted to retrieve all employees whose department is located in New York, but the employee is located in Boston. To accomplish this, we use an AND expression to combine the two conditions:

    {
        "object": "employees",
        "q" : {
            "deptId":
            {
                "$in": {
                    "object": "department",
                    "q": {
                        "city" : "New York"
                    },
                    "fields" : ["id"]
                }
            },
            "location": "Boston"
        }
    }
    

    You can use sub-queries to established a reduced scope of your objects to work with. They can then be composed into larger queries, providing you with extra flexibility in retrieving objects from your app.

    Group By Queries

    To group by 'Country', and then concatenate the 'Location' field, use the following example code:

    {
        "object" : "Employees",
        "q" : {
            "$or" : [
                {
                    "Budget" : {
                        "$gt" : 20
                    }
                },
                {
                    "Location" : {
                        "$like" :  "Palo Alto"
                    }
                }
            ]
        },
        "fields": ["Location", "Country"],
        "order": [["Budget", "desc"]],
        "groupBy": ["Country"],
        "aggregate": {
            "Location": "$concat"
        }
    }
    

    A group by query aggregates on fields, and then applies aggregation operators to the specified fields.

    Algorithm to Generate SQL from JSON Queries

      transformJson(json, sqlSchema, isFilter, callback)
    

    The result is a structure with the following fields:

    {
        "str": "<SQL statement for query>",
        "select": "<select clause>",
        "from": "<from clause>",
        "where": "<where clause>",
        "group": "<group by clause>",
        "order": "<order by clause>",
        "limit": "<limit clause>"
    }
    

    The algorithm transforms from JSON to SQL using a top-down transformation.

    Usage

    You can call the function by using the Javascript call transformJson. The parameters to this are as follows:

    1. json - JSON query or filter
    2. sqlSchema - JSON schema of database
    3. isFilter - boolean - true if 'json' is a filter
    4. callback - 'function(err, result)', called upon completion

    Escaping

    All constants appearing in the JSON query are escaped when transformed into SQL.

    Filters

    Variables take the form of:

      {{<variable name>}}
    

    You also have the ability to mark a particular NoSQL query as a filter. This allows you to use variables in your query, which are populated on the server side from either parameters sent in with the filter, or from database data in your system.

    Variables are not escaped when used as part of a filter or query - only constants can be escaped by Backand. With this in mind, you want to make sure that variables tied directly to user input are properly sanitized before being sent to the back-end. The SQL statement generated for the filter object will include the variables you provide. The variables will be substituted for the equivalent values prior to the execution of the query.

    Backand Dashboard

    Backand's REST API allows you to fully access and manipulate the backend data for your system, giving you full access to the underlying database and related functionality from any program that can send an HTTP request. While we start by wrapping your database in a true RESTful API Interface, we also give you a lot of extras that you can use to replace the server in your app:

    Let's take a quick look at each available action in the Backand dashboard, and get started with focusing on the front-end of your application!

    Below is a list of pages in the Backand dashboard, and links to the specific section of the dashboard documentation that is relevant for each. We recommend using this as your starting point - it is designed to represent the hierarchy of pages as they currently appear in the Backand dashboard

    Functions & Integrations

    The Functions & Integrations section of the Backand dashboard is dedicated to managing serverless functions in your Backand application. You'll find all object-independent functions here, as well as Cron Job management.

    Database

    The Database section of the Backand dashboard is used to manage your application's data store and schema. You can update your application's model, work with your object data, or construct custom queries against your database that can be called on-demand.

    Security

    The Security section of the Backand Dashboard is used to manage user and access restrictions for your application. You also obtain the API keys for your Backand application here.

    Admin

    The Admin section contains all the tools you need to administer your Backand account, and manage your application's hosting and environment variables.

    Docs & API

    The Docs & API tab contains links to kickstart tutorials, tutorials on converting existing applications to use Backand, and other useful documentation. let's take a look at each menu category below.

    Examples

    This links to our examples page, which has useful sample applications for many different platforms. These sample applications work to show how best to integrate Backand with an application for each mentioned platform, and can be a good starting point for integrating Backand with an existing (or brand new) application.

    Kickstart Tutorials

    Our kickstart tutorials provide a list of kickstart apps that you can use to build an app for the platform specified. These kickstart apps ship with Backand already built-in and integrated, and provide you with tools to explore the SDK's functionality. They all work with the default data model, so getting the kickstart app wired up to a new Backand application is a simple matter of changing the appropriate keys in each example.

    Existing App Tutorials

    Our existing app tutorials provide a list of tutorials on connecting Backand into your existing application, with a number of different frameworks supported. These focus on including the Backand SDK, connecting to your app, and working with the data model. If you'd like to see another platform included, please contact us!

    Realtime Database

    The Realtime Database tab provides documentation on configuring your Backand application to work with our Socket-based real-time communications capabilities. It outlines all of the steps necessary on both the client and server sides to get everything working in your app.

    Documentation

    The documentation item has a link to this documentation.

    REST API Playground

    The REST API playground is a Swagger-based page from which you can exercise all of the SDK functionality. Use this to gain familiarity with the Backand REST API.

    Objects

    The "Objects" section of the dashboard allows you to modify the specific objects in your application's database. A menu entry is created for each table in your database, and allows you to configure your application at the object level. For each object in your system, you are given access to the following areas to modify and work with.

    Model

    This sample model JSON creates two objects - Items and Users

    [
      {
        "name": "items",
        "fields": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "text"
          },
          "user": {
            "object": "users"
          }
        }
      },
      {
        "name": "users",
        "fields": {
          "email": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "items": {
            "collection": "items",
            "via": "user"
          }
        }
      }
    ]
    

    The Model parent tab allows you to modify your database's model structure, adding new objects and establishing the relationship between them. This can be done using either our GUI model editor, or the JSON schema editor. We also provide a tab demonstrating how to make - and sync - changes to your database using an external database tool (like MySQL Workbench). Below is a brief overview of how to use this interface.

    Model Diagram

    The Model Diagram tab provides a GUI editor for working with your app's database schema. It works with the model JSON in the background to orchestrate changes to your database. Using the GUI you can easily add new objects, update existing objects, create relations between objects, and all other related database modification tasks.

    Model JSON

    The Model JSON tab provides a straightforward method of editing your database schema using well-formed JSON. You're given a pane to perform your edits, and a comparison pane so that you can easily see what has changed from the current schema. Once your changes are finalized, click "Validate & Update" to finalize your changes.

    Database (pending)

    This tab describes how to make the changes you desire in your model directly in the database. Once you've made your changes via whichever RDBMS tool you prefer, you can click the "Sync your database" button to pull the changes into Backand, updating your schema and object list.

    Object List

    For each object in your schema, you are provided a dedicated management area for that object. These are accessed via a list beneath the "New object" entry.

    Each object has a set of tabs provided that allow you to modify either the object's data, or the object itself. These tabs are Data, Actions, Security, Settings, and REST API

    Data tab

    The data tab provides you with a quick method by which you can add new records, update existing records, or remove records from your database. For every action you take in this pane, we provide the code needed to reproduce the action using the SDK - simply select the appropriate language/JavaScript framework for your project, and copy the code into your application.

    We also give you access to the Filter Data functionality, which can be used to quickly construct request filters that can be applied to GET requests. Simply click on the "Filter Data" link to expose a UI for constructing your filter, and the resulting parameter code will appear in the "Request Code" textbox on the right side of the screen.

    Actions tab

    The Actions tab allows you to work with custom actions in your object. Custom actions allow you to perform automated tasks in your Backand application. You can create actions that execute at any point during the database transaction context for an object, or create actions that execute whenever a specific URL is hit. See our documentation on custom actions for more information.

    Security tab

    The security tab allows you to create custom filters that apply restrictions to loading data associated with the user session. You can also use this tab to override your app's global security configuration, allowing custom access to your object based on user role, and also restrict access to specific fields in the object as necessary.

    Settings tab

    The Settings tab allows you to modify properties of your object directly, and work with each field in the object. At the object level, you're given the capability to enable change tracking, or to set a descriptive column. Change tracking keeps a record of all changes to an object as they occur, storing these results in App Dashboard -> Log -> Data History. This can result in performance impacts, so you should use this feature sparingly. A descriptive column represents the object when it is retrieves as a part of a list, providing the user with an easy-to-understand indicator for the current object record they are manipulating.

    The field properties provide you with the capability to make a field searchable (available via the "Search" filter when making API calls), mark a field as "required", or provide a default value for a field. These options are presented for each field in your object, but depending on usage may not be modifiable. If a field represents a link to another object in your system, you are provided with a hyperlink in the settings section that takes you directly to that related object's datagrid view.

    REST API tab

    The REST API tab offers you the capability to test all of the standard database actions with a custom Swagger interface. Once you execute the call, the request that was made - and the response received - are both provided, allowing you to quickly adopt the action into your app.

    Queries

    The queries tab provides you with the capability to generate custom queries in your system. Simply click "New Query" to start building out a custom query. When building a new query you can provide a name, input parameters, and the query body using either NoSQL or SQL syntax. You can also set the security template of the query, restricting the query access based on the user's role. On the right side of this screen, you can also perform a quick test of your query by hitting either "Test Query" or "Save & Test". The test process will present the query's URL endpoint, the SDK code needed to call the query, and a sample response.

    Query List

    As you create queries, you're provided with a list of the queries present in your system. Simply click on the name of a query to begin editing or testing the query's contents.

    Create a query

    You can add a new query by clicking on "+New Query" in the menu bar. This allows you to name the query, provide any parameters necessary, and then write the query. It also allows you to set a specific security template for the query to use as it executes, and allows you to override the security template settings when running the query.

    Update an existing query

    To update an existing query, select the query from the navigation menu and press the "Edit" button.

    Test a query

    You can test both new and existing queries using the Test query parameters panel on the right hand side of the page. This executes the query, returning both the data of the query and the URL used to execute the query.

    Background Jobs

    Background jobs (also known as cron jobs) allow you to run an action, query, or external URL request on a schedule that you define. Simply set the time and frequency, and the desired task will be executed automatically by Backand's servers. With this mechanism, you can run periodic queries for things like reports, recurring actions to control your application's behavior, or regularly post to external services.

    Create a job

    To create a new Background job, click on "+ New Job" in the "Background jobs" section of the navigation bar. Simply add a name, a description, a start time or frequency, and set the type of job (Action, Query, External URL) to execute.

    Advanced Options

    In the advanced options, you can configure the job to operate via a POST or GET request. The GET request allows you to configure the query string used in the request, as well as modify the headers sent - allowing you to send additional parameters to the job when it executes. For POST requests, you can modify both the headers and the query string, but you are also given the Request Data field which you can use to send additional parameter formats, such as long text.

    This can be very useful in distinguishing between two jobs that run the same action. For each job, you can send a "type" parameter to indicate the specific job being run. You can accomplish this by setting the "Query String" field to the appropriate value: parameters={type:1} for job 1, and parameters={type:2} for job 2.

    Update an existing job

    You can update existing job by selecting the background job from the navigation menu and pressing the "Edit" button. This allows you to change all aspects of the job.

    Test a job

    You can test both new and existing jobs using the Test buttons on the right hand side of the page. These buttons execute the job on Backand's servers, displaying the request sent and the response received. In addition to simple verification, testing can be used to verify that advanced parameters function properly, and that the job responds as expected.

    Run background job using REST API

      curl https://api.backand.com/1/jobs/run/{id}
    
       var response = $http({
           method: "GET",
           url: CONSTS.apiUrl + "/1/jobs/run/" + cronId
       });
    

    Background Jobs are useful for long running tasks such as integrating with external sites (where the response time could be slow), or sending out batched push notifications. If you commonly encounter timeout errors while running on-demand actions, then you should consider using a Background Job.

    All messages and errors are logged into the console. These messages are available in the dashboard under Log --> Console.

    Test background job

    curl https://api.backand.com/1/jobs/run/{id}/test
    

    In order to test the job and get a response immediately (either valid results or an error message), use the following REST endpoint.

    Analytics

    The Analytics section provides several reports exploring the various facets of you app's performance. You are able to provide a date range to examine, using preconfigured date ranges our your own custom range. You can use these to gain insight on user activity within your app, as well as on the resources being used by your application.

    Reports

    Backand provides the following reports for your app:

    Security & Auth

    The Security & Auth section allows you to modify the security settings for your application, setting both application-level and user-level security policies.

    Security configuration

    The Security Configuration section allows you to set application-wide settings for access to your project.

    Anonymous Access

    When enabled, this allows any user with a link to access your application. You can set a role for anonymous users, and obtain an anonymous access token to use in your application's code.

    Public App

    The Public App settings determines whether users can sign up for your app, or if they must be invited. You can also assign a role to each invited user.

    Custom pages

    These custom pages are pages within your application code that are used for user registration and login. The Custom Registration Page URL is supplied in the invitation email sent to new users. The Custom Verified Email Page URL is sent to the user after they have verified their email address. The Custom Password Reset URL is used as a part of the password reset process - the user is sent to this page with a reset token, which needs to be provided in order to perform the password reset with the SDK.

    Sign-up Email Verification

    This enables or disables automated user email verification. When enabled, users are sent a verification email by Backand which they must use to verify their account. When disabled, this action is not performed and users are immediately able to use their account.

    Social & Keys

    The Social & Keys page consists of two parts - the tokens, and the social media configurations. These settings are used in your app to enable integration with social media providers, allowing your users to sign into your app using their social media accounts.

    Master Token

    The master Token is a token that you can use to access your Backand app without a username or password.

    API Signup Token

    The API Signup Token is used whenever you contact the Backand API to register a new user with your application.

    Social Configuration

    In this section you can configure the social app for each company (GitHub, Google and Facebook). By default you can use Backand as the social app, unless you add your own client and secret ids.

    Social Redirect URIs

    Following sign-in with social media, your user will be redirected to a Redirect URI that is then tasked with obtaining the full details of the authentication that occurred. This URI is called automatically by Backand, and is specified as the redirectUrl parameter to the socialMediaSignup call in the API. In order to support this more secure pattern of working with social media authentication, all URLs that can be redirected to must be present in this Social Redirect URI list. If a URL is not present in this list, then the redirect request will not be honored.

    GitHub App Configuration

    In order to enable signing in with GitHub credentials, follow these steps:

    1. Check the 'Use your credentials for signing in with GitHub' toggle
    2. Register your application on GitHub's Developer Applications Tab. Include the following details, which are mandatory for new applications:
      • Application name: A name for your app. Something users will recognize and trust
      • Homepage URL: Your application's url (you can use http://localhost for testing purposes)
      • Authorization callback URL: https://api.backand.com/1/user/github/auth
    3. Record the Client ID and the Client Secret from GitHub
    4. Finally, on the Social & Keys section of the Backand app management dashboard, copy the Client ID and Client Secret in the correct fields in the GitHub section..

    More details on GitHub integrations are available in the developer documentation.

    Google App Configuration

    In order to add Google app sign-in, follow these steps:

    1. Check the 'Use your credentials for signing in with Google' toggle/
    2. Open the Google Developer's Console.
      1. In the Google Developer's Console, Click Create Project.
      2. Enter a name, or accept the defaults, and click Create.
      3. Click Library to view the API Library, which lists all available APIs. The APIs are grouped by product family and popularity. Click on Google+ API under Social APIs
      4. Click Enable (You should see this to the right of the Google+ API button).
      5. In the sidebar on the left, select Credentials.
      6. Click Create credentials and select OAuth client ID
      7. Click Configure consents screen tab on the right panel and enter the Product name, Privacy policy URL (https://www.backand.com)
      8. Click Save
      9. Enter the following details: * Application type: Web application * Name (this can be your Backand app name) * Authorized JavaScript origins: leave this field empty * Authorized redirect URIs: Replace the default example URL with 'https://api.backand.com/1/user/google/auth'
        1. Click Create and Create again
        2. Record the Client ID and Client secret from the popup window and click OK
      10. On the left side bar click Dasboard make sure Google+ API is listed under the API list. On the right side of the list, make sure that the displayed action text is disable, indicating that the API is currently enabled.
    3. Finally, on the Social & Keys section of the Backand app management dashboard, copy the Client ID and Client Secret you copied down in the last step.

    For more details on integrating with Google, review their developer documentation.

    Facebook App Configuration

    In order to add Facebook login integration, follow these steps:

    1. Check the 'Use your credentials for signing in with Facebook' toggle.
    2. Open the Facebook Developers console.
    3. Optional: Click MyApps and register as developer
      1. Under My Apps, select Add a new app
      2. In the wizard that follows, provide your app's name and Category
      3. Click Create app ID
      4. Complete the Security Check step
      5. In the sidebar on the left, select Settings
      6. In Basic tab add your Contact Email
      7. In the sidebar click + Add Product under Products
      8. Click Get Started in the Facebook Login product
      9. In Valid OAuth redirect URIs enter: 'https://api.backand.com/1/user/facebook/auth'
      10. Click Save Changes
      11. To start using your app, you need to make it public, open App Preview from the left menu and change Make {{appName}} public? to yes and confirm the popup window
      12. In the sidebar on the left, select Dashboard
      13. Record the App ID
      14. Click Show (near App Secret) and enter your Facebook password.
      15. Record the App Secret
    4. Finally, on the Social & Keys section of the Backand app management dashboard , copy the App ID and App Secret you recorded into the appropriate fields in the Facebook integration section.
    Twitter App Configuration

    In order to add Twitter login integration, follow these steps:

    1. Un-check the 'Use Back& app for signing in with Twitter' toggle.
    2. If you haven't added your phone number to Twitter you'll need to add it before creating Twitter app, please follow these instructions
    3. Open the Twitter Apps console.
    4. Click Create New App button
      1. Enter the App details - Name, Description, Website
      2. In the Callback URL enter: https://api.backand.com/1/user/twitter/auth
      3. Check Yes, I agree in the developer agreement
      4. Click Create your Twitter application button
      5. In the Detail tab of your newly created app scroll down to the Application Setting area and click the manage keys and access tokens link
      6. Record the Consumer Key (API Key) and the Consumer Secret (API Secret)
    5. In the Backand dashboard, copy the Consumer Key and API Secret you recorded into the appropriate fields in the Twitter integration section.
    Local ADFS App Configuration

    In order to add ADFS login integration, follow these steps:

    # Step 2
    Add-AdfsRelyingPartyTrust -Name "Backand QA" -Identifier "https://api.backand.com" -TokenLifetime 10 -IssueOAuthRefreshTokensTo AllDevices -EnableJWT $True -IssuanceTransformRules '@RuleTemplate = "PassThroughClaims" @RuleName = "Windows account name" c:[Type=="http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"] => issue(claim = c); @RuleTemplate = "PassThroughClaims" @RuleName = "UPN" c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"] => issue(claim = c);' -IssuanceAuthorizationRules '=> issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");'
    
    # Step 3
    # Update the ClientId with any GUID value (Get a <a href="https://www.guidgenerator.com/">new GUID</a>)
    Add-ADFSClient -Name "Backand" -ClientId "188c552d-bf43-409b-9355-a0fb0eb227e3" -RedirectUri "https://api.backand.com/1/user/adfs/auth"
    
    # Step 4
    # 43,200 is the number of minutes in 30 days - you may change it to meet your organization requirements
    Set-AdfsProperties -EnableKmsi $True –KmsiLifetimeMins 43,200
    
    1. Open windows command shell on the ADFS server with Admin permissions
    2. Run Add-AdfsRelyingPartyTrust command with the following parameters (you may change the defaults as needed):
    3. Run Add-ADFSClient to add Backand as a client application to your ADFS:
    4. Run this command to configure persistent Single Sign-On and show the "keep me signed in" checkbox:
    5. Finally, on the Social & Keys section of the Backand app management dashboard, copy the Client Id and Redirect Uri you entered in the Add-ADFSClient command.
    Azure AD App Configuration

    In order to add Azure AD application integration, follow these steps:

    1. Open the Azure new portal.
    2. Select Azure Active Directory
    3. Select App Registrations
    4. Click +Add and use these parameters:
      1. Name: Backand
      2. Application Type: Native
      3. Redirect URI: https://api.backand.com/1/user/azuread/auth
    5. Click Create
    6. Click on the Backand App and copy the Application Id / Client Id (e.g. 7c799275-1102-4aa6-b36a-fac7aa7fee60)
    7. Click on "Endpoints" menu and copy "OAUTH 2.0 AUTHORIZATION ENDPOINT". In Backand just connect to /oauth2 in the OAUTH 2.0 Endpoint filed(e.g. "https://login.windows.net/a652911c-7a2c-4a9c-d1b2-d149256f461b/oauth2")

    8. Finally, on the Social & Keys section of the Backand app management dashboard, copy the Application Id into the Client Id field and OAUTH 2.0 Endpoint you copied down in the last step.

    Registered Users

    The registered users page lists all users currently registered for your app. You can add new user, edit existing user details, delete a user, or invite a new user to your application via email. You can also manually enter - and edit - user passwords from this interface.

    Team

    The Team section allows you to add new administrative users to your application. Admin users have full access to the application dashboard, and your application's configuration. You can perform all of the same actions available on the Users page on the Team page as well.

    Security Actions (Backand Dashboard)

    The actions on this page, much like those on the other pages of the application, allow you to define custom actions to occur at each point in the transactional CRUD conversation against an object, or when called by accessing a specific URL. These actions, though, are tied specifically to the internal Backand Users object, which manages your application''s security. All of the standard custom action options are available for use in this section, and you can easily create new actions, edit existing actions, and test the actions you have created.

    The following actions are provided by default for a Backand application. You can edit these actions as you desire, or add new actions that occur during the database transaction that modifies your app's registered_users table:

    Action Name When it Runs What it Does
    accessFilter Automatic, after successful authentication See our post on third-party security
    backandAuthOverride Automatic, prior to user authentication See our post on third-party security
    beforeSocialSignup Automatic, prior to social media registration This allows you to run additional code prior to signing up a user through social media-based authentication
    ChangePasswordOverride Automatic, during password change not currently used
    newUserVerification Automatic, during user registration This verification message is sent to new users if email address verification is enabled
    requestResetPassword Automatic, after a call to requestResetPassword This email is sent in response to initiating a password reset
    socialAuthOverride Automatic, after social media authentication and registration See our post on third-party security
    userApproval Automatic, after user registration This email is sent to users to inform them that they have been successfully added to an app
    Admin Invitation Email Automatic, during user creation This email is used to invite administrators to your application
    Create My App User Automatic, during user creation This function takes the user input from the sdk signup call, and uses it to populate a custom users object in your application.
    User Invitation Email Automatic, during user creation This email is used to invite standard users to your application
    Update My App User Automatic, during user update This action occurs whenever a registered user is modified. It attempts to make the appropriate modifications in your app's custom users object
    Delete My App User Automatic, during user deletion This action occurs whenever a registered user is deleted. It attempts to remove the associated users record for the user being deleted.

    Here's a general informational graphic demonstrating how authentication-related actions integrate with the system:

    image

    Security Templates

    Security templates allow you to create a template that is used to set permissions on objects. You can create new templates, update existing templates, and rename security templates as you see fit. Each of the checkboxes corresponds to the REST API action indicated by the column header. When you check "Create" for a user role, for example, and then assign that security template to an object, all users with the specified role will be granted "Create" access to the object.

    Hosting

    The Hosting menu item provides all the tools you need to work with Backand Hosting.

    Configuration

    This page provides dynamic information designed to walk you through the relevant steps for the current stage of your hosting effort. Follow the provided guide to initiate, update, and deploy your project's hosting.

    Hosting files

    The Hosting Files section lists the files hosted by Backand on behalf of your app. It provides a simple UI for listing and downloading the hosted files.

    Storage files

    The Storage Files section lists the files stored in S3 on behalf of your application. You can view the list of files, upload a new file, download a file, or delete a file from your app's s3 storage.

    Log

    The Log menu item provides access to Backand's built in logging functionality. We provide a number of different logs with different targets, allowing you to easily see all activity in your application in one place.

    API Requests

    The API Requests log logs all requests made to your application over the web, either via cURL or using our SDK. You can filter the request logs based on any of the provided fields.

    Console

    The Console log logs all console messages created by your application's actions. You can use this when troubleshooting server-side actions to ensure that all messages are being received correctly, and you can filter the log messages to match your current debugging scenario.

    Server Side Exceptions

    The Server Side Exceptions log provides access to any server-side exceptions generated during your app's execution. Details on the exception are provided, and you are given the capability to filter the logs based on arbitrary criteria.

    Configuration

    The Configuration log tracks all configuration changes made to your application. This includes all actions taken in your application's Backand dashboard, recording the action taken and the user responsible. You can also filter the log by any of the provided fields.

    Data History

    The Data History log contains entries for all modifications made to objects that have data tracking enabled. This log will remain empty until the data tracking feature is enabled for an object.

    Settings

    The Settings configuration section contains the application-level configurations for your Backand app.

    General

    The General section contains global configuration settings for your application. You can change the app name and title, enable debug mode, adjust the date format, adjust default pagination and object retrieval parameters, and provide global configuration values available throughout your application.

    Database

    The Database section contains information on your app's Backand database. If you have not yet entered any data or modified the default model, you are also given the capability to connect to an existing database platform on this tab. You can use the connection data provided to connect any third-party DB management tool to your database, allowing you to modify or migrate your database as you desire.

    Configuration

    The Configuration tab allows you to version your app's configuration. You can export and import settings, or work with previous application configurations.

    Billing Portal

    The Billing Portal provides you with a UI that gives you easy access to all the details of your billing agreement with Backand. From this section, you can view your current subscription, your contact information, a list of changes made, and other billing details. You can also add and modify credit card information, add or change your billing address, or review your payment history.

    Upgrade Plan

    The Upgrade Plan section provides you with the capability to change your plan to something that meets your needs. Simply select the plan you wish to use, ensure your payment method is correct, then confirm the change.

    Payment Method

    The Payment Method section allows you to add and edit your payment methods. Provide all of the required information for your payment method to update how your account is charged.

    Vanilla SDK

    The primary functionality in the Backand SDK is contained in the Vanilla SDK, located on our GitHub page. This provides a global object - backand - that can be used to work with the Backand SDK. Review the ReadMe on the GitHub repo to get started, or navigate to our SDK Documentation.

    Overview

    This is the documentation for Back&'s Vanilla SDK. This encapsulates all common API functionality. All of our other SDKs wrap this core set of function calls, which in turn provides programmatic access to your app's back end.

    Installation

    To install the Vanilla SDK, use the correct command for your dependency management platform:

    Provider Command
    npm $ npm i -S @backand/vanilla-sdk
    yarn $ yarn add @backand/vanilla-sdk
    bower $ bower install backand-vanilla-sdk
    clone/download via Git $ git clone https://github.com/backand/vanilla-sdk.git

    Import

    
    <!-- Includes for index.html, or appropriate location -->
    <script src="node_modules/@backand/vanilla-sdk/dist/backand.min.js"></script>
    <script src="backand.min.js"></script>
    
    // Import the Backand SDK object
    import backand from '@backand/vanilla-sdk'
    const backand = require('@backand/vanilla-sdk')
    
    

    To work with the SDK, you need to first import it into your project. This requires including the JavaScript source in your project in index.html (or another appropriate location), and then importing the backand object into your application. The backand object is the root of the SDK, and will be used as the core of all calls to your Backand application.

    Quick Start

    # Use a bearer token to retrieve items. Obtain the token from calling the /token endpoint
    curl https://api.backand.com/1/objects/items -H "Authorization: Bearer OfKDiw6fQwfhmUcoh3WuXken_Sgj18za8SDqn1Ed2S_qI88HWNwGBSpG2ktUkSbNIwcGn6dwos7ivvVARC1UIiCf8fzlNynFNZamCZPDpbOhRjheq3RnU6HJiCbqlks57PLvMnf9PxGK8D3FU8MeaPyUk7mmbAtvgc6GF-9s13YpFjVQkM5XRZ-CsuWjaRoukygLMOivj1iPYxBB4c-hu6ocZKQljiSnw6rroYbD4spmUIkwDnC0rz1jP9ln5KNI3KmO0KLcWJF6E_zWfepdFw"
    
    // Initialize the SDK
    backand.init({
      appName: 'APP_NAME',
      anonymousToken: 'ANONYMOUS_TOKEN'
    });
    
    // Retrieve a list of records from the server
    backand.object.getList('users')
      .then((response) => {
          console.log(response);
      })
      .catch(function(error){
          console.log(error);
      });
    

    Getting started with the SDK is as simple as configuring your application access details, initializing the SDK, and calling a getList() function for one of the objects in your system. You configure the SDK with your application's APP_NAME and ANONYMOUS_TOKEN. Once you've called init() with these values, the SDK will use this data to automaticaly manage authentication headers for API requests to your app's REST API.

    // Sample response
    {
      "totalRows": 2,
      "data": [
        {
          "__metadata": {
            "id": "1",
            "fields": {
              "id": {
                "type": "int",
                "unique": true
              },
              "items": {
                "collection": "items",
                "via": "user"
              },
              "email": {
                "type": "string"
              },
              "firstName": {
                "type": "string"
              },
              "lastName": {
                "type": "string"
              }
            },
            "descriptives": {
    
            },
            "dates": {
    
            }
          },
          "id": 1,
          "items": null,
          "email": "matt@backand.com",
          "firstName": "Matt",
          "lastName": "Billock"
        },
        {
          "__metadata": {
            "id": "2",
            "fields": {
              "id": {
                "type": "int",
                "unique": true
              },
              "items": {
                "collection": "items",
                "via": "user"
              },
              "email": {
                "type": "string"
              },
              "firstName": {
                "type": "string"
              },
              "lastName": {
                "type": "string"
              }
            },
            "descriptives": {
    
            },
            "dates": {
    
            }
          },
          "id": 2,
          "items": null,
          "email": "start@backand.io",
          "firstName": "Start",
          "lastName": "Backand"
        }
      ]
    }
    

    This connects your Back& application (with the app name of APP_NAME and an anonymous access token of ANONYMOUS TOKEN) to your current project. Once the connection is configured, the SDK uses this connection information to construct HTTP requests to your API. Result data is returned in the response object as the member variable data. In the case of getList, this will be a JSON array of objects pulled from the users table in your Back& application. You can easily change the table being manipulated by replacing users with the name of any object in your system.

    Working with the SDK

    The SDK is implemented as a wrapper around HTTP calls made to the Backand service. As a result, you can access all of Backand's functionality via cURL calls, provided you configure the header correctly. Review the section on User Authentication and Security for more information on configuring the headers for each call. For JavaScript applications, the SDK takes care of the complexity of managing the authentication headers required to communicate with Backand. Simply utilize the built-in authentication methods to authenticate, and all future requests will include the correct headers.

    The SDK is built around a global service object exported from the JavaScript called backand. You can use properties of this object to interact with the various endpoints. In the next several sections, we'll walk through all of the functionality offered by our SDK. View the pane on the right for sample code that can be used to call each method, as well as sample responses.

    SDK Properties - Overview

    Below is a list of the properties offered by the SDK, a description of the functionality handled by that property, and the list of methods provided by that property:

    Name Methods Description
    constants EVENTS, URLS, SOCIALS Provides access to constants in the SDK
    helpers filter, sort, exclude, storageAbstract Provides helper methods for working with the SDK
    root properties useAnonymousAuth, useBasicAuth, signin, signup, socialSignin, socialSigninWithToken, socialSignup, requestResetPassword, resetPassword, changePassword, signout, getSocialProviders These are properties available directly on the Backand SDK object, mostly focused on Authentication
    defaults none This stores the current app's configuration in the SDK
    object getList, create, getOne, update, remove, .action.get, .action.post This encapsulates all methods used to manipulate objects
    file upload, remove Provides helper methods for working with files
    query get, post Allows you to work with custom query objects
    user getUserDetails, getUsername, getUserRole, getToken, getRefreshToken Provides information on the current authenticated user
    on none This is the event handler for socket.io functions, replacing socket.on
    offline cache, queue, setOfflineMode provides management for offline execution capabilities

    Default Events

    By default, the Back& SDK emits the following events that your code can respond to:

    Name Description Syntax
    SIGNIN dispatched on signin window.addEventListener(backand.constants.EVENTS.SIGNIN, (e)=>{}, false);
    SIGNOUT dispatched on signout window.addEventListener(backand.constants.EVENTS.SIGNOUT, (e)=>{}, false);
    SIGNUP dispatched on signup window.addEventListener(backand.constants.EVENTS.SIGNUP, (e)=>{}, false);
    START_OFFLINE_MODE dispatched on start offline mode window.addEventListener(backand.constants.EVENTS.START_OFFLINE_MODE, (e)=>{}, false);
    END_OFFLINE_MODE dispatched on end offline mode window.addEventListener(backand.constants.EVENTS.END_OFFLINE_MODE, (e)=>{}, false);

    SDK Methods

    NOTE: - All Methods return a Promise -> you can work with the response using .then() and .catch() - You can see the response schema here

    Root properties

    The root properties on the SDK are primarily focused on authentication and session management functionality. These all hinge upon the use of the .init() function. This function accepts your application name, an anonymous access token, and an optional signup token by default - these three pieces of information are all you need to connect the SDK to any Backand application.

    Other methods on the root of the object are focused on configuring individual platform settings, such as setting an API URL, adjusting the local storage method used, or working with our socket-based communications. Review the details for each function call below to see sample calls and responses, as well as explanations of each element's functionality.

    backand.init()

    # This call has no cURL equivalent
    
    var config = {
       appName: 'APP_NAME',
       anonymousToken: 'ANONYMOUS_TOKEN'
                 };
    backand.init(config);
    

    The init() method creates a new Back& SDK instance with the supplied configuration.

    Parameters

    The available parameters for the config parameter are:

    Param Name Data Type Usage Required? Default Value
    appName string Sets the name of your backand app required
    anonymousToken string Sets the anonymous token of your backand app required
    useAnonymousTokenByDefault boolean Determines whether the sdk should use the anonymousToken when there is no other token optional true
    signUpToken string Sets the signup token of your backand app optional
    apiUrl string Sets the API url of backand servers optional https://api.backand.com
    storage object Sets the storage type to use (local/session/implementation of StorageAbstract) optional localStorage
    storagePrefix string Sets prefix to use in the storage structure optional BACKAND_
    manageRefreshToken boolean Determines whether the sdk should manage refresh tokens internally optional true
    runSigninAfterSignup boolean Determines whether the sdk should run signin after signup automatically optional true
    runSocket boolean Determines whether the sdk should run socket automatically optional false
    socketUrl string Sets the socket url of backand servers optional https://socket.backand.com
    isMobile boolean Determines whether the sdk is part of a mobile application optional false
    mobilePlatform string sets the platform used to build the mobile application ('ionic'/'react-native') optional 'ionic'
    runOffline boolean Determines whether the sdk should run pending offline actions. (cached data and queued requests) optional false
    allowUpdatesinOfflineMode boolean Determines whether the sdk will allow object updates or deletion while in offline mode. When set to "true", all objects must contain a field, "updatedAt", that needs to be before the SDK entered offline mode. Any update/delete operations on fields with an "updatedAt" that occurs after the SDK entered offline mode will fail. optional false
    beforeExecuteOfflineItem function Sets the function to be called before each cached request. In order to determines whether to dispatch the next request or drop it, you must call return with a valid boolean. optional (request) => { return true }
    afterExecuteOfflineItem function Sets the function to be called after each cached request. optional (response, request) => { }

    .on()

    # This call has no cURL equivalent
    
      //Wait for server updates on 'items' object
      Backand.on('items_updated', function (data) {
        //Get the 'items' object that have changed
        console.log(data);
      });
    

    You can easily integrate with our Socket functionality using the on method. Socket signin and signout are handled automatically by the SDK.

    Parameters

    name type description
    eventName string Name of the socket event to subscribe to
    callback function Callback triggered when eventName is received

    .signin()

    curl -X POST -d "username=<username>" -d "password=<password>" -d "appName=<app name>" -d "grant_type=password" https://api.backand.com/token
    
    backand.signin(username, password)
      .then(res => {
        console.log('signin succeeded with user:' + res.data.username);
      })
      .catch(err => {
        console.log(err);
      });
    
    {
      "access_token": "TGvnEBfhreaVwJspg0s_uDKppvjaA9jICQGsHSocmHnt8s98_rkMQIkf4fvd25j3i5QOJKPpZTpoCpdu7duxcjsUyLRYihLBhcyiSAv6PxeY4zG6SpL5CtfDl6PSpqJx571k_fSphmIha40bb0wvks3O-21E85hV7GdD3D0TJtSR0U4twJhaJl-HJmeGCEEmfr27FFtRu2Hb9pwkCNnlUNQast4s5fTlTOEiapspgUgfWT9s4V47t5TUuD6onMtDNQmXfekr-Yj2i_Q68L8a_Q",
      "token_type": "bearer",
      "expires_in": 86399,
      "appName": "bkndionicstarter",
      "username": "john@backand.com",
      "role": "User",
      "firstName": "John",
      "lastName": "Doe",
      "fullName": "John Doe",
      "regId": 1009820,
      "userId": "29"
    }
    

    Signin with username and password in order to get access_token to be used in all other calls. If you don't have users you should use anonymous token only.

    Parameters

    name type description
    username string the username to authenticate
    password string the user's password

    .signup()

    # Replace placeholder text with values for your user. Obtain signup token from
    # the Security & Auth section in your app dashboard.
    # This uses environment variables to ease presentation of the
    # information, and supplies the fields as data arguments to the cURL command.
    # $SIGNUP_TOKEN - the name of the backand application you are connecting to
    curl https://api.backand.com/token -d username=$USERNAME -d password=$PASSWORD -d grant_type=password -d appName=$APP_NAME
    
    curl -X POST -d "{'email':'user email','password':'user password','confirmPassword':'password confirmation','firstName':'first name','lastName':'last name'}" -H "SignUpToken: $SIGNUP_TOKEN" https://api.backand.com/1/user/signup
    
    backand.signup(firstName, lastName, email, password, confirmPassword, parameters = {})
      .then(res => {
        console.log(res.data);
      })
      .catch(err => {
        console.log(err);
      });
    
    {
      "username": "matt+test5@backand.com",
      "currentStatus": 1,
      "message": "The user is ready to sign in",
      "listOfPossibleStatus": [
        {
          "status": 1,
          "message": "The user is ready to sign in"
        },
        {
          "status": 2,
          "message": "The system is now waiting for the user to responed a verification email."
        },
        {
          "status": 3,
          "message": "The user signed up and is now waiting for an administrator approval."
        }
      ],
      "token": "yHbb7a9S3yteUIo604KwwhchcrpE-wESafVtnnhQgAkj57ZxjWveNR63t64hqy8N2Gd_NPQhw6SAjNLv2mfYYP_rG-vELKe6gqEhqpWBFV43lD5IESH8k1SZldCmZiKLBvhCB_iHg4TfJQ8rUxh8ODYzaLALsSsn-I30ck7h21zn_LWDzxqxZa1Jq12tS0wrII7wOIyQiFCbsEmZiNMnlOR7Oz8CD7zhNHdOCFVh8Y801QIt3Jnn1hYz_4u1niWKJ5acTQqIEfXLZ7k65WnXuD46-UwZ0sORyKDj99o_xxEZpovchVm55cb5kRggqsmUjZBnP5N79fZiYA4tA8p_jPMBePIWE0q2WQ2m6CNJeJc"
    }
    

    Creates a new user in your app. in signup you must provide the basic details of username email, first name, last name and password:

    Parameters

    name type description
    firstName string the user's first name
    lastName string the user's last name
    email string the user's email
    password string the user's password
    confirmPassword string the value entered by the user when asked to confirm the password during registration
    parameters object An object containing information for any paremeters to the signup call. This allows you to set additional info on the user object at registration time

    .changePassword()

     curl -X POST  -d "{'oldPassword':'<old password>','newPassword':'<new password>'}" -H "Authorization: Bearer FrJQqDuGeo-U2b5QHhPeF2GS86U9EDTz79CEUbtbTPl032g2VCJPpiuAuGjAS0dR-u4XfxB2p0AgeOdkMulo3FEZWqOXIdzVdjJe4u2m9CyPzzK49YzY4SeD5Ea5p-6LbJLcpDJbE2nkzGv4TQw-S3pq-Tmo-RuuKnEKbEDOMfdSjlTed7Tks2ioeVjSKUwazwX4yglg0DPVavLPFrRp9KBNTnTNnoTOFd4zbC7gGxLjIPwU1-_T_N2UK7XIBlSGXbUBL_Zybxt1fWRlSrvxlw" https://api.backand.com/1/user/changePassword
    
    backand.changePassword(oldPassword, newPassword)
      .then(res => {
        console.log('Password changed');
      })
      .catch(err => {
        console.log(err);
      });
    
    This call returns no data, only an HTTP Status Code
    

    Changes the password of the current user

    Parameters

    name type description
    oldPassword string the user's old password
    newPassword string the user's desired new password

    .socialSignin()

    # There is no cURL equivalent for this call
    
    backand.socialSignin(provider)
      .then(res => {
        console.log('signin succeeded with user:' + res.data.username);
      })
      .catch(err => {
        console.log(err);
      });
    

    Signs the user into a Back& application using a social media provider as the authentication method. This opens a dialog window supplied by the social media network provider. If the user does not have an account with the selected provider, they will be prompted to create one as a part of this process.

    Parameters

    name type description
    provider string Name of the provider to authenticate with. The full list can be obtained by calling backand.getSocialProviders(scb)

    .useAnonymousAuth()

    // enable anonymous auth
    backand.useAnonymousAuth(true);
    
    // disable anonymous auth
    backand.useAnonymousAuth(false);
    

    This configures the SDK to use Anonymous Authentication when authenticating web requests with the Backand servers.

    Parameters

    name type description
    flag boolean If true, this application will use Anonymous Authentication.

    .useBasicAuth()

    // enable basic auth
    backand.useBasicAuth(true);
    
    // disable basic auth
    backand.useBasicAuth(false);
    

    This configures the SDK to use Basic Authentication when authenticating web requests with the Backand servers.

    Parameters

    name type description
    flag boolean If true, this application will use Basic Authentication.

    .socialSigninWithToken()

    backand.socialSigninWithToken(provider_name, token_from_provider);
    

    Authenticates a user with Backand using a token provided by a social media provider's authentication schema.

    Parameters

    name type description
    provider string Name of the provider to authenticate with. The full list can be obtained by calling backand.getSocialProviders()
    token string the authentication token provided by the social media provider

    .socialSignup()

    backand.socialSignup(provider_name, "test@example.com")
    

    This creates a new user in your application using a social media provider.

    Parameters

    name type description
    provider string Name of the provider to use for registration
    email string The new user's email address.

    .requestResetPassword()

    // Initiate a password reset. This results in a call to your Custom Password Reset URL with a reset token.
    backand.requestResetPassword("email@domain.com");
    

    This method initiates a password reset request. Please note that if you have not configured your custom registration page, custom verified email page, or custom password reset URLs in Security & Auth -> Configuration, this process will not function properly.

    Parameters

    name type description
    username string The username requesting the password reset

    .resetPassword()

    //This uses the provided reset token to reset the user's Backand password.
    backand.resetPassword("hunter2", "123abc");
    

    This method resets the password for the user associated with the provided reset token. This reset token is provided by Backand in a call to your configured password reset URL.

    Parameters

    name type description
    newPassword string The user's chosen new password
    resetToken string The reset token provided by Backand

    .signout()

    backand.signout();
    

    Resets authentication in the SDK, logging out the current user. Call this method prior to authenticating a new user.

    Parameters

    None

    .getSocialProviders()

    // Obtains a list of valid social media providers supported by Backand's social signin functionality.
    

    This method obtains a list of supported social media providers from Backand. These social media provider names can then be used with any social media authentication method.

    Parameters

    None

    .object property

    The .object property contains functions related to basic database operations that can be performed on an object. You can also use this property to call the on-demand actions governed by an object in your system.

    .getList()

    # Env var $ANONYMOUS_TOKEN should contain your app's anonymous token
    curl -H "AnonymousToken: $ANONYMOUS_TOKEN" https://api.backand.com/1/objects/items
    
    // No filters
    backand.object.getList(object, params)
      .then(res => {
        console.log(res.data);
      })
      .catch(err => {
        console.log(err);
      });
    
    // With filter parameters
    let params = {
      sort: backand.helpers.sort.create('creationDate', backand.helpers.sort.orders.desc),
      exclude: backand.helpers.exclude.options.all,
      filter: backand.helpers.filter.create('user', backand.helpers.filter.operators.relation.in, userId),
      pageSize: 20,
      pageNumber: 1
    };
    backand.object.getList(object, params)
      .then(res => {
        console.log(res.data);
      })
      .catch(err => {
        console.log(err);
      });
    
    
    {
      "totalRows": 2,
      "data": [
        {
          "__metadata": {
            "id": "73",
            "fields": {
              "id": {
                "type": "int",
                "unique": true
              },
              "name": {
                "type": "string"
              },
              "description": {
                "type": "text"
              },
              "user": {
                "object": "users"
              },
              "createdAt": {
                "type": "datetime"
              }
            },
            "descriptives": {
              "user": {
                "label": null,
                "value": ""
              }
            },
            "dates": {
              "createdAt": "2017-03-08 23:13:10Z"
            }
          },
          "id": 73,
          "name": "Test 1",
          "description": "A first test item",
          "user": "",
          "createdAt": "2017-03-08T23:13:10"
        },
        {
          "__metadata": {
            "id": "74",
            "fields": {
              "id": {
                "type": "int",
                "unique": true
              },
              "name": {
                "type": "string"
              },
              "description": {
                "type": "text"
              },
              "user": {
                "object": "users"
              },
              "createdAt": {
                "type": "datetime"
              }
            },
            "descriptives": {
              "user": {
                "label": null,
                "value": ""
              }
            },
            "dates": {
              "createdAt": "2017-03-08 23:13:21Z"
            }
          },
          "id": 74,
          "name": "Test 2",
          "description": "A second test item",
          "user": "",
          "createdAt": "2017-03-08T23:13:21"
        }
      ]
    }
    

    Fetches a list of records from the specified object. Uses params to store filter data

    Parameters

    name type description
    object string Name of the Back& object to work with
    params object A hash of filter parameters. Allowed parameters are: pageSize, pageNumber, filter, sort, search, exclude, deep, relatedObjects

    .getOne()

    # Env var $ANONYMOUS_TOKEN should contain your app's anonymous token
    curl -H "AnonymousToken: $ANONYMOUS_TOKEN" https://api.backand.com/1/objects/items/<id>
    
    backand.object.getOne(object, id, params)
      .then(res => {
        console.log(res.data);
      })
      .catch(err => {
        console.log(err);
      });
    
    {
      "__metadata": {
        "id": "73",
        "fields": {
          "id": {
            "type": "int",
            "unique": true
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "text"
          },
          "user": {
            "object": "users"
          },
          "createdAt": {
            "type": "datetime"
          }
        },
        "descriptives": {
          "user": {
            "label": null,
            "value": ""
          }
        },
        "dates": {
          "createdAt": "2017-03-08 23:13:10Z"
        }
      },
      "id": 73,
      "name": "Test 1",
      "description": "A first test item",
      "user": "",
      "createdAt": "2017-03-08T23:13:10"
    }
    

    Retrieves a single record from the specified object.

    Parameters

    name type description
    object string Name of the Back& object to work with
    id integer ID of the record to retrieve, subject to the filter specified in params
    params object A hash of filter parameters. Allowed parameters are: deep, exclude, level

    .create()

    # Env var $ANONYMOUS_TOKEN should contain your app's anonymous token
    curl -X POST -H "AnonymousToken: $ANONYMOUS_TOKEN" -d "{'name':'Test 3','description':'A third test item'}" https://api.backand.com/1/objects/items
    
    backand.object.create(object, data, params)
      .then(res => {
        console.log('object created');
      })
      .catch(err => {
        console.log(err);
      });
    
    {"__metadata":{"id":"75"}}
    

    Creates a record with the provided data in the specified object

    Parameters

    name type description
    object string Name of the Back& object to work with
    data object Data to use in the creation of the new record
    params object A hash of filter parameters. Allowed parameters are: returnObject, deep

    .update()

    # Env var $ANONYMOUS_TOKEN should contain your app's anonymous token
    curl -X PUT -H "AnonymousToken: $ANONYMOUS_TOKEN" -d "{'description':'A first items updated description'}" https://api.backand.com/1/objects/items/73
    
    backand.object.update(object, id, data, params)
      .then(res => {
        console.log('object updated');
      })
      .catch(err => {
        console.log(err);
      });
    
    This call has no response other than the status code by default.
    

    Updates a record with the specified ID in the specified object with the provided data.

    Parameters

    name type description
    object string Name of the Back& object to work with
    id integer ID of the object to update
    data object Data to update the record with
    params object A hash of filter parameters. Allowed parameters are: returnObject, deep

    .remove()

    # Env var $ANONYMOUS_TOKEN should contain your app's anonymous token
    curl -X DELETE -H "AnonymousToken: $ANONYMOUS_TOKEN" https://api.backand.com/1/objects/items/77
    
    backand.object.remove(object, id)
      .then(res => {
        console.log('object removed');
      })
      .catch(err => {
        console.log(err);
      });
    
    {"__metadata":{"id":"77"}}
    

    Deletes a record from the specified object with the specified ID

    Parameters

    name type description
    object string Name of the Back& object to work with
    id integer ID of the object to update

    .action.get()

    # Env var $ANONYMOUS_TOKEN should contain your app's anonymous token
    curl -H "AnonymousToken: $ANONYMOUS_TOKEN" "https://api.backand.com/1/objects/action/items?name=simpleOnDemand"
    
    backand.object.action.get(object, action, params)
      .then(res => {
        console.log(res.data);
      })
      .catch(err => {
        console.log(err);
      });
    
    {"response":"Hello world!"}
    

    Triggers on-demand custom actions that operate via HTTP GET requests

    Parameters

    name type description
    object string Name of the Back& object to work with
    action string Name of the action to trigger
    params object Parameters for the action to operate upon

    .action.post()

    # Env var $ANONYMOUS_TOKEN should contain your app's anonymous token
    curl -X POST -H "AnonymousToken: $ANONYMOUS_TOKEN" "https://api.backand.com/1/objects/action/items?name=simpleOnDemand"
    
    backand.object.action.post(object, action, data, params)
      .then(res => {
        console.log(res.data);
      })
      .catch(err => {
        console.log(err);
      });
    
    {"response":"Hello world!"}
    

    Triggers on-demand custom actions that operate via HTTP POST requests

    Parameters

    name type description
    object string Name of the Back& object to work with
    action string Name of the action to trigger
    data object Object data to send as the body of the POST request
    params object Parameters for the action to operate upon

    .file

    This property allows you to work with file actions, interacting with the related files directly. You can use this after you have finished creating a server-side action in the Back& dashboard, in the Actions tab of an object (object -> actions tab -> Backand Files icon -> name: 'files')

    .upload()

    curl -X POST  -d "{'filename':'test.txt','filedata':'sample data'}" -H "AnonymousToken: $ANONYMOUS_TOKEN" "https://api.backand.com/1/objects/action/items?name=files"
    
    backand.file.upload(object, 'files', filename, filedata)
      .then(res => {
        console.log('file uploaded. url: ' + res.data.url);
      })
      .catch(err => {
        console.log(err);
      });
    

    Sample Response

    {"url":"https://files.backand.io/bkndionicstarter/test.txt"}
    

    Uploads a file for a server-side action

    Parameters

    name type description
    object string Name of the object controlling the desired server-side action
    fileAction string The name of the file action to work with
    filename string The name of the file to upload
    filedata string The file's data

    .remove()

    curl -X DELETE  -d "{'filename':'test.txt'}" -H "AnonymousToken: $ANONYMOUS_TOKEN" "https://api.backand.com/1/objects/action/items?name=files"
    
    backand.file.remove(object, 'files', filename)
      .then(res => {
        console.log('file deleted');
      })
      .catch(err => {
        console.log(err);
      });
    
    {}
    

    Removes a file from a server-side action file set.

    Parameters

    name type description
    object string Name of the object controlling the desired server-side action
    fileAction string The name of the file action to work with
    filename string The name of the file to remove

    .user

    The user property returns data about the connected user (getUserDetails, getUsername, getUserRole, getToken, getRefreshToken).

    .getUserDetails()

    curl -H "Authorization:Bearer <access token>" https://api.backand.com/api/account/profile
    
    backand.user.getUserDetails(force)
      .then(res => {
        console.log(res.data);
      })
      .catch(err => {
        console.log(err);
      });
    
    // From SDK
    {
      "status": 200,
      "statusText": "OK",
      "headers": {
    
      },
      "data": {
        "access_token": "7g9LM8ZHcvFLEIcSrdg8aYmpIK4gV9DYabab5spVsRmM6B_U3ovCWf8q6HeNFW4RMMQhsD6oiVpiTclHnO-J5qyFB2R8OyLl-ubrbIULvU0a7L8aS-cxPw7c4ij98zSPPa8kLkZBJULJRrcHn-fwmB4GygeTShNw7H1tqsHnIlcnk9X9ioj1CbjNjW4060gjTsGEOTGXACTrpQV4Qn3JD4XkSDNWySOG_15LorZdpiu7bcJ9T1EH9jnAIUyXA_0fIhFlDUsGV5Pr4EczaBufJQ",
        "token_type": "bearer",
        "expires_in": 86399,
        "appName": "bkndionicstarter",
        "username": "john.doe@backand.com",
        "role": "User",
        "firstName": "John",
        "lastName": "Doe",
        "fullName": "John Doe",
        "regId": 1009820,
        "userId": "29"
      },
      "config": {
      }
    }
    
    // From cURL
    {
      "username":"matt+test@backand.com",
      "fullName":"Matt Billock",
      "role":"User",
      "appName":"bkndionicstarter"
    }
    

    Gets the connected user's details.

    Parameters

    name type description
    force boolean Forces the SDK to refresh its data from the server. Default: FALSE

    .query

    The query property lets you initiate a custom Back& query using either HTTP GET or HTTP POST.

    .get()

    # Env var $ANONYMOUS_TOKEN should contain your app's anonymous token
    curl -H "AnonymousToken: $ANONYMOUS_TOKEN" https://api.backand.com/1/query/data/test1
    
    backand.query.get(name, params)
      .then(res => {
        console.log(res.data);
      })
      .catch(err => {
        console.log(err);
      });
    
    [
      {
        "id": 1,
        "email": "support@backand.com",
        "firstName": "support",
        "lastName": "support"
      },
      ...
    ]
    

    Calls a custom query using a HTTP GET

    Parameters

    name type description
    name string The name of the query to work with
    params object Parameters to be passed to the query

    .post()

    # Env var $ANONYMOUS_TOKEN should contain your app's anonymous token
    curl -X POST -H "AnonymousToken: $ANONYMOUS_TOKEN" -d "{'params':{...}}" https://api.backand.com/1/query/data/test1
    
    backand.query.post(name, data, params)
      .then(res => {
        console.log(res.data);
      })
      .catch(err => {
        console.log(err);
      });
    
    [
      {
        "id": 1,
        "email": "support@backand.com",
        "firstName": "support",
        "lastName": "support"
      },
      ...
    ]
    

    Calls a custom query using a HTTP POST

    Parameters

    name type description
    name string The name of the query to work with
    data object Data to be included in the body of the HTTP POST
    params object Parameters to be passed to the query

    .constants

    This contains constants used by the SDK, and is provided for reference.

    constant description
    EVENTS Contains the names of events fired by the SDK upon completion of one of several authentication actions
    URLS Contains the URL tokens for the Backand API
    SOCIALS Contains the list of social media authentication providers

    .helpers

    The .helpers property provides helper methods for constructing some of the more complex objects in the SDK. This includes filters and sort clauses for queries, as well as exclude clauses. It also provides a helper for obtaining a storageAbstract object.

    .filter()

    # There is no cURL equivalent
    
    backand.helpers.filter.create("name", "notEquals", "John")
    

    Sample response

    {
      "fieldName": "name",
      "operator": "notEquals",
      "value": "John"
    }
    

    Constructs a filter parameter for a GET query.

    Parameters

    name usage
    fieldName the name of the field to apply a filter to
    operator the operator to apply
    value the value to use the operator to test against

    Here's a list of the available operators and the data types on which they operate:

    Operator Applicable Data Types
    equals all
    notEquals numeric, date, text
    greaterThan numeric, date
    greaterThanOrEqualsTo numeric, date
    lessThan numeric, date
    lessThanOrEqualsTo numeric, date
    empty numeric, date, text
    notEmpty numeric, date, text
    in relation
    startsWith text
    endsWith text
    contains text

    .sort()

    # There is no cURL equivalent
    
    backand.helpers.sort.create("name", "asc")
    

    Sample response

    {
      "fieldName": "name",
      "order": "asc"
    }
    

    Constructs a "sort" clause for a GET request

    Parameters

    name usage
    fieldName the name of the field to apply a filter to
    order the order to sort ('asc' for ascending, 'desc' for descending)

    .exclude()

    # There is no cURL equivalent
    
    backand.helpers.exclude.options
    

    Sample response

    {
      "metadata": "metadata",
      "totalRows": "totalRows",
      "all": "metadata,totalRows"}
    

    The exclude option gives you a number of constants you can use to exclude system objects from results.

    .storageAbstract()

    export class MyStorage extends StorageAbstract{
      constructor () {
        super();
        this.data = {};
      }
      setItem (id, val) {
        return this.data[id] = String(val);
      }
      getItem (id) {
        return this.data.hasOwnProperty(id) ? this.data[id] : null;
      }
      removeItem (id) {
        delete this.data[id];
        return null;
      }
      clear () {
        return this.data = {};
      }
    }
    

    The storageAbstract function allows you to define a new storage proxy for storing browsing data in the local session/information store. Simply provide an object that implements the following methods:

    function arguments description
    setItem id, val sets a value in the storage container
    getItem id gets a value from the storage container
    remove id removes a key from the storage container
    clear none clears the storage container

    .defaults

    Contains a list of defaults for the SDK initialization parameters. The defaults are:

    parameter default value
    appName null
    anonymousToken null
    useAnonymousTokenByDefault true
    signUpToken null
    apiUrl 'https://api.backand.com'
    storage {}
    storagePrefix 'BACKAND_'
    manageRefreshToken true
    runSigninAfterSignup true
    runSocket false
    socketUrl 'https://socket.backand.com'
    exportUtils false
    isMobile false
    mobilePlatform 'ionic'

    .offline

    The offline property allows you to control the SDK's offline mode. When the SDK detects that it has lost internet connection, it will queue requests internally. Based on the configuration provided to the init() function, this can result in either a delay prior to call execution or an error response to any update or delete calls. Once internet connection is restored, the queued commands are sent to the server, and the responses should be handled asynchronously through standard promise resolution

    .setOfflineMode

    This function is used to enable and disable offline mode for debugging purposes. When true, the SDK will operate in offline mode. When false, the SDK will communicate over the web.

    Parameters

    name type description
    force boolean Sets the SDK to operate in - or exit from - offline mode.. Default: TRUE

    Sample Code

    // Enter offline mode
    backand.offline.setOfflineMode(true);
    // Exit offline mode
    backand.offline.setOfflineMode(false);
    

    .cache

    An object in which the cached data is stored

    Sample Code

    backand.offline.cache;
    

    .queue

    All requests queued during offline mode are stored here. These operations will be dispatched when offline mode ends.

    Sample Code

    backand.offline.queue;
    

    Examples and further reading

    To view the demo web page, pull down a sample from our example page and run npm start.

    Platform-specific SDKs

    This section covers our platform-specific SDKs. These SDKs are optimized for the named platform, and wrap the Vanilla SDK to provide access to Backand.

    Angular - Ionic 1 SDK

    Overview

    This SDK enables you to communicate comfortably and quickly with your Backand app using AngularJS and Ionic Framework. It wraps the vanilla-sdk to allow you to work with Back& more easily when working on projects based on Angular.js 1.

    Installation

    To install the Angular 1 SDK, use the correct command for your dependency management platform:

    Provider Command
    npm $ npm i -S @backand/angular1-sdk
    yarn $ yarn add @backand/angular1-sdk
    bower $ bower install backand-angular1-sdk
    clone/download via Git $ git clone https://github.com/backand/angular1-sdk.git

    Import

    <script src="node_modules/@backand/angular1-sdk/backand.provider.min.js"></script>
    <script src="backand.provider.min.js"></script>
    

    Include the following tags in your index.html file to start working with the SDK:

    Quick start

    angular
      .module('myApp', ['backand'])
      .config(function (BackandProvider) {
        BackandProvider.init({
          appName: 'APP_NAME',
          anonymousToken: 'ANONYMOUS_TOKEN'
        });
      })
      .controller('myAppCtrl', ['$scope', '$http', 'Backand', function myAppCtrl() {
    
      }]);
    

    Getting started with the SDK is as simple as configuring access to a Back& application, then calling getList on a relevant object.

    Review the full API reference for our Vanilla SDK to get started with your back end!

    Examples for Angular/Ionic 1

    To view a demo of the SDK in action, just run npm start - example page.

    Angular - Ionic 2 SDK

    Overview

    This SDK enables you to communicate comfortably and quickly with your Backand app using Angular 2 and the Ionic Framework version 2. It wraps the vanilla-sdk to allow you to work with Back& more easily when working on projects based on Angular.js.

    Installation

    To install the Angular 2 SDK, use the correct command for your dependency management platform:

    Provider Command
    npm $ npm i -S @backand/angular2-sdk
    yarn $ yarn add @backand/angular2-sdk

    Import

    Use the following import statement to include the Angular2 SDK in your project:

    import { BackandService } from '@backand/angular2-sdk'
    

    Quick start

    Using the Back& Angular2 SDK requires two steps - configuring access to the BackandService provider, and then actually calling the provider using the vanilla-sdk methods.

    app.module.ts:

    @NgModule({
      imports: [ ... ],
      declarations: [ ... ],
      providers: [ BackandService ],
      bootstrap: [ AppComponent ]
    })
    export class AppModule { }
    

    Update app.module.ts to include the BackandService as a provider

    app.component.ts:

    @Component({
      selector: 'my-app',
      template: `<h1>Hello angular2-sdk</h1>
        <h3>{{res}}</h3>`
    })
    export class AppComponent implements OnInit {
      res: string;
      constructor(private backand: BackandService) { }
      getList(): void {
        this.res = 'fetching objects...';
        this.backand.object.getList('users').then((res: any) => {
          this.res = `${res.data.length} objects fetched`;
          console.log(res);
        })
      }
      ngOnInit(): void {
        this.backand.init({
          appName: 'APP_NAME',
          anonymousToken: 'ANONYMOUS_TOKEN'
        });
        this.getList();
     }
    }
    

    Now, call the SDK from app.component.ts. The SDK is initialized during ngOnInit(), and getList is called as a property on AppComponent

    Review the full API reference for our Vanilla SDK to get started with your back end!

    Examples for Angular/Ionic 2

    To view a demo of the SDK in action, just run npm start - example page.

    We also offer an example app for Angular 2 - just follow the instructions in our sample project

    Redux - React SDK

    Overview

    This SDK enables you to communicate comfortably and quickly with your Backand app when building on top of React or Redux. It wraps the vanilla-sdk to allow you to work with Back& more easily when working on projects based on Redux.

    Installation

    To install the Redux SDK, use the correct command for your dependency management platform:

    Provider Command
    npm $ npm i -S @backand/redux-sdk
    yarn $ yarn add @backand/redux-sdk

    Import

    import { BackandService } from '@backand/angular2-sdk'
    

    Use the following import statement to include the Angular2 SDK in your project:

    Quick start

    $ "./node_modules/.bin/bkndredux" --help
    $ "./node_modules/.bin/bkndredux" user obj1 obj2 obj3... -m (thunk/saga)
    

    To get started, first use bkdnredux to generate the necessary Types, Actions, and Reducers for your Backand objects from the command line:

    Note: user is a unique object. It has a different Reducer and Type, and it reveals most of the authentication Actions (getUserDetails, signin, signout, etc.).

    import { combineReducers } from 'redux'
    import user from './user/userReducer'
    import obj1 from './obj1/obj1Reducer'
    import obj2 from './obj2/obj2Reducer'
    
    combineReducers({
      user,
      obj1,
      obj2
    })
    

    Next, Include the new Reducers in combineReducers() (see JavaScript tab)

    After this, we need to configure the middleware stack to work with the SDK. Pick the section that applies to your chosen middleware stack - either redux-thunk or redux-saga - then follow the corresponding instructions:

    redux-thunk

    Download redux-thunk and include it in createStore(): ```javascript import { createStore, applyMiddleware } from 'redux' import thunk from 'redux-thunk'

    createStore(rootReducer, initialState, applyMiddleware(thunk)) ```

    redux-saga

    Download redux-saga and include it in createStore(): ```javascript import { createStore, applyMiddleware } from 'redux' import createSagaMiddleware from 'redux-saga' import rootSaga from './sagas.js'

    const sagaMiddleware = createSagaMiddleware() createStore(rootReducer, initialState, applyMiddleware(sagaMiddleware)) sagaMiddleware.run(rootSaga) ```

    Working with the SDK

    import { getUserDetails, signin, useAnonymousAuth, signout } from './user/userActions'
    
    store.dispatch(signin(username, password))
    store.dispatch(getUserDetails())
    

    Once the above is completed, import Actions and dispatch them easily!

    Review the full API reference for our Vanilla SDK to get started with your back end!

    Examples for React/Redux

    Below are a few examples of Redux code that uses the Back& SDK: - codepen example (thunk) - codepen example (saga) - react-native-example

    Vue.js

    Vue.js is a progressive framework designed to provide an intuitive means by which a front-end developer can build their application. It is designed to be incrementally adaptable, allowing you to use it as often as you like, and provides a lightweight set of tools for adding dynamic functionality to a web app. By providing dynamic backing to the view model, you can easily make a Vue.js-based application into a large and feature-rich web app. In this section, we'll look at how we can use Backand's Vanilla SDK in a Vue.js-based application to provide the backing for that data service.

    Note: This example is also available on Codepen

    Including and Initializing the SDK

    <!-- Include the Back& SDK -->
    <script type="text/javascript" src="https://cdn.backand.net/vanilla-sdk/1.1.2/backand.min.js"></script>
    

    The first step in connecting your Vue.js app to Backand is to import the JavaScript file containing the Backand SDK. You can either do this through a package manager, or via our CDN.

    var myApp = new Vue({
      // Other constructor code here
      beforeMount: () => {
        backand.init && backand.init({
          appName: 'reactnativetodoexample',
          signUpToken: '4c128c04-7193-4eb1-8f19-2b742a2a7bba',
          anonymousToken: '2214c4be-d1b1-4023-bdfd-0d83adab8235'
        });
      },
      // Other constructor code here
    });
    

    Once you've included the SDK, you'll have access to the functionality via the global object backand. You'll next use this to initialize our connection to Backand in the constructor for your app's Vue instance. We recommend putting the initialization in the beforeMount lifecycle hook, but any location or hook that initializes the SDK before it is used should be sufficient:

    With that, the Backand SDK is initialized. This post uses a pre-built demo app, reactnativetodoexample, and its associated keys. If you wish to connect this demo to your own Backand application, simply replace appName, signUpToken, and anonymousToken with the correct values from your Backand application's dashboard. Aside from updating the data model to include the ToDo object, the only thing you will need to do to ensure your app operates in the same way is to add the relevant custom actions when editing a ToDo item (see below).

    Loading the object data

    Next, you need to define a global method that knows how to load the object data from your Backand application. To do this, first define an empty data member to store the future results from the API:

    var myApp = new Vue({
      // Other constructor code here
      data: {
        todos: []
      },
      // beforeMount: () => { ...
    });
    
    

    This data member will hold the list of ToDo items obtained from the server. Next, we'll define a global method to populate this data member:

    var myApp = new Vue({
      // Other constructor code here
      methods: {
        fetchTodos: function() {
          this.todos = [];
          let params = {
            sort: [backand.helpers.sort.create('creationDate', backand.helpers.sort.orders.desc)],
            exclude: backand.helpers.exclude.options.all,
            pageSize: 1000000,
            pageNumber: 1,
          }
          backand.user.getUserDetails().then(res=> {
            if (res.data != null && res.data.userId) {
              params.filter = [backand.helpers.filter.create('user', backand.helpers.filter.operators.relation.in, user.data.userId)];
            }
            return backand.object.getList('todos', params);
          }).then(res=> { this.todos = res.data }).catch(error);
        }
      }
      // Other constructor code here
    });
    

    This function first clears out the todos data member, then defines a set of filter params using helper methods in the SDK (refer to our documentation for more information). Then, it calls backand.user.getUserDetails() to determine if the list should be restricted to the currently logged-in user. Finally, the method calls backand.object.getList() to fetch the list of objects in the SDK, and then updates the todos data container in the promise resolution block.

    Now, you simply need to call fetchTodos() in the appropriate location in the Vue lifecycle. To load the data when mounting is complete, you can add it to the mounted handler like so:

    var myApp = new Vue({
      // Other constructor code here
      mounted: function() {
        this.fetchTodos();
      },
      // Other constructor code here
    });
    

    Creating, Editing, and Deleting Objects

    The following code is a handler for an x-template component titled todo-form, which is used to create a new ToDo entry in the application:

    Vue.component('todo-form', {
      template: '#todo-form',
      data: () => {
        return {
          input: ''
        }
      },
      methods: {
        create: function() {
          // console.log(this.input)
          if (this.input) {
            backand.user.getUserDetails().then(res=> {
              return backand.object.create(objectName, {
                text: this.input,
                creationDate: (new Date()).toISOString(),
                completionDate: null,
                user: res.data.userId
              });
            }).then(res=> this.input = '').catch(error);
          }
        }
      }
    })
    
    

    Once you've got the basic display up and running, you'll want to add methods to create, update, and delete the ToDo items based on user actions.

    Following a similar pattern to the initial load, this code first checks for a user context. If a user is not logged in, this call will have a value of null. Otherwise, we can use the userId of the active user to assign ownership of the new ToDo item. The code then calls backand.object.create() to create the record in your Backand application.

    You can follow a similar pattern when updating an object:

    const todoItem = {
      props: {
        'todo': Object
      },
      template: '#todo-item',
      methods: {
        update: function() {
          backand.object.update(objectName, this.todo.id, Object.assign({}, this.todo, {
            completionDate: this.todo.completionDate ? null : (new Date()).toISOString()
          })).catch(error);
        },
        remove: function() {
          backand.object.remove(objectName, this.todo.id).catch(error);
        }
      }
    };
    

    This function demonstrates how to update a ToDo item's completion date using backand.object.update() - simply provide the object name, the object ID, and the collection of changes to be made. The above method also provides deletion functionality with the remove method. Simply provide the object name and the ID of the ToDo item to delete the entry from your database.

    Keeping the app up-to-date

    First, create the appropriate Custom JavaScript actions in your Backand app's dashboard, and have them emit an event titled "update_todos" as follows:

    socket.emitAll("update_todos", {});
    

    While you now have a fully-functional CRUD interface for the todo object, you have not yet built a way for your application to receive - and respond to - updates. You can accomplish this using Backand's Realtime Communications capability.

    This will send a socket message to all connected clients. At the moment we do not provide any parameters to this call (just an empty object - {}), but you can replace this with any of the variables available to your custom action, such as the dbRow that was just modified.

    First, include the Socket.io library in the appropriate location in your code:

      <script type="text/javascript" src="https://cdn.backand.net/socket.io/1.4.5/socket.io.js"></script>
    

    Now that you have a set of actions designed to announce changes to your ToDo database object, we need to configure the client side to receive socket communications.

    Once that's done, we need to set the SDK to enable socket mode:

    var myApp = new Vue({
      // Other constructor code here
      beforeMount: () => {
        backand.init && backand.init({
          appName: 'reactnativetodoexample',
          signUpToken: '4c128c04-7193-4eb1-8f19-2b742a2a7bba',
          anonymousToken: '2214c4be-d1b1-4023-bdfd-0d83adab8235',
          runSocket: true
        });
      },
      // Other constructor code here
    });
    

    Finally, you need to add an event handler. Update your mounted handler to include the event handler function as follows:

    var myApp = new Vue({
      // Other constructor code here
    
      mounted: function() {
        this.fetchTodos();
        backand.on('update_todos', (data) => {
          this.fetchTodos();
        });
      },
      // Other constructor code here
    });
    

    This function handles all update_todos events the same way - by reloading the entire list from the server. You can use a similar technique to write different handlers for each database operation, or to perform other types of logic based on your application's needs.

    Conclusion

    With the above code, you now have a simple data service that you can use to update your Vue.js app's user interface with results from a Backand application. You can create, update, and delete records at will in a responsive manner, no server code required. With Backand, you can accelerate your Vue.js development, focusing on what makes your app unique, and leave the server side to us.

    jQuery

    JQuery is the most widely-deployed JavaScript library. It provides a comprehensive set of responsive tools for dynamically working with an HTML page's DOM, and is responsible for establishing and guiding a lot of the patterns that are the standard in web development. In this section, we'll look at how you can integrate the Back& Vanilla SDK with an app built with JQuery.

    Note: The code for this section is also available on CodePen

    Including and Initializing the SDK

    <!-- Include the Back& SDK -->
    <script type="text/javascript" src="https://cdn.backand.net/vanilla-sdk/1.1.2/backand.min.js"></script>
    

    The first step in connecting your JQuery-based web app to Backand is to include the JavaScript file containing the Backand SDK. You can either do this through a package manager, or via our CDN.

    Creating the Service

    var dataService = {
      init: function(){
        backand.init(
          {appName: 'reactnativetodoexample',
           signUpToken: '4c128c04-7193-4eb1-8f19-2b742a2a7bba',
           anonymousToken: '2214c4be-d1b1-4023-bdfd-0d83adab8235',
           runSocket: false
          }
        );   
      },
      // Other code here
    };
    

    Once you've included the SDK, you'll have access to the functionality via the global object backand. To integrate Back& with a JQuery-based web app, we'll make use of a global service variable that will wrap the SDK. This service will handle initialization of the sdk, and provide all of the tools necessary to work with a Backand application. We'll start by declaring the service and initializing Backand with the following code:

    This defines an object - dataService - that can be used to interact with the Backand SDK. In the data service, we define a method - init - that is used to initialize the SDK's connection to a Backand application. Simply call dataService.init() at the appropriate location in your app's initialization code, and the SDK is ready to use (in the example, we do this in the $(document).ready handler, but this is not required).

    This content uses a pre-built demo app, reactnativetodoexample, and its associated keys. If you wish to connect this demo to your own Backand application, simply replace appName, signUpToken, and anonymousToken with the correct values from your Backand application's dashboard. Aside from updating the data model to include the ToDo object, the only thing you will need to do to ensure your app operates in the same way is to add the relevant custom actions when editing a ToDo item (see below).

    Fetching and Manipulating the Data

    var dataService = {
      //other code here
      getList: function(){
            var params =  {
              sort: backand.helpers.sort.create('creationDate', backand.helpers.sort.orders.desc),
              exclude: backand.helpers.exclude.options.all,
              pageSize: 10,
              pageNumber: 1,
              filter: backand.helpers.filter.create('completionDate', backand.helpers.filter.operators.date.empty, '')
            };
            return backand.object.getList('todos',params);
      },
      // Other code here
    };
    

    Now that our app is wired up to Backand, we'll want to start writing code to work with our Backand application's objects. We can retrieve a list of todo objects from the server by adding a property to the dataService object, getList, that calls the appropriate SDK method

    This function first defines a set of filter params using helper methods in the SDK (refer to our documentation for more information). It then calls backand.object.getList() to fetch the list of objects in the SDK. The result of this call - a promise - is then passed back to the calling code. The calling code can then create its own success and failure handlers, using .then and .catch, and update internal state appropriately.

    You can use this technique to wrap every call in the Backand SDK, providing your JQuery code with full access to the server.

    var dataService = {
      //other code here
      create:function(text){
        return backand.object.create('todos',
              {"text":text,"creationDate":new Date()});
      },
      // Other code here
    };
    

    From this point onward, working with the SDK is a matter of writing wrapper methods in the dataService object for each SDK method with which you wish to interact. Backand provides interfaces for all of the common database manipulation tasks. For example, the call in the sidebar defines a method - create - that creates a new entry in the database.

    Handling Responses

    var loadList = function(){
      dataService.getList().then(function(response){
    // call a helper function to populate results in our UI
          $.each(response.data, function(i, todo){
            appendTodo(todo.text,todo.id);
          })
       })
    }
    

    All Backand SDK methods return a promise, performing the tasks requested asynchronously. To handle the responses, we simply need to write the appropriate handlers for the .then and .catch calls. In the code to the side, for example, we write a simple set of handlers for the getList call.

    As JQuery is a very flexible framework, it is hard to provide concrete guidance on exactly where SDK should take place in terms of the program's execution. The CodePen example demonstrates one method of creating this component, but you do not need to mimic the code structure there exactly. The key component is to ensure that backand.init() is called prior to any SDK calls taking place, otherwise the calls from the SDK will fail.

    Conclusion

    With the above code, you now have a simple data service that you can use to update your JQuery-based app's user interface with results from a Backand application. You can make full use of the SDK, with the capability to create, update, and delete records at will in a responsive manner, no server code required. With Backand, you can accelerate your JQuery front-end development, focusing on what makes your app unique, and leave the server side to us.

    Common Use cases

    Below are some common use cases for Backand applications

    Convert an older app to our serverless SDK

    Follow the steps below to convert your existing Angular 1 Back& application to our new Serverless SDK, and the associated Angular 1 SDK.

    Step 1: Adding the new SDK to your package manager

    To install the Angular 1 SDK, use the correct command for your dependency management platform:

    Provider Command
    npm $ npm i -S @backand/angular1-sdk
    yarn $ yarn add @backand/angular1-sdk
    bower $ bower install backand-angular1-sdk
    clone/download via Git $ git clone $ git clone https://github.com/backand/angular1-sdk.git

    As a part of this, you'll also want to remove any of the previous SDK includes from the vendor directory (or wherever your package manager stores JavaScript dependencies). Keeping these older versions around can pose problems when sending HTTP requests.

    Step 2: Include the SDK in your project

    Start by deleting any existing Backand includes.

         <script src="lib/angularbknd-sdk/dist/backand.min.js"></script>
    

    Then, include the new SDK links

    <script src="lib/backand-vanilla-sdk/dist/backand.js"></script>
    <script src="lib/backand-angular1-sdk/dist/backand.provider.js"></script>
    

    You can also use our SDK directly via our Content Distribution Network (CDN). Include the CDN links as follows, instead of the local \lib links specified above:

    <script src="//cdn.backand.net/vanilla-sdk/1.0.9/backand.js"></script>
    <script src="//cdn.backand.net/angular1-sdk/1.9.5/backand.provider.js"></script>
    

    The Serverless SDK requires two includes for Angular 1 apps. The first is our Vanilla SDK, and contains all of our core SDK functionality. The second is our Angular 1 SDK, which wraps the Vanilla SDK and provides setup and access to its functionality. Start with removing the old SDK by commenting out - or deleting - any prior includes of older Backand SDKs. Once the older includes have been deleted, replace the dependencies with the new SDK links.

    Step 3: Authentication

    The authentication functionality in the SDK has not changed considerably with the new release. Here are a few notes on authentication elements that may be important to your application:

    Step 4: Update unauthorized user detection

    The getToken() method has been expanded, to use a promise. Originally this method would return undefined when a user was unauthorized, but this functionality can now be managed via the promise method. In the new SDK, the getToken() method is not as prominent as it was in previous versions, and you are likely to not need it as you work on your app.

    Step 5: Use the new SDK methods in place of $http calls

    The Serverless SDK features wrapper methods that can be used in place of the direct HTTP calls used in the previous method. Here's a quick comparison of the old SDK's HTTP communications, as compared to the new function-based Serverless SDK:

    Old Method New Method
    $http.get(getUrl()); Backand.object.getList(objectName);
    $http.get(getUrlForId(id)); Backand.object.getOne(objectName, id);
    $http.post(getUrl(), object); Backand.object.create(objectName, object);
    $http.put(getUrlForId(id), object); Backand.object.update(objectName, object);
    $http.delete(getUrlForId(id)); Backand.object.remove(objectName, id);
    URL built with Backand.getApiUrl() No URL necessary

    Step 6: Update handling of the response object

    Fetching data, old method:

    function getAll() {
     ItemsModel.all()
       .then(function (result) {
         vm.data = result.data.data;
       });
    }
    

    New method of obtaining result data

         vm.data = result.data;
    

    The new sdk does not store the results in a nested data member, but rather in a root data element. The old SDK stored the response contents in a root property, meaning that the actual data was a subset of this data property - hence the use of result.data.data in the old SDK. With the new SDK, you no longer need the extra level of disambiguation, and can store the data in your application's object with the code on the right.

    Conclusion

    In this section, we covered the new SDK. We touched briefly on the features the new SDK has to offer, and walked through the process necessary to convert an existing Backand-powered app to the new API. Most importantly, though, is that we built this SDK based on your feedback, and we want more! Connect with us via social media, or on StackOverflow, or even directly via comments on our Git repos and contacting customer support - we’d love to incorporate your thoughts and suggestions into the next version.

    Setting up and Configuring a database

    Backand users typically fall into one of two categories. The first category works with the underlying data system as a series of objects, and doesn't spend a lot of time focused on the database underpinning the application. The second category, though, work with databases as a matter of course. Often they have existing databases that they want to build an interface on top of, with complex existing relationships that need to be modeled accurately by any framework put in front of it. Below we'll cover the database connectivity functionality offered by Backand, and how it can fit even the most complex of database needs.

    Bringing Your Own Database

    Most back-end-as-a-service providers want you to work within their clearly-defined data roles. They often require you to port your data to their format, or provide only highly static interfaces to interact with and consume existing data. At Backand, we realize that the database is often the core of your business, and you need to be able to work with your data with minimal effort possible. That's why we have built a large suite of functionality around importing – and managing your existing SQL database. Backand can analyze your database structure and build a scaffold around your existing data quickly, allowing your application developers to very rapidly begin working with your existing database structure.

    Importing a Database

    While you can create a new database from scratch using our JSON object modeling interface, the true power of Backand is shown when we integrate seamlessly with your existing database. When you connect your Backand application to an existing database on an external server, Backand quickly analyzes your database structure and constructs a meaningful interface on top of your data. This covers everything from basic table structure all the way up to complex foreign-key relationships and many-to-many mapping tables. Backand then uses this data to construct an API on top of your database, allowing you to interact with your data in a RESTful manner very quickly and easily.

    Staying In Sync

    While an import process is beneficial, it quickly loses its ease if it does not accurately track changes. Many vendors expect your database schema to remain static, and want to work only with your data – requiring a re-sync whenever the database structure changes. With Backand, the need to re-synchronize is completely removed from the process. Backand automatically detects changes to your underlying database and updates its representation of your data, removing a needless tertiary step in the process to ensure that your application remains synchronized with your database's structure. Furthermore, data changes are synced back to the database server nearly instantaneously, ensuring that no matter how you fetch your data it will always be up-to-date.

    Summary

    If you already have a database that you're looking to build into an application, your options for outsourcing the related back end can be limited. With Backand, however, you can bring your own database and import its structure directly. When you link your Backand application with your existing database you always have up-to-date access on both your database's schema and the data itself. By not having to perform awkward data transformations, or re-synchronize every time you make a change to the schema, Backand allows you to focus on the core of your application, keeping your database up-to-date no matter what.

    Using the Back& REST API

    Once your web application's data has been imported and configured, the next step is working with your data. Backand, using your underlying database structure as a key, builds a RESTful API in front of your database, allowing for full programmatic access to each of the HTTP verbs that you would want to use to interact with your server objects. Below we'll cover the concepts behind REST, and how Backand makes creating and testing a RESTful interface simple.

    What is REST?

    REST stands for Representational (RE) State (S) Transfer (T). It is a software architectural style that is designed for the creation of (and interaction with) scalable web services. Most RESTful web services – including Backand's implementation – use HTTP verbs such as GET, POST, PUT, and DELETE, to perform specific actions on the server. The end result is a stateless representation of object interaction, providing a clearly-defined interface to an underlying set of objects in an application. This allows for communication with the server to occur as a series of object changes, reducing the complex server logic needed with other, more stateful architectures.

    Automatically Building an API

    When you import your database into your application, Backand analyzes your database's underlying schema. It uses the database schema itself, along with metadata associated with each of your database's tables and columns, to build a RESTful API that accurately represents the underlying data structure. Not only does it give you API endpoints for each of the common object actions (such as CREATE, RETRIEVE, UPDATE, and DELETE), but it also uses your database's metadata to fully represent the potential ranges of your application's objects, from representing foreign key relationships all the way down to allowing minimum and maximum values on a specific column in a table. It also keeps track of the nullability of each column, marking non-null fields as required parameters in all related API endpoints.

    By automatically providing these endpoints for your database, Backand provides a scalable and understandable API based on web communication standards that would normally take months to develop, and does so within moments of attaching your database. The endpoints follow all defined security roles, and respond with well-formed JSON that pulls in as much – or as little – of your object as you need.

    The REST API Playground

    While a RESTful API is useful, it can also be opaque while the application is being built around it. To get past this nebulous initial state, Backand offers the REST API Playground. The REST API Playground is a dynamic web page built using Swagger 2.0, an automated front-end for well-defined JSON web APIs. It provides information on each of the endpoints defined in your application, and gives you complete access to test these endpoints in an easy-to-use web-based interface. Through this interface you can see every parameter involved in each API endpoint in your application, and quickly test the endpoints using the supplied parameter prompts and descriptions. This tool can greatly increase development speed, as interested parties can simply use the REST API Playground to build out their JSON web requests prior to incorporating them into the application logic.

    Actions and Queries

    Each API endpoint created by Backand also fully integrates with the Action system. You can associate actions with each of the API calls, which simply map to the underlying database actions. POST calls trigger database CREATE actions, PUT calls trigger UPDATE actions, DELETE calls trigger DELETE actions, and so on. Furthermore, the endpoints of each of your custom actions are provided in a helpful "Actions" section, allowing you to test each custom action independently, and with the same useful interface. Finally, endpoints for custom queries that you define in your application are also delineated in the API Playground, allowing for quick iteration on the underlying queries and greatly easing the troubleshooting process.

    Summary

    Interacting with the data in your application is something that is crucial to the success of your product. Through Backand's automatic REST scaffolding, you can quickly and easily get up and running with a scalable web service that can provide developers with access to all of the potential modifications they might need to make to your data. With access to both custom actions and queries, as well as the predefined database triggers you create in the dashboard, Backand's RESTful API offers you the full functionality of a scalable web service – all with the click of a button.

    Configuring Role-based Security

    One of the core concerns of any application that deals with sensitive user and business data is security. In this section we'll cover how Backand handles security for your application, covering the entire stack – from user registration to security templates. We'll also discuss anonymous access to your application, which can greatly enhance your application's adoption by the world at large. Backand takes your application's security seriously, and with the following we'll show you how we protect your data effectively.

    User Registration

    The security process starts with user registration. Backand uses two-factor authentication by default – requiring you to first invite users to your application, then directing them to a registration page that you configure. Backand takes care of the communication, handling the verification (configurable) and registration processes from your customizable sign-up page. This entire process is known as "private" mode, which is the default for all new applications – it requires that users are invited to join the app.

    Once your app is stable and your security is fully configured (or even before if you're confident in your data), you can open your application up to the public. This allows users to sign up to your application directly, without having to be invited. Once they register, Backand sends the user a verification email to ensure that the sign-up is legitimate, if the sign-up email verification setting is enabled.. Once the new user confirms the registration, Backand redirects them to a custom verified email link, representing their successful registration with the system. The user is assigned a default role (see below), and is free to use your app within the permissions framework that you constructed.

    Role-based Security

    Backand uses role-based security to secure access to your application data. This is accomplished by assigning each user in your application a role. Roles have varying permission levels throughout your app, from object-specific restrictions on record modification all the way up to full access to your application's configuration. Each role's permission set is configurable at a macro level as well as at an object level, allowing you true flexibility in securing your application.

    New users created from the admin dashboard are created in the admin role. One of your first steps should be adding an additional security role for new users – whether invited in private mode or registering organically in public mode – that will serve as the default for user sign-ups. Once this default role is set, all new users are assigned the new role automatically. You can then make any permission or access changes you need to from the administrative dashboard.

    Security Templates

    Setting a security level for every single object and user class in your database has the potential to be a tedious, error-prone process. Luckily Backand provides a solution through Security Templates. Security Templates define a default set of security permissions for all of the roles in your application that can then be applied to each of the Create, Read, Update, and Delete actions in your database. Templates can be assigned at both the object and query level, allowing you flexibility in configuring user access to your data.

    Sometimes, though, a blanket approach isn't sufficient for the final functionality of your application. In those cases, Backand allows you to override security templates at a per-role level. This ability gives you more granular control over your application's data, allowing you to grant or revoke access to sensitive components as necessary. Through use of Security Templates and Roles, you will be able to fully secure your application and ensure only authorized users can perform actions against your data.

    Anonymous Access

    In many cases, particularly when working with your application as an API, it is beneficial to grant anonymous access to a specific user. This user can be someone arriving at your site organically, or can be another web service hitting your application's RESTful endpoints. To accommodate these cases, Backand provides anonymous access. This uses token-based authentication to ensure that the anonymous use case is valid and that the user in question is allowed to interact with your app. Furthermore, you can restrict anonymous access to your application based on any of the underlying user roles, ensuring that anonymous uses can only access the elements that you want them to.

    Summary

    Securing your application is a priority task, and crucial to ensuring your application's success. Through Backand's use of two-factor authentication to drive registration, you can be sure that the users coming into your application are a low fraud risk, and that both their experience – and your data – are protected. Additionally, you can secure your app through the use of user roles and security templates, which allow you to quickly and easily manage the permissions in your application. Finally, you can grant some use cases anonymous access to your application, easing integration with third parties and handling organic traffic with ease. With Backand's security offerings, you can rest assured that your application is safe and protected.

    Integrating with Third Party APIs

    In a post originally on Google Plus, Steve Yegge detailed how it was platform development that provided the basis for success of a lot of the major technology companies, using Amazon, Microsoft, and Facebook as examples. However, True platform-based development isn't possible without a mechanism to integrate with those platforms. Below we'll look at the options available to you when developing a Backand-backed web app, detailing which APIs work best at each stage of the application.

    Guidelines on Integrations

    As a general rule, you'll see two overall ideas put forth in this article:

    1. The client side of your application can integrate with any library that is available on the client side. Most commonly, this will consist of JavaScript libraries.
    2. The server side of your application can integrate with any web service that bases its communication off of HTTP web requests.

    Most modern libraries you are likely to consume will fit into one of these two categories, so integration usually shouldn't be a concern. However, some functionality will not be available to you if it relies upon complex server libraries or non-HTTP integrations, such as SOAP web services. As such, it is critically important that you plan your library usage thoroughly, and understand the requirements and auxiliary dependencies of each vendor you choose to integrate with. You can see a few examples of this in action on Backand's GitHub account:

    Client-side Integrations

    As mentioned above, any library available to a client-side web app should be available to your AngularJS app's client-side code. Simply include the required library along with your other dependencies, and you should be able to use the library just as you would in any other application. One potential issue to be faced, though, is that of callbacks. Due to Backand providing the server-side integration for your web app, you will want to create On-Demand Custom Actions to respond to any callbacks sent from the third party you are consuming. Simply create the endpoint, specify the expected parameters, and implement the processing for the delayed notification within the JavaScript action, then provide the URL for that action as your application's callback URL. This approach allows your app to scale more quickly, as the processing load is handled primarily by Backand as opposed to your own servers.

    Server-side Integrations

    Server-side integrations of third party libraries are restricted to those libraries that communicate via HTTP requests. This can mean a RESTful API, or just a series of simple HTTP web services that accept JSON parameters. Any library that can integrate natively with JavaScript code can be implemented in this manner. Take, for example, an integration with Stripe's REST API. While Stripe helpfully provides encapsulating libraries in a number of languages, all of their functionality is available via simple web requests which can be accessed via CURL. These endpoints are ideal for server-side actions, which can use JavaScript's built in AJAX communication functionality to hit the same endpoints. Simply wrap each endpoint in a custom server-side action, then modify your client-side code to call your action wrappers. In this way, you can integrate with any HTTP API.

    While many of these libraries have code that can exist in either the client or the server, the approach above is ideal when security is a consideration. If you're dealing with a customer's sensitive personal info, a client side-based implementation may expose your users to unnecessary risk. By moving these calls to server-side custom actions, you can protect your users' information by encrypting the communications with HTTPS web requests (already provided by Backand), and put the sensitive code behind your application's administrative dashboard.

    Working with Geographic Data

    Backand lets you store geography points as fields as part of any object. A geography point is an array two floats, representing the latitude and longitude of a position on a map.

    With Backand's geography query you can easily find distances between points or objects, within a range from a specific location that you specify.

    Add a Point

    To POST a new data point for latitude 10 and longitude 20 in column geo, you can use the following JSON:

      "geo": [10,20]
    

    To add new point field, open Backand's Model UI (Database --> Model). Find an object to which you wish to add the geometry data, and select Add Field, giving the new field the point data type.

    Query Point

    To get all the restaurants within 25 Miles of San Francisco's Marina District [37.8019859, -122.4414805]:

      {
        "object": "restaurants",
        "q": {
          "location" : { "$withinMiles" : [[37.8019859, -122.4414805], 25] }
        }
      }
    

    The above NoSQL is translated into MySQL syntax using the new ST_Distance() function:

      SELECT * FROM `restaurants` WHERE (ST_Distance ( `restaurants`.`location`, ST_GeomFromText('POINT( 37.8019859 -122.4414805 )') ) <= 25 /(69))
    

    To query a distance within a geography point you can use any of the follow commands: $withinMiles $withinFeet $withinKilometers $within (in meters)

    Query Point with Parameters

    In order to query get geography points dynamically, use Queries with parameters:

    1. Add the following Input Parameters: lan, lon, dist
    2. In the Query use tokens ("{{lan}}", "{{lon}}" and "{{dist}}") to represent the input parameters: 3.

    { "object": "restaurants", "q": { "location" : { "$withinMiles" : [["{{lan}}", "{{lon}}"], "{{dist}}"] } } }

    Filter Point

    Filter all the restaurants within 25 Miles of San Francisco's Marina District [37.8019859, -122.4414805]:

      return $http ({
        method: 'GET',
        url: Backand.getApiUrl() + '/1/objects/restaurants',
        params: {
          filter: {
            "q": {
              "location" : { "$withinMiles" : [[37.8019859, -122.4414805], 25]}
            }
          }
        }
      });
    

    Using a Backand NoSQL filter, you can filter objects based on a distance to a specific point (using the appropriate $within command).

    Bulk Operations

    curl -X POST -d "JSON String of bulk operations" https://api.backand.com/1/bulk
    
    backand.bulk.general(data)
      .then(function(data) {
        console.log(data);
      });
    

    Data is an array of operation objects, which are constructed with the general format below:

    {
      "method": "POST",
      "url": object_path,
      "data": {
        "fieldname": "value"
      },
      "parameters": {
        "param1": "value 1"
      },
      "headers": {
        "Authorization": "Auth header..."
      }
    }
    

    The key element of this operation is the "headers" parameter. This represents the HTTP headers used to perform the request, and are used to uniquely identify your application as each request as made.

      headers:{
        "Authorization": "Bearer **YOUR_ACCESS_TOKEN**",
        "AppName": "**YOUR_APP_NAME**"
      }
    

    The value for YOUR_ACCESS_TOKEN is obtained via a call to https://api.backand.com/token - simply replace YOUR_ACCESS_TOKEN with the bearer token returned by this endpoint, and YOUR_APP_NAME with your application's name that was specified during app creation. Each action hash can accept a different header parameter, allowing multiple operations to be undertaken by multiple users as a part of the same bulk request. If the 'headers' parameter is not included, the headers used for the call to the bulk operations endpoint are used for the relevant action instead.

    Backand's bulk operations endpoint can be used to operate on multiple items in a single request. The request has the general form provided in the right-hand pane. This an array of parameter hashes. Each parameter hash represents a different action to be performed as a part of the bulk operaation. The parameter hashes are broken down as follows:

    Field name Possible Values Required? Description
    method POST/ PUT/ DELETE yes The HTTP verb to be used
    url url for the object yes This is the URL used to access the object being modified in bulk
    data JSON yes (POST and PUT only) This only applies to POST and PUT actions. It represents the data to be created (for POST requests), or the updates to existing data (for PUT requests). Provided as a series of key-value pairs
    parameters JSON no additional parameters, and values for those parameters, to send with the request
    headers JSON no This is used to set custom HTTP headers. You can use it to dynamically set the Authorization header for each REST call. If no value is provided, the generic bulk call authorization headers are used.

    Requests to perform bulk actions are sent as HTTP POST requests to the bulk operations URL: Bulk operations URL: https://api.backand.com/1/bulk. You can also use the SDK to send your operations list to your app.

    Constructing Bulk Requests

    Performing each of the standard non-retrieval CRUD operations in bulk is as simple as specifying the appropriate actions to take with each request. We start by constructing the URL we need in order to manipulate each object. This is done with the Backand SDK using the following code:

    // Backand is the Backand service from the SDK
    var object_path = Backand.defaults.apiUrl
                      + Backand.constants.URLS.objects
                      + "/" + "YOUR_OBJECT_NAME";
    

    Simply replace "YOUR_OBJECT_NAME" with the name of the object you wish to manipulate. Once you have the object URL, you simply need to provide the appropriate command. To create a new record, for example, use the following hash as a starting point:

    {
        "method": "POST",
        "url": object_path,
        "data": {
          "fieldname": "value"
        }
      }
    

    If you wanted to update two records in the same request (using the PUT method), you would send the following:

    [
      {
        "method": "PUT",
        "url": object_url,
        "data": {
          "heading": "Breaking news"
        }
      },
      {
        "method": "PUT",
        "url": object_url,
        "data": {
          "complete": true
        }
      }
    ]
    

    The following request will create two new records (one news article, one author), update an author record, then delete a news record:

    [
      {
        "method": "POST",
        "url": "https://api.backand.com/1/objects/news",
        "data": {
          "heading": "Breaking news",
          "author": 1,
          "complete": false
        }
      },
      {
        "method": "POST",
        "url": "https://api.backand.com/1/objects/authors",
        "data": {
          "email": "ann@backand.com",
          "firstname": "ann"
        }
      },
      {
        "method": "PUT",
        "url": "https://api.backand.com/1/objects/authors/1",
        "data": {
          "firstname": "Brian"
        }
      },
      {
        "method": "DELETE",
        "url": "https://api.backand.com/1/objects/news/3"
      }
    ]
    

    Bulk requests are implemented as arrays of request object hashes.In this hash, we specify the HTTP verb to be used - POST, in this case, which will create a new record. We set the url parameter to the calculated URL from above, and then provide the new record's data as a JSON hash in the data parameter. Simply provide the list of key and value pairs that represent your object's data, and you're set.

    Once you have a single request hash, you can add others by simply appending them to the request.

    You can also mix and match operations, varying the objects updated, the authorization headers used, even the type of request for each record to be updated. There are no restrictions on types of operations that can be performed in a single bulk request, so feel free to mix and match to suit your application's needs.

    Authenticating the Request

    You can authenticate each request as a different user. Simply supply the following elements in the Authorization header: YOUR_ACCESS_TOKEN - an access token, obtained via a call to https://api.backand.com/token YOUR_APP_NAME - the app name to operate on

      {
        "method": "DELETE",
        "url": "https://api.backand.com/1/objects/news/3"
        {
          "Authorization": "Bearer <YOUR_ACCESS_TOKEN>",
          "AppName": "<YOUR_APP_NAME>"
        }
      }
    

    Each request hash can authenticate as a different user within your application. Any valid token to connect to your application can be provided along with each bulk item being manipulated. You can also dynamically specify the app name for each bulk item. To do so, simply use the headers element of the bulk operations structure as seen on the right.

    Refer to our documentation on user security (http://docs.backand.com/#the-user-object-and-security) for more information on how to construct the authentication headers.

    Bulk Request Examples

    Below are several examples of the types of bulk actions that can be performed using this functionality.

    Example 1: Adding multiple rows

    This adds multiple rows in a single request.

    [
      {
        "method": "POST",
        "url": "https://api.backand.com/1/objects/YOUR_OBJECT_NAME",
        "data": {
          "fieldname": "value"
        }
      },
      {
        "method": "POST",
        "url": "https://api.backand.com/1/objects/YOUR_OBJECT_NAME",
        "data": {
          "fieldname": "value"
        }
      }
    ]
    

    You simply change the URL and data hashes for each record. Here's a sample request that adds two new news items to an application:

    [
      {
        "method": "POST",
        "url": "https://api.backand.com/1/objects/news",
        "data": {
          "heading": "Breaking news",
          "author": 1,
          "complete": false
        }
      },
      {
        "method": "POST",
        "url": "https://api.backand.com/1/objects/news",
        "data": {
          "heading": "Politics",
          "author": 2,
          "complete": true
        }
      }
    ]
    
    

    As you can see above, this bulk operation will add two new objects of type 'news' to your application. The first will have the heading of "Breaking News", while the second will have the heading of "Politics".

    To add multiple objects to your application, simply provide multiple POST action hashes in your request's data array. The general form of the request is in the pane on the right. Simply change the 'url' parameter of each action hash to match your object's endpoint in your application.

    Example 2: Deleting multiple rows

    The general form of the delete request will be:

    [
      {
        "method": "DELETE",
        "url": "https://api.backand.com/1/objects/YOUR_OBJECT_NAME/OBJECT_ID1"
      },
      {
        "method": "DELETE",
        "url": "https://api.backand.com/1/objects/YOUR_OBJECT_NAME/OBJECT_ID2"
      }
    ]
    

    For example, if you wanted to delete 'news' objects with IDs of 2 and 3, you would use the following set of action hashes:

    [
        {
            "method":"DELETE",
            "url":"https://api.backand.com/1/objects/news/2"
        },
        {
            "method":"DELETE",
            "url":"https://api.backand.com/1/objects/news/3"
        }
    ]
    

    To delete multiple objects from your application, simply provide multiple DELETE action hashes in your request's data array. By changing the YOUR_OBJECT_NAME and OBJECT_ID parameters, you can select which specific IDs will be deleted in your application.

    Example 3: Multiple commands

    [
      {
        "method": "POST",
        "url": "https://api.backand.com/1/objects/news",
        "data": {
          "heading": "Breaking news",
          "author": 1,
          "complete": false
        }
      },
      {
        "method": "POST",
        "url": "https://api.backand.com/1/objects/authors",
        "data": {
          "email": "ann@backand.com",
          "firstname": "ann"
        }
      },
      {
        "method": "PUT",
        "url": "https://api.backand.com/1/objects/authors/1",
        "data": {
          "firstname": "Brian"
        }
      },
      {
        "method": "DELETE",
        "url": "https://api.backand.com/1/objects/news/3"
      }
    ]
    
    

    You can mix and match operations to be performed to match whatever actions you need to take. For example, the action hashes on the right will create a new news object, create a new authors object, update an existing authors object with an ID of 1, and delete a news object with an ID of 3.

    Retrieving Data

    Seeing as most objects in a Backand application tend to be complex objects, we added an easy way to enable deep loading of objects. Simply append '?deep=true' to the object fetch URL, like so.

    curl https://api.backand.com/1/objects/users/5?deep=true
    

    An example of another complex object would be 'email'. Requesting a user using the deep parameter would result in JSON resembling the following:

    {
      "email":"....",
      // other users fields...
      "items":[{"title":"....",...},...]
    }
    

    It takes two requests to perform a Lazy Load. The first request is a shallow request for users or a specific user.

    curl https://api.backand.com/1/objects/users
    #or
    curl https://api.backand.com/1/objects/users/5
    

    The second request is for all the items of a specific user.

    curl https://api.backand.com/1/objects/users/5/items
    

    This request is similar to fetching the entire list of items, which would be done as follows:

    curl https://api.backand.com/1/objects/items
    

    You can also supply other query string parameters (such as paging, filtering, and sorting). See the getList function for more details.

    A Complex object is an object that has relationships to other objects in the database. For example, the default model provided when you create a new Backand application has two objects: users and items. There is a one-to-many relationship between users and items, meaning that a specific user may have many different related items. In this example, both users and items are complex objects. The relationship between the two tables, represented as the User object having a collection of Item objects, can be retrieved from the database by loading them through the object's API.

    There are two ways in which you can load complex objects: Deep Loading, or Lazy Loading. Deep loading pulls back both the object and all of its related objects. In the Users/Items example, this would pull back both the user, and all items related to that user. Lazy loading, by comparison, only pulls back the parent object, allowing you to more closely control when you pull in the rest of the data. This is important when the number of related objects is large, meaning a significant load time would be necessary.

    Regarding which approach to use - lazy or deep loading - there is no clear answer. It will be dependent upon the individual programming situation. If you need to present all of the relevant data at once, then deep loading is the right approach. However, if the object has a large number of relations to pull down, it might make more sense to do a lazy load, then selectively load related objects as needed.

    Filter and Predefined Filter

    This JSON provides a fieldName, an operator, and a value to define a filter. Apply multiple fields by appending to the JSON array.

    [{"fieldName":"firstName","operator":"contains","value":"oh"}]
    

    You can supply a query string parameter named 'filter' to filter your objects during fetch. This could be useful in development and debugging situations, or as a part of a UI with search functionality that allowing your users to see configurable results. You can either create a filter with NoSQL syntax (see NoSQL Query Language for syntax), or with JSON containing a field name, an operator, and a value. See the getList function for full details on filters.

    Predefined Filter

    For security reasons, you may sometimes want to enforce partial reading of object data - usually based upon the current user or their role. This can be accomplished on the server-side using a Predefined Filter. Predefined Filters can be found in the Security tab of each object. They act as a SQL where condition. The option to force it from the server side is called Predefined Filter and you can find it at the Security tab of each object. If you add any additional filters, such as those described above, then they will be combined using a boolean AND operation. You can write the predefined filter either as a SQL statement or as a NoSQL Query Language statement.

    Queries and On Demand Actions

    So far we have discussed how to read objects that were defined in the database model. To create custom data structures, we can use Queries and On Demand Actions. Queries are identical to SQL database queries but you can write them using NoSQL syntax (see NoSQL Query Language for more details). With On Demand Actions, you can orchestrate any structure that you want using javascript on the server side. You can request model objects, queries, or other on demand actions. See On Demand Actions - Server-Side Javascript Code for more information.

    Pagination

                SET @records := 20;
                PREPARE stmt FROM
                " SELECT    *
                  FROM      Users
                  LIMIT     ?, ?";
                -- {{ "{{pageNum" }}}} is the client side parameter representing the requested page number
                SET @offset := @records * ({{ "{{pageNum" }}}} -1 );
                EXECUTE stmt USING @offset,@records;
    

    The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments (number of records and offset), which must both be nonnegative integer constants. We can compute the constants either on JavaScript action or by using a prepared statement like that on the right

    Continuous Deployment and Versioning

    A common use case is separate development and production environments, often with several stages in between (testing, qa, staging), which allows phased deployment (rollout) and rollback in case of problems.The goal of Continuous Deployment is to enable a constant flow of changes from development to production.

    The following explains the flow of deploying server-side and databases changes from one environment to the other.

    Deployment Steps

    1. First, you need to sync model changes
      1. Go to your dev app and copy the JSON model ( Database --> Model --> Model JSON ) to the clipboard
      2. Go to your QA app and paste the JSON model in the Edit Model pane of the Database --> Model --> Model JSON tab.
      3. Click 'Validate & Update'

    Now the schemas are synced.

    (If you get errors when applying the schema to the QA app, you'll need to fix them before you can upload the dev configuration)

    1. Next, you need to load the dev app configuration into the QA environment
      1. Go to Admin --> App Configuration
      2. Click the 'Export Settings' button, which will download the app configuration zip file to your file system.
      3. In the QA app, go to Admin --> App Configuration and click the 'Import Settings' button to upload the configuration zip file you just downloaded from the dev app.
      4. In Admin --> General,x click the 'Clear Cache' icon in the upper-right corner (swirly arrow refresh icon near the trashcan icon - see the image below), and approve the popup message. image

    The QA app is now deployed with all the changes you made in the dev app.

    Apply this process again when deploying QA to Production.

    Versions

    With every change you make to your app, Backand saves a copy (version) of the app before the change. You can use this feature to rollback your configuration changes, if needed.

    To rollback to a previous version:

    1. Go to Admin --> App Configuration
    2. Click the Set link corresponding to the version to which you wish to roll back.

    To save a backup of a version just click the Export link. This will save a backup of the app configuration to your file system.

    Internationalization

    For the following scripts you'll need your schema_name you can find it here : https://www.backand.com/#/app//database

    ALTER SCHEMA `<YOUR_SCHEMA_NAME>`  DEFAULT CHARACTER SET utf8;
    

    On the table where you want to use multi-byte languages run:

    ALTER TABLE `<YOUR_SCHEMA_NAME>`.`<YOUR_TABLE_NAME>` CONVERT TO CHARACTER SET utf8;
    

    On each VARCHAR column on that table run:

    ALTER TABLE `<YOUR_SCHEMA_NAME>`.`<YOUR_TABLE_NAME>` MODIFY COLUMN col VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci;
    

    Supporting multiple languages often requires supporting multi-byte character sets. In order to allow for wider international character sets, you will need to run the MySQL command to the right against your database.

    Once you've done this, the final step is to edit the connection details:

    1. Go to Database --> Database Settings
    2. Click Get Password and save it to the clipboard
    3. If you don't see the Edit Connection button then add "/edit" to the browser url
    4. On the username text box, add ;CharSet=utf8;
    5. Paste the password from the clipboard
    6. Click Save

    Integrating with Ionic Creator

    Ionic Creator is an online IDE for Ionic apps that can greatly speed the development of your cross-platform mobile and web application. However, like any IDE, it can pose problems when integrating with some external service providers like Backand. Below, we’ll look at the steps needed to get your Ionic Creator app up and running with the Backand SDK, allowing you to implement serverless apps in the Ionic framework with ease.

    Configuring the connection to Backand

    angular.module('app.config', [])
    // remember to add 'app.config' to your angular modules in Code Settings
    
    .config(function(BackandProvider) {
    
        BackandProvider.setAppName('BACKAND_APP_NAME');
        BackandProvider.setSignUpToken('BACKAND_API_SIGNUP_TOKEN');
        BackandProvider.setAnonymousToken('BACKAND_ANONYMOUS_ACCESS_TOKEN');
    
    })
    

    To Enable Back with Ionic Creator, you’ll need to update your Ionic Creator app’s Other JS section to include a new file name - bkndconfig.js. In this file, replace the entire contents with the javascript code to the right.

    Once the code has been modified, replace the placeholder values in the code with the appropriate values from your Backand application as follows:

    Once these changes have been made, you'll then need to update your Ionic application's code settings.

    Code Settings

    https://cdn.backand.net/vanilla-sdk/1.1.0/backand.js
    https://cdn.backand.net/angular1-sdk/1.9.6/backand.provider.js
    

    Once you've finished, the External JS tab will have the following content:

    <script src='https://cdn.backand.net/vanilla-sdk/1.1.0/backand.js'></script>
    <script src='https://cdn.backand.net/angular1-sdk/1.9.6/backand.provider.js'></script>
    <script src='js/directives.js'></script>
    <script src='js/services.js'></script>
    <script src='js/bkndconfig.js'></script>
    

    Then, update Angular Modules

    angular.module('app', [
    'ionic',
    'app.controllers',
    'ionicUIRouter',
    'backand',
    'app.config',
    'app.services',
    'app.directives'
    ])
    

    Now, we need to update your Ionic app's Code Settings so that we can import the Backand SDK. In Code Settings, under the External JS tab, add the script URLs to the right.

    Then, under Angular Modules, add backand and app.config. The end result is visible in the right-hand pane.

    Working with the Backand provider

    .service('ItemsModel', function(Backand){
    
        var service = this;
        var objectName = 'items';
    
        service.all = function () {
            return Backand.object.getList(objectName);
        };
    
    });
    

    Now that the external code has been configured, you can start working with the Backand provider in your service class. For example, you can use the code on the right to pull rows from an items object in a Backand application. Next, we'll add this function call into a page for display.

    Updating the Page Controller

    $scope.getAll = function() {
        ItemsModel.all()
            .then(function (result) {
                console.log(result.data);
                $scope.data = result.data;
            });
    }
    
    $scope.getAll();
    

    To access this data, we'll update the page controller to call our ItemsModel and return the relevant rows. To do so, use the JavaScript to the right to define a getAll() function and store the results in $scope.

    Now, we'll need to update the page's design to display the new information. To show a list of all the items you've obtained:

    And with that, your Ionic Creator app is now connected to Backand!

    Learning more

    At this point, you have the full power of the Backand SDK available in your Ionic Creator app. You can use the SDK to add more services to your app, providing CRUD functionality, real-time communications, server-side code execution, and more! Simply head over to our documentation to get started.

    Working with Custom Actions

    Actions are a powerful tool that allow you to perform customized tasks when a number of different types of events occur within your application. They provide a great alternative to server-side custom code, and can add a lot of flexibility to how your application interacts with outside services. Below we're going to look at the types of actions that Backand offers application developers, and how they can easily be used.

    Server-Side Activity in a Front-End App

    One of the challenges facing Angular developers focused on front-end development is what you need to do when you hit the limits of what the front-end has to offer. Many calls that you might like to make from your JavaScript might expose security issues, such as specific formats for requests to external vendors like PayPal, that leave you vulnerable to hackers who are looking for any way to hijack your application. The traditional solution to this has been to move the calls themselves server-side, which is a lot harder to gain access to than the JavaScript code running your website. However, having custom server actions requires building up the surrounding infrastructure to handle web requests, trigger the actions, handle the responses, and perform authentication – among a number of other actions you need to control for – all just to send a single server-side call.

    With Backand's server-side actions, you completely sidestep the need for all of the setup, implementation, and deployment headaches you would have with a custom server-side framework like Rails or Django. It allows you to do things that would typically demand custom server code – such as authenticating with a third party vendor, or sending sensitive payment data – without having to build the server infrastructure. By providing simple hooks into Backand's API for your back end, you can quickly add new actions that can do anything from sending a simple email all the way up to running custom JavaScript that can perform any arbitrary action you like – all behind the server-side call to Backand!

    Triggers

    Actions are activated via triggers in your application. Generally speaking, there are two types of action triggers in Backand – database-related triggers, and "On Demand" triggers. Database triggers fire under certain conditions when your application interacts with your database. You can add custom triggers to each of the standard database actions that update the database – record creation (Create), record updating (Update), and record deletion (Delete). Furthermore, you can assign your actions to occur either before the action takes place (such as Before Update), while the action is taking place as part of the same transaction (such as During Create), or after the action has completed (such as After Deletion). Through clever use of these actions, you can create a very complex database experience with a deceptively simple front-end.

    On Demand triggers, on the other hand, happen whenever you like. These are associated with a specific object, and are performed in the context of a row via a simple call to an associated URL. These actions operate within the context of the provided row, allowing you to perform any custom actions you need to on that specific object. This allows you to build out a true API, providing the hooks for many custom server actions that would often need a framework surrounding them.

    Types of Actions

    Once you've selected an appropriate trigger, you need to select a type of action to perform. Backand currently offers three types of actions – Send an Email, Execute Custom JavaScript, and Execute Custom SQL. Send an Email, as the name implies, simply sends an email whenever the trigger in question occurs. You can use the subject of the trigger as a local variable, inserting details into the message as you desire. Execute Custom JavaScript allows you to write a custom JavaScript function that will execute during the trigger, all within a server context. This allows you to perform sensitive communication without exposing vital details to potential attackers. Finally, Execute Custom SQL allows you to run a custom SQL script when the trigger is encountered, performing additional bookkeeping or updating related objects based upon the action performed. With these three action types, you should be able to perform many highly complex interactions without needing to worry about maintaining a back-end server to manage them.

    Summary

    One of the common concerns with outsourcing the back end of an application is "What happens when I need something more from the server?" With Backand's actions, you have the opportunity to perform a number of different types of actions at several highly-configurable trigger points, and all in the context of your application's server! This can allow you to implement sensitive web calls to third parties, maintain complex analytics back-ends, and protect your sensitive data from attackers – all with a few clicks in Backand's application dashboard. While actions are not ideal for all situations, they should suffice for the vast majority of server-side activity that web apps most commonly need.

    Connecting to Your App's Database

    While the schema editor offered by Backand's app dashboard can be a powerful tool for managing your application's data schema, sometimes there are ideas that the schema editor can't express. For these situations, it's often best to revert to a SQL interface, either using command-line SQL or a dedicated database administration tool like MySQL Workbench. In this post, we'll look at how you can access your Backand application's database using any third-party MySQL compatible database tool you desire, and how you can sync the changes with your Backand application once you've made your changes.

    Connecting to Your Database

    Backand hosts all application databases as schemas in Amazon RDS. The benefit of this approach is that it easily allows us to make your database available to any third-party tool you like. In the Backand App Dashboard, you can find your application's database server information in the Database -> Database Settings panel. This contains the host URL, username, password, and schema name for your application. Simply input these connection values into your database administration tool of choice, and you are free to make changes to your database schema.

    Synchronizing Changes

    Once you've made the necessary changes in your schema, you'll need to synchronize the changes with your Backand application. This is accomplished in the Backand Application Dashboard as follows:

    Once you've pressed the Sync button, Backand will use reflection to determine your database's structure, and rebuild your app's REST API according to the changes it sees.

    Moving Forward

    With this approach, you can greatly increase your data model's flexibility. By working with standard SQL queries, you can bypass the need for making complex changes to your application's data structure using only the provided editors. Anything that can be expressed in SQL is permitted, and Backand will automatically adapt to your database structure modifications.

    Working with Encrypted passwords

    One common case encountered when storing passwords is in how to manage password encryption - particularly for working with third parties. In this section, we'll explore encrypting a user's password, and comparing encrypted passwords with their plaintext equivalents to check for authorization.

    Encrypting Passwords

    To work with encrypted passwords in Backand, follow these steps:

    1. Create a password field in your users object, of type text
    2. Modify or create a "before create" action for the users object, and set the type to Custom Server-Side JavaScript.
    3. Add userInput.password = security.hash(userInput.password); to encrypt the password

    With that, your encrypted password is now stored along with your users object.

    Comparing Encrypted passwords

    Once you've encrypted your password, you'll want to use it for password validation. To do so, you can use the security.compare function: return security,compare(password, hashedPassword);.

    This method returns true if the provided password is valid. It utilizes one-way encryption, so that it is not possible to decrypt the password hash

    Using UUID Primary Keys

    While integer IDs can provide a quick and easy way to get up and running with a primary key, they face a number of different challenges when it comes to both scaling and security:

    Universally-Unique IDentifiers, or UUIDs, solve many of these problems. They obfuscate the ID so that it is not brute-force guessable, they have an extremely wide range of potential values, and the risk of collisions in UUIDs is miniscule. In this section, we'll look at configuring a Backand object to use a UUID as its primary key.

    Setting up the Database

    To create a UUID primary key column, you'll need to operate within your database directly. Download a tool to connect to your database (like MySQL Workbench), and configure it with the connection settings from your application's dashboard. Once you've connected your database, you'll next want to create a new field in the object you are changing, using the datatype char(36). Once this is done, sync the changes back to your application using the Object -> Model -> Model Database tab in the app dashboard.

    Setting up the Before Create action

    /* globals
      $http - Service for AJAX calls
      CONSTS - CONSTS.apiUrl for Backands API URL
      Config - Global Configuration
      socket - Send realtime database communication
      files - file handler, performs upload and delete of files
      request - the current http request
    */
    'use strict';
    function backandCallback(userInput, dbRow, parameters, userProfile) {
      // write your code here
      userInput.id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
          var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
          return v.toString(16);
      });
      return {};
    }
    

    We'll override the default integer-based behavior in a Custom Server-Side JavaScript action that we will create expressly for this purpose. The code to the right uses Math.random() to generate a UUID Version 4-compliant value. This value is then stored in userInput.id, which in turn populates the column in the database.

    Integrating Third-Party Security

    While Backand provides a set of robust and dependable authentication and user management tools, sometimes you need a deeper integration with a provider that is not directly supported via integration with the Backand platform. In this post, we'll look at three mechanisms you can use to implement robust user security integrations with arbitrary third-party platforms. By using the backandAuthOverride, sociaAuthOverride, and accessFilter security actions, you'll be able to achieve all of your user security goals.

    A Quick Review of User Security

    There are two questions that need to be resolved in any conversation - user authentication, in which we determine whether or not the user is who they claim to be, and user authorization, in which we determine whether or not the authenticated user has access to the resources they are requesting. Backand uses OAuth2 to manage user authentication for plain username/password logins, and social media providers to manage user authentication when configured. To manage authorization, Backand provides a flexible and powerful set of security templates and security roles, which can be used to control the access a user has to any given field in a Backand application.

    Overriding Backand Authentication

    While we offer a number of ways to integrate with third-party security providers, some applications need to work within systems that we either do not offer integrations with, or whose integrations are not feature-rich enough to support all of the needed functionality. To work around this, we provide the backandAuthOverride security action. By modifying this action, you can use it to authenticate the user with any third party authentication platform you desire. You're given the user's email address and password, and can respond with one of three statuses:

    If this method returns "ignore", the standard Backand user authentication is used. Otherwise, the results of this function are adopted by Backand. If you wish, you can use the provided additionalTokenInfo object to pass back supplementary information for the authentication result, such as system user ID, system role, authentication lifetime, and so on - these will be available with the return value from the signin method, or via the SDK method getUserDetails.

    Overriding Social Media Authentication

    While you can use backandAuthOverride to integrate with most third-party authentication providers, if you're working with our social media authentication you'll need to use a different function - socialAuthOverride. This function, similar to backandAuthOverride, overrides the social media authentication experience, returning one of the following three values:

    Once again, if this method returns ignore, the default built-in social media authentication provided by Backand is used. Otherwise, the return value of this function - either allow or deny - coupled with the contents of additionalTokenInfo are returned to the caller, and the user is either authenticated or prevented access appropriately. You can use this pattern to, for example, obtain a user's Facebook profile picture upon completion of authentication, and pass the results back to the application for display or manipulation.

    Overriding Authorization

    Once you've authenticated the user, you'll need to determine whether they are authorized to access the specified resource. While our security roles and templates can cover a lot of functionality, they are by nature restricted to a single app. If you organization's security policy restricts app access to users with a specific flag in your authentication mechanism, you'll want to override basic Backand authorization to instead leverage your external solution. To do this, you can use the accessFilter method to dynamically approve or deny any users that authenticate with your system using an Oauth2 token.

    This method works like any other custom JavaScript action, allowing you to easily contact third party services for additional user information. Once you've used this feature to determine whether or not a user is authorized, you simply return allow or deny to permit or restrict access appropriately. You can also provide an additional message explaining the denial, or providing additional information on the approval.

    Conclusion

    The security landscape for internet apps is wide and varied. While we'd love to be able to support every possible method of authentication available to developers, after a while it is far more beneficial and flexible to provide the developer with tools to manage their own authentication integrations. Using our provided override functions - backandAuthOverride, socialAuthOverride, and accessFilter - you can integrate with any authentication or authorization provider that can communicate over the web.

    Managing the Application Model with JSON

    Below is an example model

    [
      {
        "name": "items",
        "fields": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "text"
          },
          "user": {
            "object": "users"
          }
        }
      },
      {
        "name": "users",
        "fields": {
          "email": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "items": {
            "collection": "items",
            "via": "user"
          }
        }
      }
    ]
    

    The Model JSON tab in the Database --> Model menu allows you to modify the JSON schema of your database's model structure, adding new objects and establishing the relationship between them. Below is a brief overview of how to use this interface.

    Definitions

    The model represents a database schema that is defined as a JSON array of one or more object (Table) definitions.

    <model> = [  <object>, <object>, ... ]
    

    An object definition is a JSON object with a name entry and a fields entry:

    <object> = { "name":  <string>, "fields" : <fields> }
    

    The fields definition is a JSON list of field attributes:

    <fields> =  { "field1" : <field>, "field2": <field>, ... }
    

    A field is defined by its type and a set of optional properties. The field definition is a JSON object:

    <field> = { "type": <type>, <optional properties>}
    

    A JSON schema consist of three types of objects:

    A field may have one of the following types:

    One-to-Many Relationship

    As an example, consider a model describing pet ownership. It has two objects, 'users' and 'pets'. Each user can own several pets, but a pet has a single owner (user). Thus, the users-pets relationship is a one to many relationship between users and pets, The 'users' object will have a 'pets' relationship field, which establishes the 'many' side of the relationship by creating a collection of pets objects for each user in the model. In 'users', add this field:

    "pets": { "collection": "pets", "via": "owner" }
    

    The 'pets' object will have an 'owner' relationship field, which establishes the 'one' side of the relationship by linking each pet back to an individual owner. In 'pets', add the following new field to complete the linkage:

    "owner": { "object": "users" }
    

    Here is the full sample model for this relationship:

    [
      {
        "name": "pets",
        "fields": {
          "name": {
            "type": "string"
          },
          "owner": {
            "object": "users"
          }
        }
      },
      {
        "name": "users",
        "fields": {
          "email": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "pets": {
            "collection": "pets",
            "via": "owner"
          }
        }
      }
    ]
    

    Many databases rely on one-to-many relationships between objects. These happen when an object can exert "ownership" over another, and is typically represented as a foreign key constraint in the "owned" object. The sidebar demonstrates how to create a one-to-many relationship in the database using the JSON Schema.

    Say, for example, that we have a one to many relationship between objects R and S. This means that for each row in R, there are many potentially corresponding rows in S. In the 'many' side of the relationship (object S), we specify that each row relates to one row in the other object R by providing an object field link:

    "myR" : { "object" : "R" }

    In the 'one' side of the relationship (object R), we specify that each row relates to several rows in S by providing a collection field link, using a 'via' attribute to denote which field on the 'many' side (object S) fulfills the relationship:

    "Rs" : { "collection": "S", "via" : "myR" }

    In the database, a foreign-key constraint will be added between tables S and R (pointing in the direction of R), represented by a foreign key field 'myR' being created in the object S's data table. This field will hold the primary key of the corresponding row in R for each row in S. One-to-many relationship between objects are specified using relationship fields. A relationship field will generate the appropriate foreign-key relationship fields in the corresponding relation objects.

    Many-to-Many Relationship

    As an example, consider a different model describing pet ownership. It has two objects, 'users' and 'pets'. Each user can own several pets, and each pet can have several owners. Thus, the users-pets relationship is many to many relationship between users and pets: First we need to add a new object - 'users-pets' - with one-to-many relationships to both 'pets' and 'users' objects. In 'users-pets':

    "pet": { "object": "pets" }
    "owner": { "object": "users" }
    

    In the corresponding objects 'users' and 'pets', we need to add a reference to 'users-pets' to complete the one-to-many relationship: In 'pets':

    "owners": {"collection": "users-pets", "via": "pet"}
    

    In 'users':

    "pets": {"collection": "users-pets", "via": "owner"}
    

    Stated another way: To build a many-to-many model of many-to-many Model: * Start with a Model that contains 2 objects that have no relations between them:

    [
      {
        "name": "pets",
        "fields": {
          "name": {
            "type": "string"
          }
        }
      },
      {
        "name": "users",
        "fields": {
          "email": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          }
        }
      }
    ]
    

    Add the new object and the relationship fields:

    [
      {
        "name": "pets",
        "fields": {
          "name": {
            "type": "string"
          },
          "owners": {
            "collection": "users-pets",
            "via": "pet"
          }
        }
      },
      {
        "name": "users-pets",
        "fields": {
          "pet": {
            "object": "pets"
          },
          "owner": {
            "object": "users"
          }
        }
      },
      {
        "name": "users",
        "fields": {
          "email": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "pets": {
            "collection": "users-pets",
            "via": "owner"
          }
        }
      }
    ]
    

    Many-to-Many relationships between objects are added by adding a new object that has a one-to-many relationship with each object participating in the many-to-many relation. Please review One-to-many relationships before continuing with this section.

    Say, for example, that we have a many to many relationship between objects R and S. This means that for many rows in R, there are many potentially corresponding rows in S. Where we could handle a one-to-many relationship between R and S using a single column in the underlying database, we can't do so to represent a many-to-many relationship. If we simply add another foreign key to the other side of the relation, we are stuck having to duplicate items that are shared among multiple owners. Instead, we use a mapping table to link the two objects together.

    {"name": "R_TO_S_MAPPING", "fields": { "r": {"object":"R"}}, "s": {"object":"S"} }

    The mapping table will have two columns - r_id, and s_id - that are then linked to by the source tables via separate one-to-many relationships between the objects themselves and the mapping table. More specifically: S will have a one-to-many relationship with R_TO_S_MAPPING:

    {"name": "R", "fields": {...., "S": { "collection": "R_TO_S_MAPPING", "via":"r"}}}

    ... and R will also have a one-to-many relationship with R_TO_S_MAPPING

    {"name": "S", "fields": {...., "R": { "collection": "R_TO_S_MAPPING", "via":"s"}}}

    ... resulting in a many-to-many relationship between R and S with the relationship managed via table R_TO_S_MAPPING.

    Enabling SMS-based Authentication

    Using Backand's security actions and a service like Twilio, you can implement a token-based authentication system that uses SMS as the delivery method, giving your users the capability to authenticate with a code received via a SMS message on a mobile device.

    Process overview

    The process we'll follow to authenticate the user in our SMS-based system is as follows:

    1. Call an on-demand action that creates a Token object. The Token object contains a token number, and a session ID. The token number is sent to the provided phone number via SMS, while the session ID is sent back to the caller.
    2. Call backand's /token API with a username (any username is acceptable), the SMS code, and the session ID sent back as a result of step 1. WE'll use a security action to verify the provided token data, and flag the token as "used" to remove it from active status.
    3. Restrict the token object to only be accessible by Admin users, to prevent malicious third-party intrusions.

    For multiple device authentication, you can use the same process - even keeping the same username. See an example of the code at work in CodePen: http://codepen.io/backand/pen/GZdYgy

    Creating the Token object

    {
      "name": "tokens",
      "fields": {
        "token": {
          "type": "string",
          "required": true
        },
        "sessionId": {
          "type": "string",
          "required": true,
          "unique": true
        },
        "used": {
          "type": "boolean",
          "defaultValue": false
        }
      }
    }
    

    The JSON to create a token object is provided to the right. This consists of three columns:

    Adding the sendToken action

    //sendToken action
    // Required parameters (to be stored in the 'parameters' object): phone
    'use strict';
    function backandCallback(userInput, dbRow, parameters, userProfile) {
        // When in debug mode, don't send SMS messages
        var debug = false;
    
        // Creates a random number to serve as the Token value
        var randomNums = function(length) {
            return Math.random().toString().slice(2,length+2);
        }
        // Creates a random string to serve as the session ID.
        // Replace with a GUID function if you wish to avoid collisions.
        var randomText = function (length) {
            if (!length) length = 10;
            return Math.random().toString(36).slice(2,length);
          }
    
        // These are used to construct basic authentication. The first value is
        // the master token for your app. The second value is a user's user token.
        // See the docs at http://docs.backand.com/#basic-authentication for more
        // information on this method of authentication
        var master_key = 'f8929838-2a2e-4818-a47e-2080ad62fc00';
        var user_key = 'f9d89228-0336-11e6-b112-0ed7053426cb';
    
        // Get a session ID and a token
        var sessionId = randomText(32);
        var token = randomNums(6);
    
        // Store the new token in the database using an API call
        var response = $http({
            method: "POST",
            url:CONSTS.apiUrl + "/1/objects/tokens",
            data: {
                token: token,
                sessionId: sesstionId
            },
            headers:{'Authorization':'basic ' + btoa (master_key + ':'+ user_key) }
        });
    
        // From this point onward, we construct and send an SMS message to the user
        var ACCOUNT_SID = 'YOUR TWILIO ACCOUNT SID';
        var AUTH_TOKEN = 'YOUR TWILIO AUTH TOKEN';
    
        var FROM_PHONE_NUM = 'YOUR TWILIO NUMBER';
    
        // Construct the endpoint in Twilio's API
        var basicUrl = 'https://api.twilio.com/2010-04-01/Accounts/' + ACCOUNT_SID + '/';
        var action = 'Messages.json' // twilio have many services
    
        // Only send SMS messages when we are not debugging
        if(!debug){
            // Send the request to Twilio for processing.
            var t1 = $http({
                method: "POST",
                url: basicUrl + action,
                data:
                    'Body=' + 'Your verification code is: ' + token +
                    '&To='  + '%2B' + parameters.phone +
                    '&From='+ FROM_PHONE_NUM,
                headers: {
                    "Accept":"Accept:application/json",
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Authorization": 'basic ' + btoa(ACCOUNT_SID + ':' + AUTH_TOKEN)
                }
            });
        }
    
        //Return the Guid
          return {"sessionId": sessionId};
    }
    

    To generate the token data for each authentication attempt, we'll use an on-demand server side JavaScript action. As all actions require an owning object, we'll attach this action to the items object in the database. While it would make more sense to link this action to the token object, the token object will have other security restrictions that will interfere with calling this action prior to authentication. So while we have chosen the items object, it can apply to any object in your system accessible to anonymous users.

    Use the JavaScript to the right as the body of the action code.

    Updating the security action to allow for authentication

    // backandAuthOverride action
    // Required parameters (in the parameters object): token, sessionId
    'use strict';
    function backandCallback(userInput, dbRow, parameters, userProfile) {
    
        //Example for SSO in OAuth 2.0 standard
        // Get the token and session ID from the parameters
        var token = parameters.token;
        var sessionId = parameters.sessionId;
    
        // If you're debugging this on the command line, you'll want to throw a new
        // Error with the session ID
        //throw new Error(sessionId);
    
        //Check if token exists and not in use
        var master_key = 'f8929838-2a2e-4818-a47e-2080ad62fc00';
        var user_key = 'f9d89228-0336-11e6-b112-0ed7053426cb';
    
        var res = $http({
            method: "GET",
            url: CONSTS.apiUrl + "/1/objects/tokens",
            params: {
                filter: [
                {
                    fieldName: "sessionId",
                    operator: "equals",
                    value: sessionId
                },
                {
                    fieldName: "token",
                    operator: "equals",
                    value: token
                },
                {
                    fieldName: "used",
                    operator: "equals",
                    value: false
                },
                ]
            },
            headers:{'Authorization':'basic ' + btoa (master_key + ':'+ user_key) }
        });
    
        //Generate a temporary password and username to serve as user input.
        var result = "deny";
        if(res.data.length == 1){
    
          result = "allow";
    
          //set the username and password
          var randomText = function (length) {
            if (!length) length = 10;
            return Math.random().toString(36).slice(2,length);
            }
            userInput.username = randomText(10) + '@domain.com';
            userInput.passsword = randomText(18);
    
            //Update the token to mark it used.
          var response = $http({
            method: "PUT",
            url: CONSTS.apiUrl + "/1/objects/tokens/" + res.data[0].id,
            data: {
                used: true
            },
            headers:{'Authorization':'basic ' + btoa (master_key + ':'+ user_key) }
          });
        }
       //Return results of "allow" or "deny" to override the Backand auth and provide a denied message
       //Return ignore to ignore this function and use Backand default authentication
       //Return values in additionalTokenInfo that will be added to Backand auth result.
       //You may access this later by using the getUserDetails function of the Backand SDK.
       return {"result": result, "message":"Incorrect information", "additionalTokenInfo":{}};
    }
    

    Next, we need to use the backandAuthOverride security action to override the standard Backand authentication process. See more info on how this works in the documentation on using third-party security.

    Replace the code of the action backandAuthOverride with the JavaScript on the right.

    Restricting access to the token object

    As the token object gives users a lot of power within your application, it is important that you restrict access to the token object in your app's API. Follow these steps to update the token object's security, restricting access to administrators only:

    1. Open the Security tab of the token object

    2. Click on 'Override the Security Template' and set it to true

    3. Uncheck all boxes until only the checkboxes for the Admin role remain checked.

    Disable token expiration

    Finally, you'll want to update your authentication tokens to never expire. This allows your SMS-based authentication to be persistent, meaning the user won't need to periodically respond to a new text message requesting re-authorization unless you explicitly choose so. To modify the token expiration length:

    a. Open the Security --> Social & Keys menu b. Change Session Length to Never - use refresh token

    Building from here

    This approach opens a number of options for authentication, supporting use cases more complex than "user is sitting at a computer with a web browser open". You can easily use this approach to implement a two-factor authentication model, for example - by requiring the session token in addition to the user's username and password, you can get more granular control over the user's access to your data. You can also use this to implement persistent authentication in a more private application environment, such as when running an app on a user's mobile device.

    Reducing Backand Compute Usage

    One common cost center for developers using the Backand platform is the Backand Compute Unit. These Units accrue as a result of API calls and other requests to the Backand platform, and reflect the computing effort expended by Backand to perform the requested operations. Below, we'll look at some strategies you can use to mitigate the accrual of Backand Compute Units, letting you more easily mitigate costs and resource usage within your Backand application.

    Strategy 1 - Reduce the number of calls

    Backand Compute Units are directly proportional to the number of API calls you make. As such, the most obvious strategy is to reduce the number of calls you make to the API. Some of this can be managed via standard caching and code optimization techniques, simply storing data that changes less frequently instead of fetching it from the server every time it is called. But you can also make use of Backand to reduce the amount of API calls necessary to perform common tasks. The Bulk endpoint, for example, allows you to combine up to 1,000 API requests into a single API call, reducing the cost of executing these API requests by that same 1,000 factor. See more information on making bulk requests here.

    Strategy 2 - Combine multiple calls into an Action

    A unique quirk of the Backand platform is that performing complex code in a custom on-demand action only counts as a single Backand compute unit. So if you are able, consolidate related Backand API requests into calls that take place within a custom action. There's no limit on the number of calls you can make, and through the use of parameters you can achieve most of the tasks you'd need separate API requests to accomplish.

    Strategy 3 - Make use of a plan-included test app

    If your plan allows for it, you may receive a test app allowance with your Backand subscription. These test apps are not billed, and are ideal for a development platform. Once you've finished developing your application, you can port the changes to your production instance, to ensure you are ready to serve your content to your users. Review our pricing page to see what types of options are included with your current package, and whether it makes sense to upgrade your subscription plan.

    Strategy 4 - Move database updates into queries

    Similar to moving multiple API requests into a single action, you can also consolidate multiple table updates into a single Query. Simply modify the query to perform multiple reads or updates, and return the results you want back to your calling code. Like custom actions, you'll only incur a usage charge for a single call, even if the query is making dozens of updates each time it is called.

    Keeping an eye to resource utilization

    Backand Compute Units can be troublesome to manage, but if you treat them like any other computing resource they are capable of being optimized along a number of vectors. If none of the strategies above help your specific use case, contact us to discuss other alternative solutions - we are always willing to help, and want to help you get the most out of your usage of the Backand platform.

    Contact us

    We'd love to hear how you use Backand, and if you have any development or usage patterns that you have found useful! Send us a message with feedback, bug reports, or anything else at support@backand.com for more info.

    Integrations

    The following set of documentation looks at integrating Backand with a number of different types of providers. Also included are some simple Backand-powered applications that can be used either as a starting point for your development, or as a guide for integrating Backand into a larger application.

    ToDo App with users

    Recently, we released a tutorial on the Backand GitHub page that shows off a lot of the features available by default in a Backand-powered application. After completing the tutorial, you'll have a simple ToDo list application with full support for user and role-based security. Below we'll discuss each of the features demonstrated in the tutorial, and cover any items remaining that are necessary for a full deployment.

    RESTful API Out-of-the-Box

    One of the first things we do in the tutorial, after actually creating the application with Backand, is create a new database using our JSON-based schema language. This powerful tool allows you to quickly build a database and the associated tables and objects without having a client installed. More importantly, once the database has been created, Backand automatically creates a RESTful API based on your underlying database schema. This allows you to have immediate access to your database via a series of REST API calls that create, retrieve, update, and delete records at whim. With some simple JavaScript, you can quickly build out a data layer that would take months in a stand-alone project! Furthermore, the moment you make a change to your schema, Backand will detect the change and update the API endpoints accordingly. This automated updating greatly eases the process of migrating database schema changes, and takes some of the load of server programming off your shoulders, allowing you to focus on your application's functionality.

    Security Roles

    While the RESTful API is indeed a powerful tool, the main goal of this tutorial is to explore user- and role-based security. Through Backand's dashboard you are granted a powerful array of tools that you can leverage to secure your underlying application. You can assign user-specific security settings for each object in your app, including everything from table update calls to custom triggers and actions.

    However, doing this for every user that signs up for your application would be incredibly tedious. Luckily, Backand provides User Roles that you can assign to the users in your application. Roles set a basic template for interacting with your application's API, allowing you to restrict all users with that role to only specific actions in your application. These roles can also be overridden at an endpoint level, allowing you to grant roles specific access to resources while still maintaining their general security profile.

    After the tutorial has been completed, you will have three roles for your users – administrators who have full control, users who can view all records in the application (but only update or delete those that they create themselves), and read-only users that are only able to view the ToDo items in your application.

    Login and Anonymous Access

    In addition to security roles, this tutorial will introduce you to the user access functionality available in Backand. You'll implement a mechanism for inviting users to register for your application, and enable two-step verification for your application's users, and all of the complexity will be managed by Backand! Furthermore, you'll learn how to enable anonymous access to your application through a few simple administrative dashboard settings. After the tutorial has been completed, you will have a fully secure application that allows you to invite users to the system, automatically assign them a security role, and even enable anonymous access to your ToDo list should you wish to do so.

    Remaining Items

    While the tutorial will walk you through the entire application – from inception to completion – there will still be a few tasks remaining before you can show off your new Backand-powered ToDo list app. The first section of the tutorial focuses on setting up a local application development environment, which allows you to develop and run the code on your local machine. However, once you've implemented the code and are ready to show it off, you still need to track down a web server to use for deployment. Luckily this web server does not need to be particularly robust, as your application requires zero server-side customization – simply deploy the application code to a publicly-accessible folder and you are set!

    Once you've published your application on a web server, you have a few more steps remaining in order to fully deploy the application. As a part of the tutorial you set several internal sign-up and authentication URLs that point at your local development instance. Obviously these will no longer function once you have deployed the code! Simply change the appropriate user security settings in your application's Backand dashboard, and your application will be ready to show the world!

    Summary

    This tutorial gives you a quick look at the power offered by Backand's back end tools and APIs. You'll explore creating a database and implementing a RESTful API for that data with zero effort. You'll customize your application's security and learn how to restrict users based on role and based on endpoint. You'll even spend some time working with custom server-side actions that execute on-demand. By the time you have finished the tutorial, you will have implemented a secure ToDo list application with user authentication – and all with minimal effort!

    Ionic With Backand

    Today many AngularJS developers are using Ionic to build the user interface for their mobile apps. AngularJS provides the app structure. But these mobile apps still need a backend. In this section we’ll give you the recipe you need to build an Ionic mobile app with Backand’s Backend as a Service (BaaS). Review the working demo here.

    What is Ionic?

    The Ionic framework is a mobile programming framework for constructing hybrid mobile apps. Hybrid mobile apps use a web technology (HTML, JS, CSS) to build cross-platform mobile apps (iOS, Android). Ionic is built on top of the Cordova hybrid app technology.

    The major advantage of using Ionic over Cordova itself or its commercial version PhoneGap is that it provides a plethora of mobile user interface templates both for the entire structure of the app (side menu, tabs) and for common parts (navigation top bar).

    Ionic is built using the well known AngularJS web MVC framework. Hence, developing Ionic apps is done at a higher level of abstraction than using plain HTML and jQuery. To facilitate working with the mobile device APIs in the AngularJS way, Ionic developed ngCordova, a set of AngularJS components for interacting with the various mobile device capabilities (like taking pictures). Ionic also provides a set of convenient command line tools for building and running apps.

    The Perfect Recipe for Building Mobile Apps

    In this scenario we’ll provide you with the recipe you need to use the Ionic template for a mobile app with a side menu.

    Backand

    Create an app in Backand using the free database feature. For this example we will demonstrate simple ‘playlists’ app with 3 objects: users, playlists and songs. You can use the following JSON mode:

    [
      {
        "name": "users",
        "fields": {
          "email": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "is_approved": {
            "type": "boolean"
          },
          "list": {
            "collection": "playlists",
            "via": "user"
          }
        }
      },
      {
        "name": "playlists",
        "fields": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "text"
          },
          "user": {
            "object": "users"
          },
          "songs": {
            "collection": "songs",
            "via": "playlist"
          }
        }
      },
      {
        "name": "songs",
        "fields": {
          "name": {
            "type": "string"
          },
          "order_date": {
            "type": "datetime"
          },
          "playlist": {
            "object": "playlists"
          }
        }
      }
    ]
    

    Ionic

    Now create your mobile app, naming it ‘PlaylistsApp’, with the Ionic command-line tools.

    JS Libraries

    Your Ionic app has a www folder which is a single page application (SPA) built with AngularJS. You will need to include the Backand libraries in your application. Either download them or use bower to obtain them. Then, copy them into your index.html.

        bower install angular1-sdk
    
         <script src="lib/angularbknd-sdk/dist/backand.min.js"></script>
         <script src="lib/angular-cookies/angular-cookies.js"></script>
    

    Authorization

    Backand uses authorization headers in HTTP requests. The token for authorization is obtained upon sign in to Backand and is then stored using cookies via ngCookies. The Backand SDK adds authorization headers to each HTTP request using an $http interceptor.

    In your main JavaScript file, app.js requires backand:

         var myApp = angular.module('starter', ['ionic',
           'starter.controllers', 'backand', 'starter.services']);
    

    And in your app's config add:

         myApp.config(function($stateProvider, $urlRouterProvider,
           $httpProvider)    {
            $httpProvider.interceptors.push(httpInterceptor);
         });
    

    Defining the interceptor as: javascript function httpInterceptor($q, $log, $cookieStore) { return { request: function(config) { config.headers['Authorization'] = $cookieStore.get('backand_token'); return config; } }; }

    Sign In

    In your controllers module require Backand and ngCookies:

        var myModule = angular.module('starter.controllers', ['backand', 'ngCookies']);
    

    In your login controller require Backand:

        myModule.controller('loginCtrl', function($scope, Backand) {});
    

    To perform the login call, remember that playlists is our Backand database name:

        var appName = 'playlists';
        Backand.signin(username, password, appName).then(
          function(data){}, function(error){});
    

    CRUD

    Now you will need to define a service to make the database operations. In your services module require backand:

        var myServices = angular.module('starter.services', ['backand'])
    

    Define a DatabaseService, require Backand:

        .service('DatabaseService', function($http, Backand){    
    
          var baseUrl = '/1/object/data/';
    
          return {
    
            // read all rows in the object
              readAll: function(objectName) {  
                return $http({
                  method: 'GET',
                  url: Backand.getApiUrl() + baseUrl + objectName
               }).then(
              function(response) {
                  return response.data.data;
                });
              },
    
            // read one row with given id
              readOne: function(objectName, id) {
              return $http({
                method: 'GET',
                url: Backand.getApiUrl() + baseUrl + self.objectName
                    + '/' + id
              }).then(
                function(response) {
                  return response.data;
                });
              }
          };
        });
    

    Using Backand Data

    In your controller, require DatabaseService, and make calls like:

        myModule.controller('playlistsCtrl',    
          function($scope, DatabaseService) {
    
          $scope.playlists = [];
    
          // read all playlists for a user
          DatabaseService.readAll('playlists').then(
            function(data){
            $scope.playlists = data;
          });
    
          // a click handler for selecting a playlist
          $scope.clickPlaylist = function(id){
                    DatabaseService.readOne('playlists', id).
               then(function(data){});
          });
    
        });
    

    Now you can add more Tables and build more views by repeating the above steps. You can also add server side code or send emails in the Backand cloud service under the Action tab.

    To review in Github: ionic demo.

    Retrieving data from Facebook using the Graph API

    Once you've integrated with Facebook, you can use Facebook's Graph API to augment your user data with information directly from the user's Facebook account. To do so, you'll just need to grab the user's Facebook User ID, and use the Graph API to retrieve data, update or publish new content, or any of the other functionality Facebook has to offer.

    Obtaining the Facebook User ID

    To store the user's Facebook user ID (FUID) in Backand, follow these steps:

    1. Open Security --> Security Actions menu and edit the "beforeSocialSignup" action
    2. Change the Where Condition of this action to "true" (this is set at the bottom of the content pane)
    3. Uncomment the provided code that saves the Facebook user id: userInput.fuid = parameters.socialProfile.additionalValues.id;
    4. Save the Action

    Next, you need to add the FUID field to the "users" object:

    1. Open the model page, from the Objects menu
    2. Edit the model to add a new field - fuid, type string - to the "users" object
    3. Click Validate & Update to validate the model, then Ok in the confirmation dialog to save your changes.

    From this point onward, any user that signs up to your app using Facebook as their social media provider will have their FUID automatically populated in the users object.

    Obtaining the Facebook Access token

    Modify the security action "socialAuthOverride" to return "Allow"

      return { "result": "allow", "message": "", "additionalTokenInfo": additionalTokenInfo };
    

    Now, Backand returns the Facebook access token from getUserDetails, under data.providerAccessToken

    {
      ...
      "data": {
        ...
        "providerAccessToken": "EAAWqshXVWMMBANSpEtxBuvGTucyOoiCYIbrNNuQnULqZAJqvNpBKJTZBV660NGQ6Ge6ZA0X0kr3mGEMpvqUX4vldM7n2iatOTZB8JjoinqaIfZCT9Lz8uAlt6LBZBqxAmmxTYLRFLgktVFzYhSxuCtzYc4COyG6DMZD",
        ...
      },
      ...
    }
    

    Once you've authenticated with Facebook, you can easily record your user's Facebook access token. This can be used to re-authenticate the user with Facebook when performing API calls, such as fetching additional user data using the Facebook Graph API.

    Getting Facebook data into Backand code

        var fuid = "176102422846507";
        var facebookAccessToken = "EAAWouLyM4lEBADjVlK9yslq9YNjx7S5UUx9oKUo6BWxsj9qc77ZCuKZAPvBQUIulpieNJIJ0Uit3K0UFR0oxjxl68DupTb0uoJFXPQFUdTOlneLEprG6b8WxuYN3AX6m05hKpFbBPKczCab1OUetevdvkZCO6rtPUQEUtc68gZDZD";
    
        var response = $http({
            method: "GET",
            url:"https://graph.facebook.com/v2.8/" + fuid + "/friends?fields=id,name,gender",
            params:{
                "access_token": facebookAccessToken
            },
            headers:{"Content-Type":"application/json"}
        });
    
        console.log(response);
    

    Once you have the Facebook user ID and access token, you can use the Graph API to access any available Facebook data.

    At this point, you're ready to work with the API. For example, you can use this sample code to get a list of a user's friends in Facebook:

    Getting a Facebook profile image

    <a href="#">http://graph.facebook.com/{fuid}/picture</a>
    

    You can easily obtain a user's Facebook profile using a single URL reference. The template is available on the right - simply replace {fuid} with the user's Facebook User ID.

    <a href="http://graph.facebook.com/{fuid}/picture?type=large" target="_blank">http://graph.facebook
    .com/{fuid}/picture?type=large</a>
    

    You can pull in a larger version of the profile picture using the HTML to the right:

    Finally, you can refer to Facebook's Docs on their Graph API, and use the information to create whatever type of integration with Facebook that you desire.

    Amazon AWS and S3 Integrations

    Amazon Web Services, or AWS, offer a lot of useful functionality for web developers. From hosting, to distributed computing, to even simple data storage, Amazon has backed many of the web's largest websites since its inception. Below we'll look at Amazon S3, and how we can integrate the data storage service into a Backand-powered application.

    A Quick S3 Overview

    Amazon's Simple Storage Service, or S3, is an online file storage web service offered as a part of the Amazon Web Services suite of functionality. It was first launched in the US in 2006, and uses standard web service interfaces for communication. Service consumers can simply authorize their app with S3, then perform a series of web service calls to manage their S3 storage bucket. By using this service, a developer can offload concerns about data availability, reliability, and storage space to Amazon's server farms, simply paying a usage-based fee each month for the data stored.

    Server-side Action

    Backand's Noterious app has an excellent example of how simple an integration with S3 can be. The functionality revolves around the creation of server-side actions to wrap the web service requests made over HTTP. The actual integration looks like this:

    var data =
        {
            // enter your aws key
            "key" : "AKIAIJX26SY3COIWV4FQ",
    
            // enter your aws secret key
            "secret" : "ogun3pSOyw8FtP5i17s2STBPO9jQ8cs+lnpxwg82",
    
            // this should be sent in post body
            "filename" : parameters.filename,
            "filedata" : parameters.filedata,         
    
            "region" : "US Standard",
            "bucket" : "backand-free-upload"
    
        }
    var response = $http({method:"PUT",url:CONSTS.apiUrl + "/1/file/s3" ,
                   data: data, headers: {"Authorization":userProfile.token}});
    
    return response;
    

    The above code is inserted into a new Custom Server-Side JavaScript Action created using the Backand dashboard. It pulls the file information from the parameters passed to the action, then sends a request to S3's file upload endpoint, putting the file into the bucket backand-free-upload. By customizing the above code, you can achieve any underlying file structure you desire.

    Client-side Integration

    Of course the server-side code is only half of the story – we need to integrate this wrapped API call into our application for it to be useful. Going back to the Noterious demo application, you can see an example of this taking place in the Notes model class:

    //Send file content in base64 to Backand on-demand action
    self.s3FileUpload = function(filename, filedata, success, error)
    {
      return $http ({
        method: 'POST',
        url: Backand.getApiUrl() + '/1/objects/action/notes?name=upload2s3',
        headers: {
          'Content-Type': 'application/json'
        },
        data:
        {
          "filename":filename,
          "filedata": filedata.substr(filedata.indexOf(',')+1, filedata.length) //need to remove the file prefix type
        }
      });
    };
    

    The above code is pretty straightforward. It defines a function – s3FileUpload – that takes input from your application in the form of file data, and then communicates with your new custom JavaScript action via an HTTP POST request using JavaScript's built-in AJAX capabilities. Simply call this function from your Angular code, and you will be uploading files in no time!

    Stripe Integration

    Once you've decided how you want to monetize your web app, you'll likely begin looking at ways to integrate your code with a vendor that will accept and process payments on your behalf. While this would be a daunting effort to perform in a custom-built environment, Backand's built-in security and stability help to ease many of the requirements that are imposed upon payment applications. Below we'll look at using a third-party vendor – Stripe – to process payments, and examine how to integrate Stripe with a Backand application.

    A quick note: In our Stripe Example Application, we used angular-stripe – a popular third-party tool that allows you to easily interface with Stripe from your Angular code – to make calls to Stripe's Stripe.js file, which provides most of the payment tokenization functionality. This is obviously a convenience, and you are free to call Stripe.js directly from your application, but the below text assumes you are also using this library. It is also important to note that the code below – particularly the client side code – was adapted from the Stripe example application, and as such may not be directly usable without some modification. Please study the code to understand the content, rather than simply trying to cut-and-paste the client-side components.

    Why use a vendor?

    The first question that you are likely asking is "Why should I use a third-party vendor for my payment system?" The short answer, albeit not a very good one, is that a solid and reliable payments platform is not only extremely challenging, but extremely expensive as well. Setting aside the data concerns (which we have covered elsewhere), you'll need significant liquid assets available to even begin working with financial systems directly. Furthermore, you'll be accepting full fraud risk for your users – if any of your users tries to use your payments system for illegal or unethical ends, then you will be liable for the damages caused. These are just a few of the many concerns that would come with building a payment system from the ground up without using a payment vendor.

    With a payment vendor, on the other hand, you are able to offload all of the above issues to the vendor, allowing you to focus instead on integrating payments into your application. Stripe performs underwriting (which handles any potentially fraudulent individuals by simply preventing them from accepting payments), payment processing, communication with financial systems, and all necessary reporting as the transactions move through the various banks and financial APIs. While it would be possible to perform all of this work yourself, you'll save yourself years of labor by simply leveraging someone else's efforts.

    Server-side Action

    We'll begin the application by adding a custom server-side action. This action will execute JavaScript that accepts a payment token as an argument, and then uses that token to register a payment with Stripe. Simply use the following code in your server-side action to log your payment:

      // Secret key - copy from your Stripe account   
      // - https://dashboard.stripe.com/account/apikeys -
      // or use Backand's test account
      var user = btoa("sk_test_hx4i19p4CJVwJzdf7AajsbBr:");
    
      response = $http({
        method: "POST",
        url: "https://api.stripe.com/v1/charges",
        params: {
            "amount":parameters.amount,
            "currency":"usd",
            "source": parameters.token
        },
        headers: {
            "Authorization": "Basic " + user,
            "Accept" : "application/json",
            "Content-Type": "application/x-www-form-urlencoded"
        }
      });
    
    return {"data":response};
    

    The above code simply takes all of the information needed for a payment – specifically the amount (in pennies) and the payment method token – and sends them to Stripe via a POST request to their RESTful API. You can create as many of these actions as you like, wrapping additional Stripe API calls at will.

    Client-side Integration

    Once you've got the server-side action, you are just about ready to start accepting payments. There are two steps that need to take place on the client side before you can do so. First, we'll look at setting the API Key.

    The API Key tells the Stripe.js file that the actions being taken are to take place under your Stripe account. On the server side, this is the Secret Key that you obtain from the Stripe dashboard. The client side needs something more secure, though, as anyone with your secret key could impersonate your app and cause security issues. Recognizing this, Stripe provides you with a public key that you can use for client-side code. This is secured against a secret key on your Stripe account, and cannot be used to actually register payments or perform transfers. To set your public key, use the following code:

      .config(function (stripeProvider) {
        //Enter your Stripe publish key or use Backand test account
        stripeProvider.setPublishableKey('pk_test_pRcGwomWSz2kP8GI0SxLH6ay');
      })
    

    Once you've set your publishable key, you're ready to start tokenizing payment methods. The code below performs two tasks. It first creates a token from the payment data entered into your app's UI, then it sends that token to the custom action that we created in the previous section by calling a convenience method. We'll first add the tokenization and payment success code:

      self.charge = function(){
    
        self.error = "";
        self.success = "";
    
        //get the form's data
        var form = angular.element(document.querySelector('#payment-form'))[0];
    
        //Use angular-stripe service to get the token
        return stripe.card.createToken(form)
          .then(function (token) {
            console.log('token created for card ending in ', token.card.last4);
    
            //Call Backand action to make the payment
            return BackandService.makePayment(form.amount.value, token.id )
          })
          .then(function (payment) {
            self.success = 'successfully submitted payment for $' + payment.data.data.amount/100.0;
          })
          .catch(function (err) {
            if (err.type && /^Stripe/.test(err.type)) {
              self.error = 'Stripe error: ' +  err.message;
            }
            else {
              self.error = 'Other error occurred, possibly with your API' + err.message;
            }
          });
      }
    

    Once this code has been created, we need to write one additional function. This function wraps a HTTP request to the custom action we created previously. It assumes that the action's name is makePayment, so be sure to change it to something that matches your actual implementation:

    factory.makePayment = function(amount, token){
        return $http({
          method: 'GET',
          url: Backand.getApiUrl() + '/1/objects/action/items?name=makePayment',
          params:{
            parameters:{
              token: token,
              amount: amount
            }
          }
        });
      }
    

    And with that, we've added the basic code necessary to contact Stripe and record a payment.

    Conclusion

    The above code gives us the basis of a payments system. It can accept payments from a user, which are recorded against your own Stripe account. You can use this as a basis for a larger application, that provides a deeper integration with Stripe's API. Simply follow the pattern of wrapping the API calls in server-side actions, then calling those actions via the Backand API, and you'll have a solution built very rapidly that is both secure and scalable from day one.

    Mandrill

    Mandrill is an email infrastructure service that focuses on transactional emails. Using Mandrill, you can send personalized e-commerce messages on a one-to-one basis, or automated transactional messages for things like password resets, order confirmations, and welcome messages.

    Send Email with Mandrill API (No Attachment)

    Mandrill has an API that you can use to send emails, along with a lot of other functionality. By translating their provided cURL commands to Angular $http calls, you can easily integrate Mandrill with Backand.

    Server side action code

    /* globals
      $http - Service for AJAX calls
      CONSTS - CONSTS.apiUrl for Backands API URL
    */
    'use strict';
    function backandCallback(userInput, dbRow, parameters, userProfile) {
        // write your code here
        var response = $http({
          method: 'POST',
          url: 'https://mandrillapp.com/api/1.0/messages/send.json',
          data: {'key':<enter your mandrill key>,
                'message':{'html':parameters.message,
                'subject':'Example for Mandrill Integration',
                'from_email':userProfile.username,'from_name':parameters.name,
                'to':[{'email':userProfile.username,'name':parameters.name,'type':'to'}],
                'headers':{'Reply-To':'message.reply@backand.com'}}}
        });
        console.log(response);
        return {};
    }
    

    To send an email with Mandrill, you need to create a server side action. You can either trigger this action with an object's CRUD event handler, or call it on-demand from your client code. The following example demonstrates the on-demand option. In the Backand dashboard, open the Actions tab for one of your application's objects, and create a new on-demand server-side JavaScript action. Learn more about how to create actions here. Name the action mandrillapp, add message and name to the Input Parameters, and paste the code on the right into the code editor.

    In the example app we're building, the app's users can send messages to themselves. This is done through the use of userProfile.username, which is the email address used to register with the application. Make sure to replace the key property above with your Mandrill API key.

    Client-side code

    return $http ({
      method: 'GET',
      url: Backand.getApiUrl() + '/1/objects/action/<your object name>/1',
      params: {
        name: 'mandrillapp',
        parameters: {
          message: 'Anything you can put your mind on',
          name: '<your name here>'
        }
      }
    });
    

    Next, add the JavaScript code to the right to your app's client-side code base. Replace <your object name> with the object associated with the action you created. Once this is done, you'll be able to easily trigger emails via Mandrill using Backand's custom action API.

    Send Email with Mandrill API (with Attachments)

    Below, we’ll create a server-side Node JS action that imports the Mandrill SDK, allowing you to easily send email with attachments through Mandrill in your Backand application.

    Getting Started in Backand

    To get started with a Mandrill action, you’ll need to first create a new Server-Side NodeJS action in Backand. To do so, open up your app’s dashboard at https://www.backand.com, and navigate to an object that will host the action. On the Actions tab of this object, create a new 'On Demand' action. Name this action, then select 'Server-Side Node.JS Action' as the action’s type. Follow the documentation provided to download the Backand CLI and initialize your action locally.

    Initializing the Mandrill Action

    Once you have the Server-Side Node.js action ready to go, the next step is to create an action in Mandrill. Navigate to http://www.mandrill.com/ and create a new action in the MailChimp dashboard provided when you log in. Once the action is ready, copy down the Mandrill API Key value and save it somewhere safe. This API key will be used by the Node.js action to connect and communicate with Mandrill.

    Updating the Code

    var mandrill = require('node-mandrill')(MANDRILL_API_KEY);
    var request = require('request').defaults({ encoding: null });
    

    Next, we’ll need to update the action’s code to communicate with Mandrill. We’ll start by configuring the mandrill SDK requirements in index.js. Add these lines into index.js in your Node.js action folder structure, before the function exports.backandCallback:

        var filePath = 'PATH_TO_ATTACHMENT_INCLUDING_FILENAME';
        var fileName = 'FILENAME_OF_ATTACHMENT';
    
        request.get(filePath, function (error, response, body) {
          if (!error && response.statusCode == 200) {
            sendEmail(fileName, response.headers['content-type'], new Buffer(body).toString('base64'));
          }
        });
    
        function sendEmail(fileName, fileType, fileContent) {
          mandrill('/messages/send', {
            message: {
              to: [{email: 'RECIPIENT_EMAIL', name: 'RECIPIENT_DISPLAY_NAME'}],
              from_email: 'SENDER',
              subject: 'EMAIL_SUBJECT',
              text: 'MESSAGE_BODY',
              attachments: [{
                'type': fileType,
                'name': fileName,
                'content': fileContent
              }]
            }
          }, function (error, res) {
            //uh oh, there was an error
            if (error) {
              //console.log(JSON.stringify(error));
              response(error, null);
            }
            //everything's good, lets see what mandrill said
            else {
              console.log(res);
              response(null, res);
            }
    
    
          });
        }
    

    Next, we’ll modify the backandCallback function to send a message with Mandrill. Replace the contents of this function with the code on the right. This code does two things:

    1. The initial code fetches the attachment data from the server on which it is stored. If this code succeeds, it calls sendEmail with the file data provided as a Base 64 string.
    2. sendEmail then takes this data and contacts Mandrill to send the message.

    Configuring the Code

    To tie the project together and finalize the above code, simply replace each of the placeholders with the appropriate value:

    You can also use the parameters argument to the action to send additional message data, whether that data originates in your app’s database or via the API call. Once these changes are made, your server-side action is ready to deploy!

    Testing and Deployment

    You can debug and run the action locally using the provided debug.js file. Simply enter node debug.js on the command line to debug. Once you’ve finished your local testing, you can then deploy the action via the documentation provided in the Server-Side Action’s UI in your app’s dashboard at Backand.com - head to the Actions tab for the relevant object, and follow the instructions on using backand action deploy to deploy your code.

    Calling the Action

    To call the action in your client-side code, simply use the Backand SDK’s action functionality as you would any other on-demand action:

      return Backand.object.action.get('OBJECT_NAME', 'ACTION_NAME', {
        'parameters': {}
      })
    

    Simply replace OBJECT_NAME with the name of the object controlling your action, and ACTION_NAME with the Server-Side Node.js Action’s name in Backand. You can provide any extra information or detail using the provided parameters object - this will be passed into the parameters argument of your action.

    Mailgun

    Mailgun is an email automation service provided by Rackspace. It offers a complete cloud-based email service for sending, receiving, and tracking email messages sent by your registered websites and applications.

    Send Email with Mailgun API

    Server-side Action

    /* globals
      $http - service for AJAX calls - $http({method:"GET",url:CONSTS.apiUrl + "/1/objects/yourObject" , headers: {"Authorization":userProfile.token}});
      CONSTS - CONSTS.apiUrl for Backand's API URL
    */
    'use strict';
    function backandCallback(userInput, dbRow, parameters, userProfile) {
        // write your code here
    
        var apiBaseUrl = "https://api.mailgun.net/v3/sandbox<your mailgun sandbox key here>.mailgun.org/messages";
    
        var apiKey = "api:<your mailgun key here>";
    
        var encodedAuth = btoa(apiKey);
        //console.log(encodedAuth);
    
            var response = $http(
            {
                method:"POST",
                url: apiBaseUrl,
                headers: {
                    "Authorization": "Basic " + encodedAuth,
                    "Content-Type" : "multipart/form-data; charset=utf-8",
                },
                data: {
                    from: userProfile.username,
                    to: userProfile.username,
                    subject: 'testing mailgun with backand',
                    text: parameters.message
                }
    
            }
        );
    
        console.log(response);
        return {};
    }
    

    Mailgun provides an API that can be used to easily send email, among many other features. By translating Mailgun's provided cURL examples to JavaScript $http calls, you can easily integrate Mailgun with Backand.

    To send an email with Mailgun, you need to create a server side action.You can either trigger this action with an object's CRUD event handler, or call it on-demand from your client code. The following example demonstrates the on-demand option. In the Backand dashboard, open the Actions tab for one of your application's objects, and create a new on-demand server-side JavaScript action. Learn more how to create actions here. Name the action mailgun, add message and name to the Input Parameters, and paste the code on the right in the code editor. In this example the app user can send any message that he wants to himself. Please replace the "apiKey" property, as well as the sandbox URL, with your associated mailgun values.

    Client-side code

    return $http ({
      method: 'GET',
      url: Backand.getApiUrl() + '/1/objects/action/<your object name>/1',
      params: {
        name: 'mailgun',
        parameters: {
          message: 'Anything you can put your mind on',
          name: '<your name here>'
        }
      }
    });
    
    

    Next, add the client-side JavaScript code to your app's code base. Replace <your object name> with the object associated with the action you created, and you are ready to send messages via Mailgun!

    SendGrid

    SendGrid is a cloud-based SMTP provider that allows you to send email without having to maintain email servers. SendGrid manages all of the technical details, from scaling the infrastructure to ISP outreach and reputation monitoring to whitelist services and real time analytics.

    Who is SendGrid for?

    SendGrid is for anyone that needs to send email, whether it’s transactional email or marketing emails and campaigns. We send billions of emails each month, so we can handle your email regardless of volume.

    Send Email with SendGrid API

    Server-Side Code

    /* globals
      $http - Service for AJAX calls
      CONSTS - CONSTS.apiUrl for Backands API URL
      Config - Global Configuration
      socket - Send realtime database communication
    */
    'use strict';
    function backandCallback(userInput, dbRow, parameters, userProfile) {
    
        var res = $http({
            method:"POST",
            url:"https://api.sendgrid.com/api/mail.send.json",
            data:
                "from=" +userProfile.username+
                "&to=" + parameters.to +
                "&subject=hellow"+
                "&html=" + parameters.message,
    
             headers: {"Accept":"Accept:application/json",
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Authorization":"Bearer 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"
    
             }
         });
         return res;
    }
    

    SendGrid has an API that you can use to send emails, along with a lot of other functionality. By translating their provided cURL commands to Angular $http calls, you can easily integrate SendGrid with Backand.

    To send an email with SendGrid, you need to create a server side action. You can either trigger this action with an object's CRUD event handler, or call it on-demand from your client code. The following example demonstrates the on-demand option. In the Backand dashboard, open the Actions tab for one of your application's objects, and create a new on-demand server-side JavaScript action. Learn more how to create actions here. Name the action SendGrid, add to and message to the Input Parameters (like that: to, message ), and paste the server-side code into the code editor.

    In the example app we're building, the app's users can send messages to an email sent by the client side in the 'to' parameter. Make sure to replace the 'Authorization' header above with your SendGrid API key (after you register with SendGrid you should waite for your account to be provisioned and than you'll see the API KEY under Settings/ API Keys).

    Client-Side code

    return $http ({
      method: 'GET',
      url: Backand.getApiUrl() + '/1/objects/action/<your object name>',
      params: {
        name: 'SendGrid',
        parameters: {
          message: 'Anything you can put your mind on',
          to: '<your destination email>'
        }
      }
    });
    
    

    Next, add the client-side JavaScript code to your app's code base. Replace <your object name> with the object associated with the action you created and <your destination email> with the target recipient.

    Once this is done, you'll be able to easily trigger emails via SendGrid using Backand's custom action API.

    PayPal

    Once you've decided how you want to monetize your web app, you'll likely begin looking at ways to integrate your code with a vendor that will accept and process payments on your behalf. While this would be a daunting effort to perform in a custom-built environment, Backand's built-in security and stability help to ease many of the requirements that are imposed upon payment applications. Below we'll look at using a third-party vendor – PayPal – to process payments, and examine how to integrate PayPal with a Backand application.

    A quick note: The below text was adapted from the PayPal developer docs, and as such may not be directly usable without some modification. Please study the code to understand the content, rather than simply trying to cut-and-paste the client-side components.

    PayPal provides many options for accepting payments, including Express Checkout, transactions, refunds, payment with agreementId, and so on. In this example, we will implement Express Chackout as it is the simplest and most straightforward method to enable.

    Server-side Action

    Server-side Action Code

    
       var paypalUrl = 'https://api.sandbox.paypal.com/';
    
       // PayPal has a 2 stage process where: // the first stage prepares the payment and a returns a url for the user to pay
       // and the sconde stage (where the payment is actually done) is where the application send an approval API call to PayPal
       if (parameters.process == 'payment') {
         var payment = postPayment();
         return payment.links[1].href;
       }
       else if (parameters.process == 'approval') {
         return postApproval();
       }
    
       function postPayment() {
         var authorization = "Bearer " + getAccessToken().access_token;
         var payment = {
           "intent": "sale",
           "redirect_urls": {
             "return_url": "http://localhost:3000/#/paypal",
             "cancel_url": "http://localhost:3000/#/paypal?fail=true"
           },
           "payer": {"payment_method": "paypal"},
           "transactions": [
             {
               "amount": {
                 "total": parameters.amount,
                 "currency": "USD"
               }
             }
           ]
         };
         try {
           return $http({
             method: 'POST',
             url: paypalUrl + 'v1/payments/payment',
             data: payment,
             headers: {
               "Content-Type": "application/json",
               "Accept-Language": "en_US",
               "Authorization": authorization
    
             }
           });
         }
         catch (err) {
           if (err.name == 401) {
             cookie.remove('paypal_token');
             return postPayment();
           }
           else {
             throw err;
           }
         }
       }
    
       function postApproval() {
         var authorization = "Bearer " + getAccessToken().access_token;
         var payer = {"payer_id": parameters.payerId};
         try {
           return $http({
             method: 'POST',
             url: paypalUrl + 'v1/payments/payment/' + parameters.paymentId + '/execute/',
             data: JSON.stringify(payer),
             headers: {"Content-Type": "application/json", "Accept-Language": "en_US", "Authorization": authorization}
           });
         }
         catch (err) {
           if (err.name == 401) {
             cookie.remove('paypal_token');
             return postApproval();
           }
           else {
             throw err;
           }
         }
       }
    
       function getAccessToken() {
         var token = cookie.get('paypal_token');
         if (!token) {
           var ClientId = 'YOUR_PayPal_CLIENT_ID';
           var Secret = 'YOUR_PayPal_SECRET_KEY';
           var user = btoa(ClientId + ":" + Secret);
    
           try {
             token = $http(
               {
                 method: 'POST',
                 url: paypalUrl + 'v1/oauth2/token',
                 data: 'grant_type=client_credentials',
                 headers: {
                   "Accept-Language": "en_US",
                   "Authorization": "Basic " + user
                 }
    
               });
           }
           catch (err) {
             if (err.name == 401) {
               var e = new Error("Unauthorized (401), check client id and secret");
               e.name = err.name;
               throw e;
             }
             else {
               throw err;
             }
           }
           cookie.put('paypal_token', token);
         }
         return token;
       }
    
    

    We'll begin the application by adding a custom server-side action. This action will execute JavaScript that implements a 2 stage process. It performs the payment API call, and then the Approval API call. Each step uses an access token obtained from PayPal's OAuth2/token call. To save a call to the OAuth endpoint for an extra token, we'll cache the OAuth token in a server side cookie (although if the cookie expires, you'll need to refresh the token from the OAuth2/token endpoint. See the try-catch block). The first stage prepares the payment and returns a url for redirecting the user to PayPal site. The second stage occurs after the user has acknowledged the payment and been brought back to your application, at which point you call the Approval API to complete the payment. The code example is a server-side action that implements all of the functionality necessary to register an Express Checkout payment with PayPal.

    The code takes the payment stage information in parameters.process, and executes the appropriate PayPal API call. In the first stage, when directing the user to PayPal to confirm the payment, parameters.process will contain "Payment". This results in the function postPayment being called, which sends a POST command to PayPal with the payment information, along with a URL to redirect to when the user either accepts or cancels the payment. In the second payment stage, when contacting the Approval API to complete the payment, parameters.process will contain "Approval". This will result in the code calling postApproval, which issues a POST call to PayPal using the PayerID and PaymentID stored in the query string of the return URL. This function will return a PayPal payment object including all of the relevant payment details and the payment status.

    Client-side Integration

    Client-side prepare payment code.

          var self = this;
    
            self.charge = function () {
              self.error = "";
              self.success = "";
    
              //get the form's data
              var form = angular.element(document.querySelector('#paypal-form'))[0];
    
              //Call Backand action to prepare the payment
              var paypalUrl = BackandService.makePayPalPayment(form.amount.value)
                .then(function (payment) {
                  var paypalResponse = payment;
                  //redirect to PayPal - for user approval of the payment
                  $window.location.href = paypalResponse.data;
                })
                .catch(function (err) {
                  if (err.type) {
                    self.error = 'PayPal error: ' + err.message;
                  } else {
                    self.error = 'Other error occurred, possibly with your API' + err.message;
                  }
                });
            }
    

    Once you've got the server-side action, you are just about ready to start accepting payments. The code to the right performs two tasks. It first calls a service to prepare the payment (the Payment API in PayPal), which returns a URL to which the user is redirected.

    Client-side finalize payment code

          //check if this is a redirect from PayPal , after the user approves the payment
          // PayPal adds PayerID and  paymentId to the return url we give them
    
          if ($location.search().PayerID && $location.search().paymentId) {
    
            //Call Backand action to approve the payment by the facilitator
            BackandService.makePayPalApproval($location.search().PayerID, $location.search().paymentId)
              .then(function (payment) {
                // remove PayPal query string from url
                $location.url($location.path());
                self.success = 'successfully submitted payment for $' + payment.data.transactions[0].amount.total;
              }
            )
        }
    

    Once the user has accepted or canceled the payment, PayPal redirects them back to the URL that was provided to the server-side action. In this example, we use the same page by checking the query string parameter paymentid. This allows the code to detect which stage of the payment process we are at.

    Client-side code to contact custom actions for paypal

      //Call PayPalPayment on demand action
      factory.makePayPalPayment = function (amount) {
    
          return $http({
            method: 'GET',
            url: Backand.getApiUrl() + '/1/objects/action/items/1',
            params: {
              name: 'PayPalPayment',
              parameters: {
                amount: amount,
                process:"payment"
              }
            }
          });
        };
    
        //Call PayPalApproval on demand action
        factory.makePayPalApproval = function (payerId, paymentId) {
            return $http({
            method: 'GET',
            url: Backand.getApiUrl() + '/1/objects/action/items/1',
            params: {
              name: 'PayPalPayment',
              parameters: {
                payerId: payerId,
                paymentId: paymentId,
                process:"approval"
              }
            }
          });
        };
    

    Once this code has been added to your project, we need to implement the service that calls Backand's server side payment action. This service wraps a HTTP request to the on-demand custom action that we created earlier in the tutorial. It assumes the action name is PayPalPayment, so be sure to change it as appropriate to match your actual implementation. With that, we've added the basic code necessary to contact PayPal and record a payment.

    Conclusion

    The above code gives us the basis of a payments system. It can accept payments from a user, which are recorded against your own PayPal account. You can use this as a starting point for a larger application that provides a deeper integration with PayPal's API. Simply follow the pattern of wrapping the API calls in server-side actions, then calling those actions via the Backand API, and you'll have a solution built very rapidly that is both secure and scalable from day one.

    Segment.io

    There are a large number of web analytics tools available that can help your marketing team understand both how many users are using your product, and what they are doing while they use it. Implementing these services in your Backand application is as simple as any other third-party API integration. Segment.io allows you to implement an analytics API and send it to almost any notification tool available, depending on your infrastructure needs. Normally this type of integration would be done on the client side, but there are some instances where a server-side integration is useful. In this example, we will look at implementing a Segment.io integration with your Backand application using a custom server-side action.

    Server-side Action

    Server-Side Action Code

    /* globals
     $http - Service for AJAX calls
     CONSTS - CONSTS.apiUrl for Backands API URL
     */
    'use strict';
    function backandCallback(userInput, dbRow, parameters, userProfile) {
      // write your code here
    
      var writeKey = 'YOUR_SEGMENT_IO_WRITE_KEY';
      var authorization = 'Basic ' + btoa(writeKey);
      var segmentUrl = 'https://api.segment.io/v1/identify';
    
      var segmontPostResponse = $http(
        {
          method: 'POST',
          url: 'https://api.segment.io/v1/identify',
          data: {
            "userId": parameters.userId,
            "traits": {
              "email": parameters.userId,
              "ActiveApps": parameters.activeApp
            },
    
    
            "integrations": {
              "All": false,
              "Woopra": true,
              "Intercome":true
            }
          },
          headers: {'Authorization': authorization, 'Accept': 'application/json', 'Content-Type': 'application/json'}
    
        });
    
      return segmontPostResponse;
    }
    

    We'll start by adding a new custom server-side action. This action will execute JavaScript code that sends user identification data to segment.io (and, from there, to Woopra, or Intercom, or any other interested service). The code takes two parameters - userId and activeApp, with the userId being the user's email address. You can also send Segment.io data collected from Backand using a query to obtain the data you have stored on a given user.

    Client-side Integration

    This code has no client-side component.

    Twilio

    Twilio takes care of dealing with messy telecom hardware, exposing a globally available cloud API that developers can interact with to build intelligent and complex communications systems. As your app's usage scales up or down, Twilio automatically scales with you.

    Who is Twilio for?

    Twilio is for anyone that needs to send SMS, MMS, or VoIP, along with a lot of other communication channels embedded into web, desktop, and mobile software.

    Send SMS with Twilio API

    Server-Side Action code

    /* globals
      $http - Service for AJAX calls
      CONSTS - CONSTS.apiUrl for Backands API URL
      Config - Global Configuration
      socket - Send realtime database communication
      files - file handler, performs upload and delete of files
      request - the current http request
    */
    'use strict';
    function backandCallback(userInput, dbRow, parameters, userProfile) {
        // write your code here
        var ACCOUNT_SID = 'AC2933cadba659d1f15bd409333e3bc38b';
        var AUTH_TOKEN = 'e924350f6eefb5dd1ae011b49d5cb5dd';
    
        var FROM_PHONE_NUM = 'GetEat';
    
        var basicUrl = 'https://api.twilio.com/2010-04-01/Accounts/' + ACCOUNT_SID + '/';
        var action = 'Messages.json' // twilio have many services
    
        return $http({
            method: "POST",
            url: basicUrl + action,
            data:
                'Body=' + parameters.message +
                '&To='  + parameters.to +
                '&From='+ FROM_PHONE_NUM,
            headers: {
                "Accept":"Accept:application/json",
                "Content-Type": "application/x-www-form-urlencoded",
                "Authorization": 'basic ' + btoa(ACCOUNT_SID + ':' + AUTH_TOKEN)
            }
        });
    
    }
    

    Twilio has an API that you can use to send SMS. By translating their provided cURL commands to Angular $http calls, you can easily integrate Twilio with Backand.

    To send SMS with Twilio, you need to create a server side action. You can either trigger this action with an object's CRUD event handler, or call it on-demand from your client code. The example code demonstrates the on-demand option. In the Backand dashboard, open the Actions tab for one of your application's objects (Database --> Objects --> <object name>, actions tab), and create a new on-demand server-side JavaScript action. Learn more how to create actions here. Name the action TwilioSendSMS, add to and message to the Input Parameters, and paste the server-side code in the code editor.

    In the example app we're building, the app's users can send a SMS message to a phone number. The phone number is sent, from the client side, in the to parameter, while the message content is sent in the message parameter.

    Setup a FREE account in Twilio

    After you register with Twilio, you can get your Twilio phone number here:

    1. To choose a different phone number from the one provided, click on 'Don't like this one? Search for a different number.' and select SMS in capabilities.
    2. Replace the FROM_PHONE_NUM in the code with the Twilio phone number obtained in the prior step (dont forget the (+) sign before the number)
    3. Make sure you replace the 'ACCOUNT_SID' and 'AUTH_TOKEN' in the code with your Twilio API keys (from the getting started page). Simply click on 'Show API Credentials' on the right side of 'Get Started with Phone Numbers,' and than you'll see the ACCOUNT SID and AUTH TOKEN values.

    Setup client-side code:

    Client-Side Code

    return $http ({
      url: Backand.getApiUrl() + '/1/objects/action/<your object name>',
        params: {
          name: 'TwilioSendSMS',
          parameters: {
            message: 'Anything you can put your mind on',
            to: '<your destination phone number>'
          }
        }
    });
    
    

    Next, add the client-side JavaScript code to your app's code base. Replace <your object name> with the object associated with the action you created and <your destination phone number> with a vaild phone number (when using Twilio trial account you first need to validate this phone number), Once this is done, you'll be able to easily trigger SMS via Twilio using Backand's custom action API.

    Netmera

    Netmera is a cloud based service that can be used to send Push Notifications to various platforms, among other services such as Exception reporting. It offers a friendly site where campaigns (push notifications) can be managed and customized and a REST API to send push notifications automatically. In this guide you can find out how to get started on Netmera and send push notifications with Backand.

    Get Started with Netmera

    1. Register to Netmera
    2. Download the Netmera SDK from here or their starter app.
    3. Check out their guide to set up your app/the starter app with the Netmera SDK
    4. Follow this Android guide and iOS guid to configure push notifications on the app and get the key from Google Cloud Messaging. If you use the starter app you only need the first 3 steps to get started (unless you want to trigger advanced features like tags).
    5. For Ionic you would need to implement the SDK for PhoneGap Plugin

    Integrating Netmera with Backand

    Netmera has a rest API that can be used to remotely send push notifications. You can integrate Netmera with Backand by using Backand server-side actions. You can either trigger this action with an object's CRUD event handler, or call it on-demand from your client code.

    In the Backand dashboard, open the Actions tab for one of your application's objects, and create a new on-demand server-side JavaScript action by clicking on Netmera under 'Push Notifications'.

    You have just created your first push notification action!

    Client-Side code

    return $http ({
      url: Backand.getApiUrl() + '/1/objects/action/<your object name>',
        params: {
          name: 'SendPushNotification',
          parameters: {
            notificationTitle: 'My First Push Notification',
            notificationContent: 'Hello! This is my first notification!'
          }
        }
    });
    

    In order to call the function from your angular app, use the following code:

    Replace ‘your object name’ with the object associated with the action you created, set a title for the 'notificationTitle' field, write any message you want in ‘notificationContent’ field and you’re good to go. Now you can start sending push notifications dynamically using Backand and Netmera.

    PushWoosh

    Pushwoosh is a cloud based service that can be used to send Push Notifications to various platforms. It offers a friendly site where push notifications can be sent and customized and an API to send push notifications automatically. In this guide you can find out how to get started on PushWoosh with an example app for Android and send push notifications with Backand.

    Get Started with PushWoosh

    1. Register an account in PushWoosh and proceed to create an application. Using the PushWoosh control panel, configure your application to support Android including configuring GCM (Google Cloud Messaging)
    2. You can either get the starter app or to integrate in an existing app. > To get a starter app: clone the PushWoosh Android SDK:
    git clone https://github.com/Pushwoosh/pushwoosh-android-sdk.git
    

    Then, open /Samples/Android-Simple directory in Android Studio and build the app.

    1. To integrate in an existing app use the following Android guide – include the SDK.jar and add the relevant code to your application.
    2. To integrate in an existing app use the following iOS guide
    3. For Ionic you would need to implement the SDK for Cordova / PhoneGap and check this example for PhoneGap Build

    Integrating PushWoosh with Backand

    PushWoosh has an API that can be used to send Push Notifications. You can integrate PushWoosh with Backand by using Backand server-side actions. You can either trigger this action with an object's CRUD event handler, or call it on-demand from your client code.

    In the Backand dashboard, open the Actions tab for one of your application's objects, and create a new on-demand server-side JavaScript action by clicking on 'PushWoosh' under 'Push Notifications'.

    You have just created your first push notification action!

    Client-side code

    return $http ({
      url: Backand.getApiUrl() + '/1/objects/action/<your object name>',
        params: {
          name: 'SendPushNotification',
          parameters: {
            notificationContent: 'Hello! This is a push notification!',
          }
        }
    });
    

    In order to call the function from your angular app, use the provided code. Replace <your object name> with the object associated with the action you created, write any message you want in ‘notificationContent’ field, and you’re good to go. Now you can start sending push notifications dynamically using Backand.

    Facebook Messenger Bot

    Facebook recently opened up their Messenger platform to enable bots to converse with users through Facebook Apps and on Facebook Pages. In support of this, the Facebook Messenger team created a comprehensive set of documentation describing the functionality on offer. While they offer a lot of functionality and platform-level integration for free, you still need to create a publicly-accessible application that Facebook can communicate with in order to automatically interact with your end users.

    In this tutorial, we'll walk through creating your own messenger bot on the Backand backend-as-a-service system, and make it live - all in 10 minutes.

    Demo

    You can chat with the simple bot example to see the end result at http://m.me/1150283998341709

    Getting Started

    Messenger bots are programs that receive messages from an interface, process those messages, and then send results back to the caller. These results are then displayed to the user by the controlling application - Facebook Messenger in this case. A bot's response can be as simple as echoing text back to the user, or as complex as ordering and shipping new computer components to the end user. The only restrictions are that the bot is authenticated to communicate with Facebook, and that Facebook has approved the bot and allows it to communicate with the world at large.

    Luckily, Backand handles the majority of the server and connectivity functionality for you, allowing you to focus on building out responsive content.

    Building the server

    Follow these steps to build out the back-end to your bot:

    1. Sign up for free at backand.com (if you don't already have an account).

    2. Create a new app in the Backand dashboard, then navigate to that app's management page.

    3. In the new app, open menu Database --> Objects --> Items, and click on the Actions tab. In the Actions tab, click on the Facebook Messenger Bot template.

    4. Click Save

    At this point you have a back-end server that is ready to integrate with Facebook Messenger. However, you need to make a few more configuration changes before you're ready to test.

    Create a Facebook App and Page

    Once you have the back-end and are ready to integrate, the first thing you need to do is create a Facebook Page at https://www.facebook.com/pages/create/?ref_type=pages_browser. This page will serve as the central integration point between your Backand application and Facebook, as the messenger bot is authorized to interact with Facebook on behalf of this page.

    Facebook App Creation

    Once you have the app's page up and running, you need to configure the Facebook integration. To do so:

    image

    image

    image

    Setup Webhooks
    https://api.backand.com/1/objects/action/items?
    name=FBMessengerBot&Authorization=basic+<master token>:<user key>
    

    Once the app page is created, and the app is registered, you need to tell Facebook where to send its messages for processing. You can do this with the following steps:

    image

    image

    Get a Page Access Token

    Once you've configured the app in Facebook, it's time to tie it back into your Backand application. In the Token Generation section, select your Page. A 'Page Access Token' will be generated for you. Copy this 'Page Access Token', and navigate back to your Backand app. Open the Action section of your Items object, and paste the token into the Backand Action where indicated (PAGE_ACCESS_TOKEN).

    image

    Subscribe the App to the Page

    Finally, you need to subscribe to the webhooks available for your page. This is managed in the Webhooks section of the Facebook configuration:

    image

    Run the Bot

    At this point, you're ready to test your bot! Navigate to your Facebook Page and send it a message using Facebook Messenger. You should see the same message echoed back to you with a prefix of "Back& bot says:". This is also sent to the javascript console for immediate analysis.

    image

    At this point your basic bot is working. From here, you can customize the bot's server side to build out functionality for your users

    How to share your bot

    A bot is only useful if people choose to interact with it. Below are some methods you can use to advertise your bot and draw in users.

    Add a chat button to your webpage

    As a part of their initial documentation, Facebook provided an easy method to add a Chat button to your website. The documentation on how to do this is available here.

    You can also implement a shortlink that can be used to initiate a chat with your app. Simply use a URL of the form 'https://m.me/<PAGE_USERNAME>' to begin a Messenger chat.

    What's next?

    At this point, you have a chatbot interacting with Facebook Messenger, driven by Backand as a back-end. You can customize the bot's code to meet your needs by following the information available in the following section of Customize the Bot's Code in a Backand Action.

    You can also review Facebook's complete guide on Messenger integration, which provides more comprehensive detail on the platform's capabilities. These can be used to enhance your message responses, adding web-enabled content that your users can follow.

    Eventually, you'll want to get your bot approved for use by the public. You can find out how to do that here.

    Finally, you can enhance your app's intelligence with an AI integration. Find out how to get started at Wit.ai!

    Customizing the Bot's Code to Receive Messages

    Code to receive messages from Facebook

    if (request.method == "POST"){
    
        var data = request.body;
        if (data.object == 'page') {
    
            // Iterate over each entry
            // There may be multiple if batched
            data.entry.forEach(function(pageEntry) {
    
                var pageID = pageEntry.id;
                var timeOfEvent = pageEntry.time;
    
                // Iterate over each messaging event
                pageEntry.messaging.forEach(function(messagingEvent) {
                    if (messagingEvent.optin) {
                        //receivedAuthentication(messagingEvent);
                    } else if (messagingEvent.message) {
                        receivedMessage(messagingEvent);
                    } else if (messagingEvent.delivery) {
                        //receivedDeliveryConfirmation(messagingEvent);
                    } else if (messagingEvent.postback) {
                        receivedPostback(messagingEvent);
                    } else {
                        console.log("Webhook received unknown messagingEvent: ", messagingEvent);
                    }
                });
            });
        }
    }
    

    All callbacks and webhooks from Facebook will end up in your object's Facebook Action code. The JavaScript for this action is solely responsible for listening to the incoming POST calls, and responding appropriately. The template code handles all webhooks from Facebook by default. For example, receiving messages is handled by looking for the messagingEvent.message field in the webhook, and then calling the receivedMessage() function as seen to the right:

    Customizing the Bot's Code to Send a Text Message

    Sending a message to the user

    function receivedMessage(event) {
    
        var senderID = event.sender.id;
        var recipientID = event.recipient.id;
        var timeOfMessage = event.timestamp;
        var message = event.message;
    
        console.log("Received message for user" + senderID + " and page " + recipientID + " at " + timeOfMessage + " with message");
        console.log(JSON.stringify(message));
    
        var messageId = message.mid;
    
        // You may get a text or attachment but not both
        var messageText = message.text;
        var messageAttachments = message.attachments;
    
        if (messageText) {
    
        // If we receive a text message, check to see if it matches any special
        // keywords and send back the corresponding example. Otherwise, just echo
        // the text we received.
        switch (messageText) {
              case 'image':
                //sendImageMessage(senderID);
                break;
    
              case 'button':
                //sendButtonMessage(senderID);
                break;
    
              case 'backand':
              case 'Backand':
                sendGenericMessage(senderID);
                break;
    
              case 'receipt':
                //sendReceiptMessage(senderID);
                break;
    
              default:
                sendTextMessage(senderID, messageText);
            }
        } else if (messageAttachments) {
            sendTextMessage(senderID, "Message with attachment received");
        }
    };
    

    In receivedMessage, we've added logic that can send a message back to the user. The default behavior is to echo back the text that was received, with some static modifications ('Back& bot says'...)

    sendTextMessage formats the message to be sent to Facebook, then calls the appropriate API endpoint:

    function sendTextMessage(recipientId, messageText) {
        var messageData = {
            recipient: {
              id: recipientId
            },
            message: {
              text: "Back& bot says: " + messageText
            }
        };
    
        callSendAPI(messageData);
    };
    

    callSendAPI calls the Send API to send the message back to the user:

    function callSendAPI(messageData) {
        try{
    
            var response = $http({
                method: "POST",
                url:"https://graph.facebook.com/v2.6/me/messages",
                params:{
                    "access_token": PAGE_ACCESS_TOKEN
                },
                data: messageData,
                headers:{"Content-Type":"application/json"}
            });
    
            var recipientId = response.recipient_id;
            var messageId = response.message_id;
    
            console.log("Successfully sent generic message with id " + messageId + " to recipient " + recipientId);
        }
        catch(err){
            console.error("Unable to send message.");
            console.error(err);
        }
    
    }
    

    Customizing the Bot's Code to Send a Structured Message

    Sending a structured response

    function sendGenericMessage(recipientId) {
        var messageData = {
            recipient: {
                id: recipientId
            },
            message: {
                attachment: {
                    type: "template",
                    payload: {
                        template_type: "generic",
                        elements: [{
                            title: "Messanger BAAS",
                            subtitle: "Backand as a service for Facebook Messanger",
                            item_url: "https://www.backand.com/features/",
                            image_url: "https://www.backand.com/wp-content/uploads/2016/01/endless.gif",
                            buttons: [{
                                type: "web_url",
                                url: "https://www.backand.com/features/",
                                title: "Open Web URL"
                            }, {
                                type: "postback",
                                title: "Call Postback",
                                payload: "Payload for first bubble",
                            }],
                        }, {
                            title: "3rd Party Integrations",
                            subtitle: "Connect your Bot to 3rd party services and applications",
                            item_url: "https://www.backand.com/integrations/",
                            image_url: "https://www.backand.com/wp-content/uploads/2016/01/3.png",
                            buttons: [{
                                type: "web_url",
                                url: "https://www.backand.com/integrations/",
                                title: "Open Web URL"
                            }, {
                                type: "postback",
                                title: "Call Postback",
                                payload: "Payload for second bubble",
                            }]
                        }]
                    }
                }
            }
        };
        callSendAPI(messageData);
    };
    

    receivedMessage can also send back other kinds of messages if it sees certain keywords. For example, if you send the message 'backand', it will call sendGenericMessage() - a function that sends back a Structured Message with a generic template.

    Customizing the Bot's Code to Handle Postbacks

    In our webhook handler, we handle the postback by calling the function receivedPostback():

    ....
    else if (messagingEvent.postback) {
        receivedPostback(messagingEvent);
    }
    ...
    

    Structured messages use postbacks to communicate with your application when a user clicks on one of the provided enhanced objects. The postback message contains the payload that was created for the button in the original Structured Message. Buttons on Structured Messages support both opening URLs and communicating via postbacks.

    This function sends a message back saying that the postback was called:

    function receivedPostback(event) {
        var senderID = event.sender.id;
        var recipientID = event.recipient.id;
        var timeOfPostback = event.timestamp;
    
        // The 'payload' param is a developer-defined field which is set in a postback
        // button for Structured Messages.
        var payload = event.postback.payload;
    
        console.log("Received postback for user " + senderID + " and page " + recipientID + "with payload '" + payload + "' " +
        "at " + timeOfPostback);
    
        // When a postback is called, we'll send a message back to the sender to
        // let them know it was successful
        sendTextMessage(senderID, "Postback called");
    };
    

    From here, you can expand the bot to provide a wealth of functionality to your page's users. Simply expand upon the above code until it meets your requirements.

    SalesforceIQ

    Building and maintaining customer relationships is crucial for driving sales to your platform. However, it can also be a complex process requiring integrating data from multiple sources and, more importantly, ensuring that data is accessible when it is needed. Customer Relationship Management (CRM) software is designed to make this data management and integration process much easier, providing you with the tools you need to drive customers through your sales funnel. In this section, we'll look at integrating a Backand application with Salesforce IQ, providing you with all of the tools you need to effectively leverage your customer data in your Backand application.

    What is SalesforceIQ?

    SalesforceIQ is an out-of-the-box CRM solution that quickly gives you access to dynamic information tied into a full CRM solution. With Automatic Data Capture and enterprise-level intelligence under the hood, SalesforceIQ acts like your own personal assistant so you can focus on what matters most: selling. SalesforceIQ, in addition to providing easy integrations with tools like Google and Microsoft Exchange, also gives you the capability to dynamically access and manage your data through a series of robust APIs.

    Connecting a Backand application with SalesforceIQ

    Integrating Backand and SalesforceIQ is as simple as leveraging the full-featured API provided by Salesforce from within your Backand application. While traditionally you'd need to make these calls to the API from a server, you can achieve the same functionality in Backand by using our custom template action. This action provides an easy-to-use code template for making calls to the SalesforceIQ API, letting you update your user tracking data based upon user activity in your Backand app, or even update your Backand app's UI based upon what you know about your user in SalesforceIQ.

    Working with the SalesforceIQ API provides you with full capabilities to create, retrieve, and update data on your users, as well as manage their information in SalesforceIQ. Communicating with their API is as simple as translating the cURL commands provided by Salesforce in their documentation into the appropriate $http calls that you can make from JavaScript. Simply provide the required authentication and identification headers, construct the URL, make the call, and handle the response when it arrives, dispatching it either directly to your application via a synchronous function call return, or emitting the data as an event using our Socket-based real-time communications functionality.

    The SalesforceIQ Action Template

    /* globals
      $http - Service for AJAX calls
      CONSTS - CONSTS.apiUrl for Backands API URL
      Config - Global Configuration
      socket - Send realtime database communication
      files - file handler, performs upload and delete of files
      request - the current http request
    */
    'use strict';
    function backandCallback(userInput, dbRow, parameters, userProfile) {
    
        var API_KEY = '-- YOUR API --';
        var API_SECRET = '-- YOUR SECRET --';
    
        //get accounts
        var response = $http({
            method: "GET",
            url: "https://api.salesforceiq.com/v2/accounts",
            headers: {
                "Accept":"application/json",
                "Authorization": 'basic ' + btoa(API_KEY + ':' + API_SECRET)
            }
        });
    
        return response;
    }
    

    We have created an action template that will give you jump start with salesforceIQ. You can either trigger this action from an object's database transaction event actions, or create a new on-demand action that you can call from your app's client code. The sample JavaScript is provided by the template action, which is available as SalesforceIQ in the CRM & ERP section of action templates.

    This code provides you with all of the basic tools you need to get connected to the SalesforceIQ API. It takes in your SalesforceIQ API Key and API Secret, and performs a call to the /accounts endpoint to fetch accounts.

    Connecting this action to your SalesforceIQ account

    To connect to SalesforceIQ, you'll first need to register for an account if you haven't done so. Once you've signed up, follow these steps to obtain your API Key and API Secret:

    1. Open Settings under the gear icon
    2. Open the Integration tab under My Account Settings
    3. Under Create New Custom Integration, click Custom
    4. Set the name to Backand API, and provide a description
    5. Copy the API Key and API Secret from the integration page into the JavaScript Action code
    6. Click Save

    When this is completed, you should now be able to access all of your SalesforceIQ accounts from the custom JavaScript action.

    Setup client-side code:

    return $http ({
      url: Backand.getApiUrl() + '/1/objects/action/<your object name>',
        params: {
          name: '<your action name>'
        }
    });
    
    

    Once you've configured the action to connect to SalesforceIQ, you'll need to call the action from your client-side code. To do so, use the JavaScript to the right to construct a GET request and trigger your SalesforceIQ action. Simply replace <your object name> with the object that contains your SalesforceIQ custom action, and replace <your action name> with the name of the action that you provided while creating the integration.

    With these changes, you're now able to pull in any and all SalesforceIQ accounts available via their API! You can use a similar pattern to construct additional calls to the SalesforceIQ API - simply replace the URL and parameters in the custom SalesforceIQ action with the URL and parameters for the object you want to retrieve.

    Salesforce CRM

    As mentioned in our section on integrating with SalesforceIQ, building and maintaining customer relationships is crucial for driving sales to your platform. However, it can also be a complex process requiring integrating data from multiple sources and, more importantly, ensuring that data is accessible when it is needed. Customer Relationship Management (CRM) software is designed to make this data management and integration process much easier, providing you with the tools you need to drive customers through your sales funnel. In this section, we'll look at integrating a Backand application with Salesforce CRM, providing you with all of the tools you need to effectively leverage your customer data in your Backand application.

    What is Salesforce CRM?

    Salesforce CRM is the world's foremost CRM solution, and gives your sales teams the tools they need to close deals. Salesforce CRM is also built in the cloud, meaning that your sales team can increase their productivity and keep the sales pipeline filled with solid leads, all without the need to deploy additional hardware or work around speed limitations. Through Salesforce's REST API you can get easy programmatic access to all of your customer data.

    Connecting a Backand application with Salesforce CRM

    Integrating Backand and SalesforceIQ is as simple as leveraging the full-featured REST API provided by Salesforce from within your Backand application. While traditionally you'd need to make these calls to the API from a server, you can achieve the same functionality in Backand by using our custom template action. This action provides an easy-to-use code template for making calls to the Salesforce REST API, letting you update your user tracking data based upon user activity in your Backand app, or even update your Backand app's UI based upon what you know about your user in Salesforce.

    The Salesforce CRM Action Template

    /* globals
      $http - Service for AJAX calls
      CONSTS - CONSTS.apiUrl for Backands API URL
      Config - Global Configuration
      socket - Send realtime database communication
      files - file handler, performs upload and delete of files
      request - the current http request
    */
    'use strict';
    function backandCallback(userInput, dbRow, parameters, userProfile) {
        // write your code here
        var baseUrl = "https://eu11.salesforce.com/services/data/v37.0/";
    
      // This function manages authenticating with Salesforce, providing the access
      // token as a return value
        var loginSalesForce = function() {
            var client = "-- Your Client Id --"; //Consumer Key
            var secret = "-- Your Secret Id --"; //Consumer Secret
    
            var username = "-- User Username --";
            var password = "-- User Password --";
    
            var loginUrl = "https://login.salesforce.com/services/oauth2/token";
    
            var response = $http({
                method: "POST",
                url: loginUrl,
                data: "grant_type=password" +
                    "&username=" + username +
                    "&password=" + password +
                    "&client_id=" +  client +
                    "&client_secret=" + secret,
                headers: {
                    "Accept":"application/json",
                    "Content-Type": "application/x-www-form-urlencoded"
                }
            });
    
            console.log(response.access_token);
            return response.access_token;
        }
    
        //get access token first. Check if access token exists in cookie session
        var accessToken = cookie.get('sf_access_token');
        if(accessToken == null){
            accessToken = loginSalesForce();
            cookie.put('sf_access_token', accessToken);
        }
    
        //get list of Opportunities
        var opps = $http({
            method: "GET",
            url: baseUrl + "sobjects/Opportunity",
            headers: {"Authorization": "Bearer " + accessToken}
        });
    
        return opps;
    }
    

    We have created an action template that will give you jump start with salesforceCRM. You can either trigger this action with an object's CRUD event handler, or call it on-demand from your client code. The following is the content of the ready action template call Salesforce CRM under the CRM & ERP section:

    Setup access and get client and secret keys

    Follow these steps to obtain your Salesforce CRM authentication information:

    1. Sign in to Salesforce CRM as a user with Admin rights
    2. Open Setup, found under the gear icon
    3. Open App Manager
    4. Click on New Connected App
    5. Provide Connected App Name, API Name, and Contact Email
    6. Check Enable OAuth Settings
      1. Check Enable for Device Flow
      2. Under Selected OAuth Scopes, select Full Access (or any other permissions you need)
    7. Click Save
    8. Copy Consumer Key into the client variable in the code
    9. Copy Consumer Secret into the secret variable in the code

    Once you've obtained the consumer key and the consumer secret, you'll need to enable server-side security in Salesforce. To do so, follow these steps:

    1. From App Manager, select your new App and Click Manage
    2. Click Edit Polices
    3. Change IP Relaxation to Relax IP Restriction, or add Backand's IP to your organization's IP restrictions
    4. Change Timeout Value to 24 hours
    5. Click Save

    With that completed, you should now have full access to your CRM objects using the Salesforce REST API.

    Setup client-side code:

    return $http ({
      url: Backand.getApiUrl() + '/1/objects/action/<your object name>',
        params: {
          name: '<your action name>'
        }
    });
    
    

    Once you've configured the action to connect to Salesforce, you'll need to call the action from your client-side code. To do so, use the following JavaScript to construct a GET request and trigger your Salesforce action:

    Simply replace 'your object name' with the object that contains your Salesforce custom action, and replace 'your action name' with the name of the action that you provided while creating the integration.

    With these changes, you're now able to pull in any and all Salesforce accounts available via their API! You can use a similar pattern to construct additional calls to the Salesforce API - simply replace the URL and parameters in the custom SalesforceCRM action with the URL and parameters for the object you want to retrieve.

    Calling Backand from Native Android Code

    This is a simple class you can use to easily construct API requests to any Backand API URL

    com.backand.backandandroidsample;
    
    import android.util.Base64;
    import android.util.Log;
    
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.URL;
    
    import javax.net.ssl.HttpsURLConnection;
    
    public class BackandConnector {
        private String masterToken;
        private String userToken;
        private String appName;
    
        private final String TAG = "Backand";
        public BackandConnector(String appName, String userToken, String masterToken) {
            this.masterToken = masterToken;
            this.userToken = userToken;
            this.appName = appName;
        }
    
        public String sendGetRequest(URL url) {
            StringBuilder stringBuilder = new StringBuilder();
            String userNamePasswordCombination = this.masterToken + ":" + this.userToken;
            final String basicAuth = "Basic " +  Base64.encodeToString(userNamePasswordCombination.getBytes(), Base64.NO_WRAP);
    
            try {
    
                HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setRequestProperty("Authorization", basicAuth);
                conn.setRequestProperty("Content-Type", "application/json");
                conn.setRequestProperty("AppName", this.appName);
    
                int responseCode = conn.getResponseCode();
                if (responseCode == HttpsURLConnection.HTTP_OK) {
                    String line;
                    InputStream in = conn.getInputStream();
    
                    InputStreamReader isw = new InputStreamReader(in);
    
                    int data = isw.read();
                    while (data != -1) {
                        char current = (char) data;
                        data = isw.read();
                        stringBuilder.append(current);
                    }
                } else {
                    Log.d(TAG, "readRemoteJson: " + conn.getResponseMessage());
                    return "";
                }
            } catch (Exception e) {
                Log.e(TAG, "readRemoteJson error: " + e.getMessage());
            }
            return  stringBuilder.toString();
        }
    }
    

    As Backand is a web API, it can be used by any application that is built on top of a programming language that can make HTTP requests. As an example of this, in this section we'll look at how to connect a native Android application to a Backand back-end using HTTP calls. We'll cover configuring the connection headers, authenticating with Backand, sending requests, and receiving responses. We'll also take a brief look at how to integrate with other Backand SDK functionality.

    Configuring the Connection

    This code takes three arguments - appName, userToken, and masterToken - and populates class member variables with this data. These values are then used in constructing the authentication header for each request.

    public class BackandConnector {
        private String masterToken;
        private String userToken;
        private String appName;
    
        private final String TAG = "Backand";
        public BackandConnector(String appName, String userToken, String masterToken) {
            this.masterToken = masterToken;
            this.userToken = userToken;
            this.appName = appName;
        }
    }
    

    To integrate with Backand, you'll need three pieces of information. The first is the app name, which can be found in the Backand dashboard. The second is the app's Master key. This is found in the application dashboard, under Security --> Social & Keys. Once you've obtained this, you'll also need the User Key. This is a key that is unique to each registered user in your application. It is used to associate the actions being taken in your app with a user, so that you can apply security templates appropriately. Obtain the User Key from Security -> Registered Users - simply click on the "key" icon next to a user record to obtain the key:

    image

    You can store this information in a wrapper class, which you will use to govern all calls to the Backand service. Start by defining the class, along with a constructor that accepts the three authentication values.

    Authenticating

    To authenticate your requests with Backand, you'll need to construct an authentication header. This consists of a Base 64-encoded string consisting of your application's master key and user key, coupled with the word "Basic". The code to construct this header is as follows:

    StringBuilder stringBuilder = new StringBuilder();
    String userNamePasswordCombination = this.masterToken + ":" + this.userToken;
    final String basicAuth = "Basic " +  Base64.encodeToString(userNamePasswordCombination.getBytes(), Base64.NO_WRAP);
    

    You can use Backand's Basic Authentication to authenticate with your app. This uses your app's master key and a user key to authenticate API requests. This works well for server-side (and other non-visible) code, but you should be careful to ensure that your app's Master key is not exposed in source control or via your app - this key bypasses all user authentication, and can be used to perform administrative actions in your app without your knowledge.

    Sending the Request

    This code uses the HttpsUrlConnection object from javax.net.ssl to construct a basic HTTP request to the URL specified. Set the Authorization header to the authorization value you calculated in the previous section, then use the app's name to populate the AppName header. Finally, set the content type to "application/json", and open the connection.

    public String sendGetRequest(URL url) {
        //Auth header generation code here
        try {
    
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Authorization", basicAuth);
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("AppName", this.appName);
    
            // handle response here.
        } catch (Exception e) {
            Log.e(TAG, "readRemoteJson error: " + e.getMessage());
        }
       //return your desired result here
    }
    

    Once you've built out the authentication header, you're ready to fire requests at the API. The Backand API is built as a web API, meaning that you simply need to send HTTP requests to the API URLs in order to obtain and modify your application's data. To the right is some sample code that implements a basic request to a Backand API URL

    Handling the Response

    Below is sample code for handling a response from our API:

      int responseCode = conn.getResponseCode();
      if (responseCode == HttpsURLConnection.HTTP_OK) {
          String line;
          InputStream in = conn.getInputStream();
    
          InputStreamReader isw = new InputStreamReader(in);
    
          int data = isw.read();
          while (data != -1) {
              char current = (char) data;
              data = isw.read();
              stringBuilder.append(current);
          }
      } else {
          Log.d(TAG, "readRemoteJson: " + conn.getResponseMessage());
          return "";
      }
    

    Backand responds to your request with JSON that can be adapted however you wish. The sample code starts by obtaining the response code from the HTTP Request. If the response code indicates success, it uses InputStreamReader to read in the JSON response, to be used elsewhere in your application. Otherwise, it logs the failed request details for later debugging.

    Adding New Functionality

    At this point you have a fully-functional wrapper for calls to any Backand API. Simply create a new instance of this class, supply it with the connection information, and then make your API calls by sending URLs to the method sendGetRequest. You can easily modify this pattern to send POST, PUT, and DELETE requests as you need. Additionally, if you wish to save computation time and effort, you can abstract away the authorization header construction, saving the constructed header instead of rebuilding it every time.

    Conclusion

    As Backand is a web API, it can be easily integrated with nearly every programming language available. While this example focuses on Android, you can use similar code in any popular development language to communicate with Backand's API. Simply construct an authorization header using basic authentication, specify the request URL, and fire the request. Consult our documentation to get started!

    Calling Backand from Native iOS Code

    While you can use a pattern similar to the method used when integrating Backand with a native Android application, Haijian Huo - a developer using Backand in an iOS app - has helpfully developed an SDK wrapper that reduces the complexity of calling the Backand SDK on iOS. See the project on Github at https://github.com/haijianhuo/HHBackand-iOS-SDK!

    The Backand Lambda Launcher

    The Backand Lambda Launcher is a tool we developed to ease the process of executing your AWS Lambda functions. Through use of the Lambda Launcher, you can easily execute any AWS Lambda function in your AWS account. This provides a number of benefits over traditional Lambda execution:

    Configuration

    In order to work with your Lambda functions in Backand, you'll first need to connect Backand to your AWS account. Below, we walk through the process of creating a security policy to govern your integration of AWS Lambda with Backand, creating a user with the security access necessary to connect to your Lambda functions from Backand, and finally configuring Backand to communicate with your AWS Lambda functions.

    These next sections focus on configuring the Lambda Launcher tool from a number of different locations. In all cases, the process will have three primary steps:

    1. Create an IAM Policy to control access to your account's Lambda functions
    2. Create an IAM User that you can use to connect Backand to your AWS account
    3. Connect AWS to Backand using the IAM User's access keys

    In all cases, step 3 - pasting the credentials into Backand - is the same, and as such we present the instructions for that step in a section after the AWS-specific configuration instructions. To create the AWS IAM Policy and User, choose the section most appropriate to your organizational practices from the options below.

    Setting up IAM Access for the Lambda Launcher

    The Backand Lambda Launcher requires the following IAM policies in order to work with your lambda functions:

    Backand takes security very seriously - all credentials entered are encrypted, and never used for any purpose other than executing your Lambda functions. If you would like further assistance in setting up the security policy, please contact us.

    IAM Policy JSON

    The following JSON is to be used when creating the IAM security policy, to manage Backand's access to your AWS Lambda functions

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Stmt1495964947000",
                "Effect": "Allow",
                "Action": [
                    "lambda:GetFunction",
                    "lambda:InvokeAsync",
                    "lambda:InvokeFunction",
                    "lambda:ListFunctions"
                ],
                "Resource": [
                    "*"
                ]
            }
        ]
    }
    

    The Backand Lambda integration relies on the policy JSON provided to the right. This grants Backand the capability to fetch a list of functions, fetch an individual functions, and invoke a function both synchronously and asynchronously.

    From AWS CloudFormation

    If you have admin access to your organization's AWS account, you can use AWS CloudFormation to easily create the appropriate IAM policies and users for Backand's external function links.

    Run this command using the AWS CLI, and we create an IAM user that only has the 'GetFunction', 'InvokeFunction' and 'ListFunctions' policies:

    aws cloudformation create-stack --template-url https://s3.amazonaws.com/cdn.backand.net/cf/1/backand-rc --stack-name createbackanduser --capabilities CAPABILITY_IAM

    Once the IAM user has been created, use this command to obtain the user's access and secret keys, then copy these values into the Connection Details dialog in the Backand dashboard, under Functions & Integrations -> Functions -> External Functions:

    aws cloudformation describe-stacks --stack-name createbackanduser

    From the AWS Console

    If you're already logged into the AWS Console for your region, use the following steps to connect your AWS Lambda functions to Backand:

    Create the IAM Security Policy

    1. Open the IAM service panel
    2. In the navigation menu on the left, select Policies
    3. Click the Create Policy button image
    4. For "Step 1 : Create Policy," select Create Your Own Policy
    5. Set the policy name to BackandLambdaReadExecuteAccess
    6. Paste the policy JSON into the area provided for the Policy Document image
    7. Once the JSON is ready, click Create Policy

    Create the IAM User

    1. On the navigation menu on the left, select Users
    2. Click Add User image
    3. Enter backand_lambda_user as the user name
    4. Check the Programmatic access option image
    5. Click on Next: Permissions
    6. Click on Attach existing policies directly
    7. Search for BackandLambdaReadExecuteAccess, and select it from the search results using the provided checkbox
    8. Click Next : Review
    9. click Create User
    10. On the Complete page of the wizard, click the Show link in the table column Secret access key
    11. Copy the "Access key ID" and "Secret access key" values to use with Backand.

    From the AWS Lambda Service panel

    Using AWS Lambda, you can leverage a python script that we created which goes through the process of creating the IAM Policy and User on your behalf.

    Lambda Python Script

    from __future__ import print_function
    
    import json
    import boto3
    
    print('Loading function')
    
    s3 = boto3.client('s3')
    
    
    def lambda_handler(event, context):
    
        settings = {
            "name" :"backand_lambda_user",
            "policyName":"BackandLambdaReadExecuteAccess",
            "policy": ""
        }
        settings["policy"] = json.dumps({
              'Version': '2012-10-17',
              'Statement': [
                {
                  'Sid': 'Stmt1494926726830',
                  'Action': [
                    'lambda:GetFunction',
                    'lambda:InvokeAsync',
                    'lambda:InvokeFunction',
                    'lambda:ListFunctions'
                  ],
                  'Effect': 'Allow',
                  'Resource': '*'
                }
              ]
            })
        client = boto3.client('iam')
        response = client.create_user(
            UserName=settings["name"]
        )
        print(response);
        accessReponse = client.create_access_key(
            UserName=settings["name"]
        )
        print(accessReponse)
        policy = client.create_policy(
            PolicyName= settings["policyName"],
            PolicyDocument=settings["policy"]
        )
        print(policy)
        user_policy = client.attach_user_policy(
            UserName=settings["name"],
            PolicyArn=policy["Policy"]["Arn"]
        )
        return {
            'AccessKey': accessReponse["AccessKey"]["AccessKeyId"],
            "SecretKey":accessReponse["AccessKey"]["SecretAccessKey"]
    
        }
    

    This approach uses a python script to create the appropriate IAM resources. This script is provided in the right-hand panel, and should be used as the body of the Lambda action that will perform the required resource allocation in IAM.

    Create the Lambda Function

    1. go to Lambda service panel
    2. Select the "Blank Function and click "Next"
    3. name your function "createBackandLambdaUser"
    4. Select the "Python 3.6" runtime
    5. paste the lambda python code into the provided area. image
    6. in the Role dropdown select "Create Custome Role"
    7. in the "AWS Lambda requires access to your resources" window, select "Create new Role Policy"
    8. click "View Policy Document" and click the Edit button on the right image
    9. approve the "Edit Policy" pop-up image
    10. Paste the policy JSON into the area provided for the Policy Document and click "Allow" image
    11. click "Next"
    12. click "Create Function"
    13. after the function was created , click "Test", image
    14. Copy the "Access key ID" and "Secret access key" values to use with Backand.

    From the AWS CLI

    If you primarily use the AWS CLI to interact with AWS, you can easily connect Backand to your AWS account using the following steps:

    Create the IAM Policy and User

    First, ensure that all files involved are saved in an ASCII-encoded format. Before starting, you'll need to create a new file in the current directroy - createBackandLambdaUser.json - and populate it with the policy JSON before starting. Then, run the following series of commands to create the IAM Policy and User in your account:

    1. aws iam create-policy --policy-name BackandLambdaReadExecuteAccess --policy-document file://createBackandLambdaUser.json ( and copy the policy arn for step 4)arn:aws:iam::<>:policy/BackandLambdaReadExecuteAccess
    2. aws iam create-user --user-name backand_lambda_user
    3. aws iam attach-user-policy --user-name backand_lambda_user --policy-arn arn:aws:iam::<>:policy/BackandLambdaReadExecuteAccess
    4. aws iam create-access-key --user-name backand_lambda_user
    5. Copy the "Access key ID" and "Secret access key" values to use with Backand.

    Creating Cross-Account Access for AWS Lambda

    You can create an IAM role and user that span multiple AWS accounts, allowing you to bring your lambda functions from multiple AWS accounts into a single interface. This method creates a restricted linkage between your AWS account and Backand, allowing you to import your personal Lambda functions into your Backand application.

    Obtaining the AWS Account ID

    This approach relies upon obtaining your AWS Account ID. To do this:

    Save this ID for use in later configuration steps.

    AWS CLI

    Using CloudFormation, we'll create a stack that we'll use to drive cross-account integration with Backand. Use the following AWS CLI command to get started:

    aws cloudformation create-stack --template-url https://s3.amazonaws.com/cdn.backand.net/cf/1/backand-cc --parameters ParameterKey=ExternalId,ParameterValue=bknd_{{appMasterToken}} --stack-name createBkndCrossAccess --capabilities CAPABILITY_NAMED_IAM

    AWS Management Console

    Instead of achieving the above via CLI, you can perform the same actions in the AWS Management console. To get started, open the AWS Management Console as an account administrator, and pull up the IAM console. Before you create the role, you'll need to create a managed policy that defines the permissions required by the IAM role to be created. You will attach this policy to the new role in a later step.

    In the navigation pane, on the left side of the screen, select Policies, and then select Create Policy

    Step 1 - Create Policy
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Stmt1500562449000",
                "Effect": "Allow",
                "Action": [
                    "lambda:CreateFunction",
                    "lambda:GetFunction",
                    "lambda:InvokeFunction",
                    "lambda:InvokeAsync",
                    "lambda:ListFunctions",
                    "lambda:ListVersionsByFunction"
                ],
                "Resource": "*"
            }
        ]
    }
    

    For Step 1: Create Policy, select Create Your own Policy. Name the policy BackandCrossAccountPolicy.

    Next, set the Policy Document to the JSON on the right. Once this is done, the policy should appear in your list of managed policies.

    When you've completed your changes, the screen should look like the following:

    image

    Step 2 - Create a Role

    The next step is to create an IAM Role.

    1. Open the IAM Console for this account
    2. Click Roles
    3. For Step 1: Select Role Type, select and expand the "Role for cross-account access" option.
    4. Select Provide access between your AWS account and a third party AWS accountimage
    5. On the next page, set Backand's account ID and external ID to the following values:
      • Account ID: 328923390206
      • External ID: bknd_{{appsMasterToken}} image
    6. Click Next Step
    7. Attach the policy created above by selecting it from the provided list
    8. Click Next Step
    9. Set the role name to BackandCrossAccountRole image
    10. Click Create Role

    Reference documentation

    Connect the IAM User to Backand

    If you are configuring your Lambda Launcher access for the first time, via the modal dialog, you can simply paste your Access Key ID and Secret Access Key into the provided fields. If you have an existing app, you can update those from the External Functions page:

    1. Open the Backand App Dashboard
    2. Select the Functions & Integrations tab, if it is not already selected
    3. Select External Functions, under Functions in the left-hand navigation menu
    4. Provide the Access Key, Secret Key, and Region in the provided fields
    5. Press Link

    At this point, your AWS Lambda functions should be listed in the Backand interface.