Backendless REST API © 2015 Backendless Corp. Backendless REST API © 2015 Backendless Corp. All rights reserved. No parts of this work may be reproduced in any form or by any means - graphic, electronic, or mechanical, including photocopying, recording, taping, or information storage and retrieval systems - without the written permission of the publisher. Products that are referred to in this document may be either trademarks and/or registered trademarks of the respective owners. The publisher and the author make no claim to these trademarks. While every precaution has been taken in the preparation of this document, the publisher and the author assume no responsibility for errors or omissions, or for damages resulting from the use of information contained in this document or from the use of programs and source code that may accompany it. In no event shall the publisher and the author be liable for any loss of profit or any other commercial damage caused or alleged to have been caused directly or indirectly by this document. Generated on: December 2015 Special thanks to: All the people who contributed to this document, to everyone who has helped us out with the vision for the product, feature suggestions and ideas for improvements. Special thank s to our families for your support, encouragement and patience. Contents 3 Table of Contents User Service 6 1 Overview ................................................................................................................................... 6 2 User Properties ................................................................................................................................... 6 3 User Registration ................................................................................................................................... 7 4 Login................................................................................................................................... 11 5 Update ................................................................................................................................... User Properties 16 6 Logout ................................................................................................................................... 19 7 Password ................................................................................................................................... Recovery 22 8 Security ................................................................................................................................... 24 9 User to ................................................................................................................................... Role Mapping 28 Data Service 34 1 Overview ................................................................................................................................... 34 2 Setup................................................................................................................................... 35 3 Native................................................................................................................................... vs External Databases 36 4 Using................................................................................................................................... External Databases 37 5 Data Object ................................................................................................................................... 41 6 Saving ................................................................................................................................... Data Objects 41 7 Updating ................................................................................................................................... Data Objects 42 8 Deleting ................................................................................................................................... Data Objects 45 9 Retrieving ................................................................................................................................... Schema Definition 48 10 Basic................................................................................................................................... Search 49 11 Advanced ................................................................................................................................... Search 50 12 Using................................................................................................................................... Dates in Search 52 13 Relations ................................................................................................................................... Overview 54 14 Relations ................................................................................................................................... (Save/Update) 59 15 Relations ................................................................................................................................... (Delete) 62 16 Relations ................................................................................................................................... (Retrieve) 63 17 Relations ................................................................................................................................... with Geo Points 67 18 Security ................................................................................................................................... 73 Messaging Service 79 1 Overview ................................................................................................................................... 79 2 Setup................................................................................................................................... 80 3 Core ................................................................................................................................... Classes 81 © 2015 Backendless Corp. 3 4 Backendless REST API 4 Push ................................................................................................................................... Notification Setup (Android) 82 5 Push ................................................................................................................................... Notification Setup (iOS) 84 6 Managing ................................................................................................................................... Registrations 94 7 Message ................................................................................................................................... Publishing 96 8 Publish ................................................................................................................................... Push Notifications 99 9 Cancel ................................................................................................................................... Scheduled Message 100 10 Message ................................................................................................................................... Subscription 101 11 Sending ................................................................................................................................... Email 102 File Service 104 1 Overview ................................................................................................................................... 104 2 Setup ................................................................................................................................... 104 3 Handling ................................................................................................................................... Files via Console 106 4 File ................................................................................................................................... Upload 110 5 Save................................................................................................................................... Files From Byte Arrays 111 6 File ................................................................................................................................... Download 112 7 File ................................................................................................................................... Deletion 114 8 Directory ................................................................................................................................... Deletion 114 9 Git Integration ................................................................................................................................... 114 10 Web................................................................................................................................... Hosting 116 11 Custom ................................................................................................................................... Domain Name 117 12 Custom ................................................................................................................................... Web Template Hosting 118 13 Files................................................................................................................................... Security 121 Geo Service 122 1 Overview ................................................................................................................................... 122 2 Setup ................................................................................................................................... 124 3 Adding ................................................................................................................................... a Geo Category 125 4 Deleting ................................................................................................................................... a Geo Category 127 5 Retrieving ................................................................................................................................... Geo Categories 129 6 Adding ................................................................................................................................... a GeoPoint 129 7 Updating ................................................................................................................................... a GeoPoint 129 8 Deleting ................................................................................................................................... a GeoPoint 129 9 Importing ................................................................................................................................... Geo Data 131 10 Search ................................................................................................................................... in Category 132 11 Search ................................................................................................................................... in Radius 133 12 Search ................................................................................................................................... in Rectangular Area 134 13 Geo................................................................................................................................... Point Clustering 135 14 Relations ................................................................................................................................... with Data Objects 139 15 Geofence ................................................................................................................................... Designer 142 © 2015 Backendless Corp. Contents 5 16 Geofence ................................................................................................................................... API 153 Index 156 © 2015 Backendless Corp. 5 6 Backendless REST API 1 User Service 1.1 Overview The Backendless User Service empowers applications with the functionality related to the user accounts such as user registrations, logins, password recovery and logouts. The core concept which the User Service relies on is the User entity. The structure of the entity is configurable, that is a developer can decide which properties "describe" a user in the context of a given version of the application. Typically, properties describing a user are the ones collected during the user registration process. The User Service provides the API enabling the following functionality for the applications built on top of Backendless: User Registration - Applications use the Backendless' registration API to let the users register and create accounts for subsequent logins. Application developers can restrict access to the server-side resources for specific user accounts or based on roles. User Login - the API lets the registered users login to establish their identity within the application. Password Recovery - Backendless supports a complete workflow allowing users to recover lost or forgotten passwords. User Logout - the API lets the logged in users terminate their session and disassociate their identity from the application. Updating User Registration - the API supports the operation of updating user information. 1.2 User Properties When a user registers with an application, he provides information which establishes the person's identity. For one application these properties may include name, phone number and email address, for another it could be user id, age and gender. Backendless User Service allows each application to have a custom set of properties associated with the user entity. There are two ways to define what properties the User entity should have in a Backendless application: Defining properties with Console User property management is available on the User Properties screen of the console. To get to the screen: 1. Login to the console 2. Select the desired application and version 3. Click the Users icon on the left side of the interface. The "User Properties" panel is selected by default. The interface consists of two lists: Available Properties and Selected Properties. The Selected Properties list contains the properties assigned to the User entity - these are the effective properties for the selected version of the application. The Available Properties list is simply a storage for the noneffective properties which can be moved to the Selected list if needed. A property can be moved between the lists by clicking its name. Identity Property Among the Selected Properties, one must be marked as identity. This is the property Backendless uses for the Login and Restore Password operations.. As users register, Backendless ensures the provided value for the property selected as identity is unique in the context of a specific version for an application. Password Property © 2015 Backendless Corp. User Service 7 "password" is a special property. Backendless automatically adds the property when an application is created. The following rules apply to the password property: Password cannot be moved out of the Available Properties list. Password cannot be marked as Identity. Password is always a required property To add a property, click the "Add Custom Property" button. New properties automatically added to the Selected Properties list. To move a property to the other list, simply click its name. Defining properties with API User properties can be defined with the user registration API call. For any property specified in the object with the user registration information Backendless creates a user property. This behavior can be turned off/on using the Dynamic User Definition configuration setting in the console (select the Users >> User Properties). The setting is turned on by default: 1.3 User Registration The user registration API can be used to create user accounts in the application. The registration request must provide a user object as a collection of key/value properties. The collection must contain all the required properties which must include a property marked as identity as well as the "password" property. Unless the properties are modified in the console, the default property marked as identity is "email" . Additionally, the "email" property is required if the application is configured to confirm email addresses for the registered users. Method: © 2015 Backendless Corp. 8 Backendless REST API POST URL: /<version name>/users/register Request Headers: application-id: app-id-value secret-key: secret-key-value Content-Type:application/json application-type: REST where: application-id secret-key Content-Type application-type - the ID of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the key of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the static value, should be set to application/json. This header is mandatory. - the static value, should be set to REST. This header is mandatory. How to obtain application-id and secret-key: Values for the application-id and secret-key headers must be obtained through the Backendless Console: 1. Login to your account and select the application. 2. Click the Manage icon from the vertical icon-menu on the left. 3. The "App Settings" section is selected by default. The interface contains the text fields for "Application ID" and secret keys for each supported client-side environment. 4. Use the "Copy" button to copy the value into the system clipboard. © 2015 Backendless Corp. User Service Request Body: { "email" : value, "password" : value, … } Response Body: { "objectId" : value, "email" : value, "password" : value, … } Errors: When the server-side reports an error, it returns a JSON object in the following format: { "message":error-message, "code":error-code } © 2015 Backendless Corp. 9 10 Backendless REST API Error codes returned by the registration API are listed below: Error Code Description 2002 Version is disabled or provided wrong application info (application id or secret key) 3009 User registration is disabled for the version of the application 3010 User registration has an unknown property and dynamic properties are disabled for this version of the application 3011 Missing "password" property 3012 Required property is missing 3013 Missing value for the identity property 3014 External registration failed with an error. 3021 General user registration error. Details included with the error message. 3033 User with the same identity already exists 3038 Missing application-id, version name or collection of properties for the registering user 3039 Property "id" cannot be used in the registration call 3040 Email address is in the wrong format 3041 A value for a required property is missing 3043 Duplicate properties in the registration request 8000 Property value exceeds the length limit Example: curl -H application-id:application-id -H secret-key:secret-key -H application-type:REST -H Content-Type:application/json -X POST -d '{"name":"James Bond", "password":"watchingya", "email":"jbond@007.com"}' -v https://api.backendless.com/v1/users/register Turning Registration Off User registration can be disabled for a particular version of the application using the Backendless Console: 1. Login to the console and select the application. 2. Click the "Users" icon in the vertical icon menu on the left. 3. Click "Registration". The "Registration" toggle turns the registration API on or off. When the registration is turned off and a user attempts to register, the system returns error 3009 . © 2015 Backendless Corp. User Service 11 Email Confirmations Backendless can send out an email requesting new registered users to confirm their email address. This feature can be configured in the Backendless Console: 1. Log into the console and select the application. 2. Click the "Users" icon in the vertical icon menu on the left. 3. Click "Registration". When email confirmations are required (the feature is enabled by default), the "email" user property is required and must contain a value formatted as an email address. To configure the text of the email message, select "Communication & Email Templates" from the Users menu in the console and select the "User registers" event. External Registration User registrations can be duplicated in an external system through the External Registration Callback. Developer can specify a URL where Backendless sends a POST request to with the user registration data as a JSON object. The external registration callback is synchronous and takes place in the same transaction as the Backendless registration call. As a result, the external system must return result as fast as possible. The format of the request and response for the external registration is the same as the request/response body of the Backendless registration API. To configure the callback: 1. Login to the console and select the application. 2. Click the "Users" icon in the vertical icon menu on the left. 3. Click "Registration". 4. Turn on the "Execute registration callback" toggle. 5. Enter the URL of the script into the "Callback URL" text field. 1.4 Login Registered users can login to establish their identity with the application using the API below. The login operation requires two properties: one marked as user identity and the second is password . Backendless automatically assigns the "AuthenticatedUser" role to all successfully logged in users. The role can be used to differentiate access to various resources (persistent objects, messaging channels, media streams) between authenticated users and guests. Method: © 2015 Backendless Corp. 12 Backendless REST API POST URL: /<version name>/users/login Request Headers: application-id: app-id-value secret-key: secret-key-value Content-Type:application/json application-type: REST where: application-id secret-key Content-Type application-type - the ID of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the key of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the static value, should be set to application/json. This header is mandatory. - the static value, should be set to REST. This header is mandatory. How to obtain application-id and secret-key: Values for the application-id and secret-key headers must be obtained through the Backendless Console: 1. Login to your account and select the application. 2. Click the Manage icon from the vertical icon-menu on the left. 3. The "App Settings" section is selected by default. The interface contains the text fields for "Application ID" and secret keys for each supported client-side environment. 4. Use the "Copy" button to copy the value into the system clipboard. © 2015 Backendless Corp. User Service 13 Request Body: { "login" : value, "password" : value, } The value for the "login" key must be the value for the property marked as identity. Response Body: { "objectId" : value, "user-token": value, //all user properties (except for password) in the "propname":"prop-value" format "prop-name1":value, "prop-name2":value, "prop-name3":value, ... } The "objectId" property is a unique identifier assigned by Backendless to the user account. The "user-token" value identifies the user session initiated by the Login operation. Both of these values ("objectId" and "user-token" ) are required for Updating User Properties. © 2015 Backendless Corp. 14 Backendless REST API Maintaining User Session: The "user-token" value returned from the login must be used in all subsequent request to Backendless in order to maintain user session. The value uniquely identifies both user and the session on the server and is used to enforce security policy, apply user and user roles permissions and track usage analytics. For all requests made after the login, the "user-token" value must be sent as an HTTP header: "user-token":value Errors: When the server-side reports an error, it returns a JSON object in the following format: { "message":error-message, "code":error-code } Error codes returned by the registration API are listed below: Error Description Code 2002 Version is disabled or provided wrong application info (application id or secret key) 3000 Login has been disabled for the user account. 3001 Missing login settings, possibly invalid application id or version. 3002 User cannot login because Multiple Logins disabled and there is a logged in user for the account. 3003 Invalid login or password. 3006 Either login or password is an empty string value. 3034 User logins are disabled for the version of the application. 3036 Account locked out due to too many failed logins. 3038 One of the required parameters (application id, version, login or password) is null 3044 Multiple login limit for the same user account has been reached. 8000 Property value exceeds the length limit Example: curl -H application-id:application-id -H secret-key:secret-key -H application-type:REST -H Content-Type:application/json -X POST -d '{"login":"jbond@007.com", "password":"watchingya"}' -v https://api.backendless.com/v1/users/login External Authentication © 2015 Backendless Corp. User Service 15 Similar to external registration, Backendless supports external authentication. When configured, Backendless delegates the authentication process to an external system by sending the provided user credentials to a URL. The URL of the external authentication system can be configured in Backendless Console: 1. Log into the console and select the application. 2. Click the "Users" icon in the vertical icon menu on the left. 3. Click "Login". 4. The "External authentication" section contains the configuration settings. When the external authentication is enabled and user attempts to login, Backendless sends the following request to the specified URL: POST http://external-authentication-url Authorization: Basic base64-encoded-login:password Where base64-encoded-login:password is constructed as follows: 1. login and password are combined into a string "login:password" 2. The resulting string literal is then encoded using Base64 Multiple Logins The Multiple Logins feature enables login using the same account from different computers or devices. Multiple logins can be configured in the Backendless Console: 1. Log into the console and select the application. 2. Click the "Users" icon in the vertical icon menu on the left. 3. Click "Login". 4. The "Multiple Logins" section contains the configuration settings. When the feature is turned on (multiple logins allowed), the configuration setting may include the maximum number of simultaneous logins for the selected version of the application. When the feature is disabled (multiple logins are not allowed), the configuration must indicate whether which login should be invalidated (first or second for the account): Session Timeout Backendless supports session expiration which can be configured in console. Along with the session timeout interval, the configuration can also include a forwarding URL which is used to © 2015 Backendless Corp. 16 Backendless REST API redirect requests to for the expired sessions. Account Lockout An application powered by Backendless can be configured to lock out accounts with failed logins. The console has two configuration options: number of failed logins before the account is locked and a time interval to wait before the account is available for logins again. 1.5 Update User Properties Backendless supports the operation of user properties update for the logged in users. This operation is useful if an application needs to provide to the users the functionality for updating user profiles and registration properties. User must be logged in in order to update his registration properties. Method: PUT URL: /<version name>/users/<user-id> where <user-id> is a value of the "id" property received in the response for the Login operation. Request Headers: application-id: app-id-value secret-key: secret-key-value Content-Type:application/json application-type: REST user-token: value-of-the-user-token-header-from-login << optional header where: © 2015 Backendless Corp. User Service application-id secret-key Content-Type application-type user-token 17 - the ID of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the key of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the static value, should be set to application/json. This header is mandatory. - the static value, should be set to REST. This header is mandatory. - the ID of the user object that sends the request. If the value is set, it will be assigned to the ownerId property of the object to facilitate the object retrieval according to "Owner Policy." This header is optional. The value for the user- token header can be obtained in the response of the preceding Login operation. How to obtain application-id and secret-key: Values for the application-id and secret-key headers must be obtained through the Backendless Console: 1. Login to your account and select the application. 2. Click the Manage icon from the vertical icon-menu on the left. 3. The "App Settings" section is selected by default. The interface contains the text fields for "Application ID" and secret keys for each supported client-side environment. 4. Use the "Copy" button to copy the value into the system clipboard. © 2015 Backendless Corp. 18 Backendless REST API Request Body: { "email" : value, "password" : value, … } Response Body: { "email" : value, "password" : value, … } Errors: When the server-side reports an error, it returns a JSON object in the following format: { "message":error-message, "code":error-code } Error codes returned by the registration API are listed below: © 2015 Backendless Corp. User Service Error Code Description 2002 Version is disabled or provided wrong application info (application id or secret key) 3018 The property marked as "identity" is being updated and another user already has the specified value which must be unique. 3024 General "update registration" error. Error message should contain additional details. 3028 User is not logged in. 3029 Cannot modify properties of another user. Returned when one user is logged and the call attempts to modify properties of another user. 3030 Unable to locate user account - invalid user id. 3031 A new "dynamic" property is being added, but dynamic property definition is disabled. 3045 Required properties in the provided object do not contain values. 19 Example: curl -H application-id:application-id -H secret-key:secret-key -H application-type:REST -H user-token:value-of-user-token-from-login -H Content-Type:application/json -X PUT -d '{"phoneNumber":"5551212"}' -v https://api.backendless.com/v1/users/value-of-id-from-login 1.6 Logout The Logout operation terminates user session and disassociates the AuthenticatedUser role from the subsequent requests made by the client application. Method: GET URL: /<version name>/users/logout Request Headers: application-id: app-id-value secret-key: secret-key-value user-token: value-of-the-user-token-header-from-login application-type: REST where: application-id © 2015 Backendless Corp. - the ID of your application generated upon its creation. You can find 20 Backendless REST API secret-key user-token application-type this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the key of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the ID of the user object that sends the request. If the value is set, it will be assigned to the ownerId property of the object to facilitate the object retrieval according to "Owner Policy." This header is optional. The value for the usertoken header can be obtained in the response of the preceding Login operation. - the static value, should be set to REST. This header is mandatory. How to obtain application-id and secret-key: Values for the application-id and secret-key headers must be obtained through the Backendless Console: 1. Login to your account and select the application. 2. Click the Manage icon from the vertical icon-menu on the left. 3. The "App Settings" section is selected by default. The interface contains the text fields for "Application ID" and secret keys for each supported client-side environment. 4. Use the "Copy" button to copy the value into the system clipboard. © 2015 Backendless Corp. User Service Request Body: None Response Body: None Errors: When the server-side reports an error, it returns a JSON object in the following format: { "message":error-message, "code":error-code } Error codes returned by the registration API are listed below: Error Code Description 2002 Version is disabled or provided wrong application info (application id or secret key) 3007 Invalid application-id or version. 3023 General error while executing logout. Error details should be available in the message property. © 2015 Backendless Corp. 21 22 Backendless REST API Example: curl -H application-id:application-id -H secret-key:secret-key -H application-type:REST -H user-token:value-of-user-token-from-login -v https://api.backendless.com/v1/users/logout 1.7 Password Recovery Password recovery sends an email to the user's email address with a link where the user can change the password. Method: GET URL: /<version name>/users/restorepassword/<user-identity-property> where <user-identity-property> is a value for the property marked as identity. The value must be URL-encoded. Request Headers: application-id: app-id-value secret-key: secret-key-value application-type: REST where: application-id secret-key application-type - the ID of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the key of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the static value, should be set to REST. This header is mandatory. How to obtain application-id and secret-key: Values for the application-id and secret-key headers must be obtained through the © 2015 Backendless Corp. User Service 23 Backendless Console: 1. Login to your account and select the application. 2. Click the Manage icon from the vertical icon-menu on the left. 3. The "App Settings" section is selected by default. The interface contains the text fields for "Application ID" and secret keys for each supported client-side environment. 4. Use the "Copy" button to copy the value into the system clipboard. Request Body: None Response Body: None Errors: When the server-side reports an error, it returns a JSON object in the following format: { "message":error-message, "code":error-code } Error codes returned by the registration API are listed below: Error Code Description © 2015 Backendless Corp. 24 Backendless REST API 2002 Version is disabled or provided wrong application info (application id or secret key) 3020 Unable to find user with the specified login (invalid user identity). 3025 General password recovery error. Additional details should be available in the "message" property of the response. 3038 One of the requirement arguments (application id, version or user identity) is missing. Example: curl -H application-id:application-id -H secret-key:secret-key -H application-type:REST -v -X GET https://api.backendless.com/v1/users/restorepassword/myusername 1.8 Security All Backendless API operations can be restricted either for specific user accounts or for roles. A user account may be associated with one or more roles. Backendless supports several built-in system roles as well as developer-defined roles. The system roles include: NotAuthenticatedUser - any user who has not authenticated to a Backendless application. AuthenticatedUser - any user who has successfully logged in. SocialUser - any user who has logged in through a social network. FacebookUser - any user who has logged in with a Facebook account. TwitterUser - any user who has logged in with a Twitter account. Developer-defined roles can be added using the Backendless Console. Roles are defined at the application version level, that is a particular version of an application may have its own set of developerdefined roles. Backendless manages permissions as tuples consisting of: Operation - Users interact with Backendless either via console or the API. Any request to Backendless is an operation which may have a permission associated with it. Resource - Some operations target specific resources. These can be data tables, messaging channels or media tubes. Principal - Either a specific user identity or a role associated with the user initiating the operation. There are two levels of permissions for the API operations - global and resource-specific. The resourcespecific permissions guard access to the specific resources (data tables, messaging channels, etc). They have higher priority and are checked first. When Backendless receives an API call from a client, it determines the user associated with the request and obtains a list of roles associated with the user account (for the users who have not authenticated, the NotAuthenticatedUser role is used). The resource-specific permissions can be set to either inherit the permission from the global matrix or explicitly grant or deny access to the resource for the given user or role. The diagram below illustrates the process when the resource-specific permission is set to inherit: © 2015 Backendless Corp. User Service 25 When the resource-specific permission is explicitly set to either grant or deny access, the global permissions are bypassed: Global Permissions The global service permissions apply to all resources managed by a particular service. For example, global Data Service permissions for a particular role apply to all data tables. These permissions can be viewed and modified by clicking a role on the Users > Security and Restrictions screen in Backendless Console: © 2015 Backendless Corp. 26 Backendless REST API The table below shows a global permissions matrix for a role: © 2015 Backendless Corp. User Service 27 Each global permission has two states: Grant - represented by a green check mark - grants the rights to execute an operation Deny - represented by a red X - denies the rights to execute an operation. To change a permission click the icon of the current state. The change will be effective immediately. To register a new role use the "Add Role" button on the "Security and Restrictions" screen. Once a role is added, you can configure it's global permission matrix as well as resource-specific permissions. Resource-Specific Permissions To view, assign or modify resource-specific permissions, use a corresponding screen in the Backendless Console. For example, to restrict access to a data table, switch to the Data view, select a table and click the "Schema and Permissions" button. The user interface has two views - one is for managing permissions for user accounts and the other for roles. To modify permissions for a user account: 1. Click the "User Permissions" list item. 2. Enter the user name in the search field. 3. Select the user and click the "Add" button. 4. The table displays the permissions for various operations for the selected user and the resource. 5. Click an icon representing the permission state to modify the permission. © 2015 Backendless Corp. 28 Backendless REST API Similarly permissions can be assigned or modified for specific roles - use the "Role Permissions" list item. To modify the permissions for Messaging channels, click the "Messaging" icon, select a channel and switch to the "Permissions" view. 1.9 User to Role Mapping User accounts can be mapped to roles using the API documented below. Once a role is assigned to a user account, any permissions assigned to the role (both grant and deny) automatically apply to all API operations executed by the application on behalf of the user. Roles can be assigned to users in Custom Business Logic. This can be accomplished using the custom events. When the code makes a request, make sure the application-type HTTP header contains the value of "BL." Retrieving User's Roles This operation retrieves a list of the roles associated with the account of the currently logged in user. If you send the request without a logged in user, the system will return only one role NotAuthenticatedUser. Method: GET URL: /<version>/users/userroles where: <version> - name of the application's version. Application versions can be managed using Backendless Console. Login to the console, select an application, click Manage, then Versioning. Backendless automatically creates version "v1 " for any new application. Request Headers: application-id: app-id-value secret-key: secret-key-value Content-Type: application/json application-type: REST where: application-id - the ID of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining © 2015 Backendless Corp. User Service secret-key Content-Type application-type 29 Application ID and Secret Key section for information on how to obtain the values for the header. - the key of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the static value, should be set to application/json. This header is mandatory. - the static value, should be set to REST. This header is mandatory. Request Body: None Response Body: [ "roleName1", "roleName2" ] Assigning a Role to a User Account Method: POST URL: /<version name>/users/assignRole Request Headers: application-id: app-id-value secret-key: secret-key-value Content-Type:application/json application-type: BL where: application-id secret-key © 2015 Backendless Corp. - the ID of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the key of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This 30 Backendless REST API Content-Type application-type header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the static value, should be set to application/json. This header is mandatory. - the static value, should be set to BL. This header is mandatory. How to obtain application-id and secret-key: Values for the application-id and secret-key headers must be obtained through the Backendless Console: 1. Login to your account and select the application. 2. Click the Manage icon from the vertical icon-menu on the left. 3. The "App Settings" section is selected by default. The interface contains the text fields for "Application ID" and secret keys for each supported client-side environment. 4. Use the "Copy" button to copy the value into the system clipboard. Request Body: { "user" : value, © 2015 Backendless Corp. User Service 31 "roleName" : value, } The value for the "user" key must be the value for the property marked as identity. Response Body: None Errors: When the server-side reports an error, it returns a JSON object in the following format: { "message":error-message, "code":error-code } Error codes returned by the registration API are listed below: Error Code Description 2002 Version is disabled or provided wrong application info (application id or secret key) 2005 Could not find role. 3038 One of the required parameters (user identity or roleName) is null. 3057 Could not find user by id or identity. 3058 Could not assign role to user. 3059 Could not unassign role to user. Example: curl -H application-id:application-id -H secret-key:secret-key -H application-type:BL -H Content-Type:application/json -X POST -d '{"user":"jbond@007.com", "roleName":"SuperAgent"}' -v https://api.backendless.com/v1/users/assignRole Unassigning a Role from a User Account Method: POST URL: /<version name>/users/unassignRole Request Headers: application-id: app-id-value secret-key: secret-key-value © 2015 Backendless Corp. 32 Backendless REST API Content-Type:application/json application-type: BL where: application-id secret-key Content-Type application-type - the ID of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the key of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Obtaining Application ID and Secret Key section for information on how to obtain the values for the header. - the static value, should be set to application/json. This header is mandatory. - the static value, should be set to BL. This header is mandatory. How to obtain application-id and secret-key: Values for the application-id and secret-key headers must be obtained through the Backendless Console: 1. Login to your account and select the application. 2. Click the Manage icon from the vertical icon-menu on the left. 3. The "App Settings" section is selected by default. The interface contains the text fields for "Application ID" and secret keys for each supported client-side environment. 4. Use the "Copy" button to copy the value into the system clipboard. © 2015 Backendless Corp. User Service 33 Request Body: { "user" : value, "roleName" : value, } The value for the "user" key must be the value for the property marked as identity. Response Body: None Errors: When the server-side reports an error, it returns a JSON object in the following format: { "message":error-message, "code":error-code } Error codes returned by the registration API are listed below: Error Code Description 2002 Version is disabled or provided wrong application info (application id or secret key) © 2015 Backendless Corp. 34 Backendless REST API 2005 Could not find role. 3038 One of the required parameters (user identity or roleName) is null. 3057 Could not find user by id or identity. 3058 Could not assign role to user. 3059 Could not unassign role to user. Example: curl -H application-id:application-id -H secret-key:secret-key -H application-type:BL -H Content-Type:application/json -X POST -d '{"user":"jbond@007.com", "roleName":"SuperAgent"}' -v https://api.backendless.com/v1/users/unassignRole 2 Data Service 2.1 Overview The Backendless Data Service is a highly scalable, object storage system. It is available via intuitive API which supports all basic data persistence operations - Create, Retrieve, Update and Delete (CRUD). The Data Service operates with persistent data at the object level, that means applications use the APIs to save, update, delete or search for objects, rather than traditional database records. Developers using the Data Service API do not need to know or understand the databases, schema creation rules, stored procedures or SQL syntax. The Data Service follows the following rules when working with user objects: 1. Objects persisted by the Data Service must specify the "type" or be an instance of a class (for client applications written in strongly-typed languages). 2. Backendless automatically creates tables for each persisted type it has not seen before and saves objects in the corresponding tables. Each table has columns corresponding to the properties of the persisted objects. 3. Backendless creates three additional system-level columns for each new table: objectId - contains a unique object ID assigned by Backendless to each object. created - contains a timestamp when the object was first saved by Data Service updated - contains a timestamp when the object was most recently updated. The value is null for newly created objects. 4. When an object of a known type/class introduces any new properties throughout the lifetime of the application, the persistence structure will be modified accordingly. When such an object is persisted, Backendless analyzes the object's properties and automatically alters the structure of the corresponding table if any new properties are added. 5. When an object is saved or updated, it may reference another related object (a one-to-one relationship) or objects (one-to-many). Backendless creates the underlying tables for the main and the referenced types and persists the hierarchy accordingly. © 2015 Backendless Corp. Data Service 2.2 35 Setup PHP clients can consume the Backendless services using the class library provided in the Backendless SDK for PHP. Make sure the backendless directory with all the classes is located in the root of the project directory. Download SDK The SDK can be downloaded from the Backendless website. Include Backendless SDK In you project file add the following line to include Backendless SDK for PHP: Alternatively, you can use require_once or include for adding Backendless SDK. Before the php client uses any of the APIs, the code must initialize the Backendless Application using the following call: Example: Application ID and Secret Key Values for the application-id and secret-key headers must be obtained through the Backendless Console: 1. Login to your account and select the application. 2. Click the Manage icon from the vertical icon-menu on the left. 3. The "App Settings" section is selected by default. The interface contains the text fields for "Application ID" and secret keys for each supported client-side environment. 4. Use the "Copy" button to copy the value into the system clipboard. © 2015 Backendless Corp. 36 Backendless REST API The version argument must contain the name of the targeted version. When a new application is created, the default version name is "v1" . To manage versions, login to the console, select the "Manage" icon and click "Versioning". 2.3 Native vs External Databases A Backendless backend supports two alternative mechanisms of data persistence. There is a built-in storage, referred to as native and an external storage. The native mechanism is enabled by default and a developer working with a Backendless backend does not need to do anything special to configure it. All the data persisted through the Data Service API and Backendless console is stored internally, in the database maintained by the Backendless service. The external storage can be any database located elsewhere which the Backendless service connects to with the connection parameters provided by the developer. Currently MySQL/MariaDB databases is the only type of the supported external storage. An application must be configured to use either the native or an external storage mechanism, they cannot be combined into the hybrid mode. However, regardless of which mechanism is enabled, the Data Service API can be used to work with the data. Additionally, if the application is configured to use an external database, Backendless console can be used the manage the external data the same way it does so with native. The only exception is the management of an external schema - Backendless Console displays it in the view only mode. To learn more about external data storage, see the Using External Databases chapter. © 2015 Backendless Corp. Data Service 2.4 37 Using External Databases Backendless data storage is an ultra-scalable system for storing objects hierarchies ranging from simple to very deep and possibly recursive in nature. The default implementation uses an internal persistent system which functions as a black box from the client-side developer's perspective. The internal implementation is referred to as native. There are use-cases when the native storage system cannot be used in an application built with Backendless. For instance, a new mobile application must built on top of an existing MySQL database which is used by an existing desktop application. To support this scenario, Backendless provides integration with External Databases. The integration enables a client application to use the Data Service API as it would with the native storage, however the backend operates on the data stored externally. Adding an External Database in Backendless Console To link the external database to your Backendless backend: 1. Log in to the Backendless Console, select your app and click the Data icon. 2. Click the External radio-button as shown in the image below: 3. In the Database Connection pop-up window, specify the connection details. To test the connection, click the Test link. To proceed with the connection, click the Next button. © 2015 Backendless Corp. 38 Backendless REST API 4. Once a connection is established (it may take several minutes), console displays a list of the databases in the Database drop-down menu. Select a database and click the Ok button to confirm your choice. 5. Backendless will inspect the selected database and an email is delivered to the application developer email address with the status of the inspection. 6. Upon successful database inspection the Data Management screen displays a list of the tables from the external database. The user interfaces is updated to reflect the new available functions: Re-inspect the external database by clicking the Refresh icon: © 2015 Backendless Corp. Data Service 39 Connect to another external database by clicking the add button: Re-connect (or edit the connection details) to current external database by clicking the connect button: © 2015 Backendless Corp. 40 Backendless REST API Handling Data Objects in an External Database All of the Data Service APIs can be used with external databases. The only caveat is with the data tables which have composite primary keys (a PK consisting of more than one column). In this case, the Data Service API provides special methods where object identity is established by sending in entire object rather than a specific identity value. saving an object updating an object deleting an object basic search advanced search saving and updating relations retrieving relations Supported Data Types Currently Backendless supports only MySQL and MariaDB as external databases. The table below provides a mapping between the MySQL data types and the corresponding types in Backendless: MySQL Data Type Backendless Data Type varchar( x ) String value with maxLength = x int Integer long Long integer double, float, decimal Double tinyint( 1 ) Boolean datetime Datetime text Text other types String Limitations © 2015 Backendless Corp. Data Service 41 There are several limitations for working with external databases: 1. The number of tables allowed in a database is limited by your billing plan (which is the same as for the native Backendless storage). 2. There must be a permission for the MySQL information_schema table used to inspect the external database. 3. Some of the system-level columns (and thus data object properties) will not be available with the external databases, specifically: updated, created, ownerId 4. 5. 6. 7. 8. 2.5 , objectId . You can not use the native and external databases simultaneously; once you establish a connection with an external database, a native one will not be available any longer and vice versa. Only one external database can be used in an application (cannot connect to two different external databases). The schema of an external database cannot be edited in Backendless Console. You can not import data to or export data from an external database using Backendless Console. If the database schema changes, it is important to re-inspect the database to avoid errors. Data Object Backendless supports persistence of arbitrary PHP objects. Object's class can extend Backendless class Data or dont do it. Also in class object automatically will be added properties as:objectId, created, updated. Example: Example with extend Data class: If you use Backendless Data class for extending your user data class you get set of setters and getters methods and dont need manual describe class properties structure of class properties declared in backendless console. For example if in backendless console object has property 'name' you can set this propery or get it using pattern class_object->getName(), class_object->setName ( $value ). 2.6 Saving Data Objects The API to save an object can be used for two separate scenarios: if an object has been previously saved, it is updated in the data store, otherwise it is saved (created). The save operation checks if the object has objectId assigned by the server. in that case, the object is updated, otherwise it is created in the Backendless data store. In case when there is no table for the persisted object, Backendless creates one and maps table's columns to the object's properties. The objectId property is automatically assigned to all persisted objects when they are initially saved. See the Data Object section for details on objectId . Method: object php class with data which must be stored.(Also can be php multi array in the form of key-value. where key - property name value - property value.For example: ['name'=>'Bob', ...]) © 2015 Backendless Corp. 42 Backendless REST API Return Value: The method returns the saved object( or multidimensional array if it put as method arguments ). Example: Consider the following class: The following code saves a new instance of the Contact class: 2.7 Updating Data Objects Updating a data object which has been previously stored in the Backendless data store can be done using the same API as for saving the initial object version. Once an object has objectId assigned, the call updates the persisted copy of the object: Updating an Object Individually in a Native Database Method: Example: Method: PUT URL: https://api.backendless.com/<version>/data/<table-name>/<object-id> where: <version> <table-name> <object-id> - name of the application's version. Application versions can be managed using Backendless Console. Login to the console, select an application, click Manage, then Versioning. Backendless automatically creates version "v1" for any new application. - name of the table where the object needs to be updated. - ID of the object to update assigned by Backendless in the create object operation. Request Headers: application-id: app-id-value secret-key: secret-key-value Content-Type:application/json application-type: REST where: application-id - the ID of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Setup section for information on how to obtain the values for © 2015 Backendless Corp. Data Service secret-key Content-Type application-type 43 the header. - the key of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Setup section for information on how to obtain the values for the header. - the static value, should be set to application/json. This header is mandatory. - the static value, should be set to REST. This header is mandatory. Sample Request Body: { "objectId" : "28325E9F-2DED-D3CA-FFC6-C76911AFBB00" "name" : "James Bond", "age" : 33, "phoneNumber" : "+44123456789", } Sample Response Body: { "name" : "James Bond", "age" : 33, "phoneNumber" : "+44123456789", "updated" : "02/05/2014 12:47:10 GMT+0000", "created" : "02/04/2014 19:40:10 GMT+0000", "ownerId" : null | <user-id>, "objectId" : "28325E9F-2DED-D3CA-FFC6-C76911AFBB00", "___class" : "Person" } where: updated created ownerId objectId ___class - special property generated by Backendless which contains the timestamp when the object was last updated. - similar to 'updated', but contains the timestamp showing when the object was initially created. - when the object is created by an authenticated user, this property contains the id of the currently logged in user object. - unique id (GUID) assigned to the object. - contains the name of the table where the object is stored. This is the same value as the <table-name> in the URL. Example: curl -H application-id:application-id-value-from-console -H secret-key:secret-key-value-from-console -H Content-Type:application/json -X PUT -d "{\"name\":\"Bob\", \"age\":20 }" -v https://api.backendless.com/v1/data/Person/6C77C11B-E9B3-EB14FFA2-69F38CF48800 © 2015 Backendless Corp. 44 Backendless REST API Notice the objectId value is put directly into the URL. The same value is optional in the JSON body of the request. Updating Several Objects at a Time (Bulk Update) in a Native Database Method: Method will return the number of the updated objects. where: data_object condition - user class with new data value. - condition for selecting the objects for the bulk update in mysql format ( for example $condition = " age = 12", $condition = " name = 'Jack'" ) Example: Method: PUT URL: https://api.backendless.com/<app version>/data/bulk/<table-name>? where=<where clause> where: <app version> <table-name> <where clause> - name of the application's version. Application versions can be managed using Backendless Console. Login to the console, select an application, click Manage, then Versioning. Backendless automatically creates version "v1" for any new application. - name of the table where the objects need to be updated. - condition for selecting the objects for the bulk update (please refer to the examples below in this section). Should be URL encoded. Request Headers: application-id: app-id-value secret-key: secret-key-value Content-Type:application/json application-type: REST where: application-id secret-key - the ID of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Setup section for information on how to obtain the values for the header. - the key of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please © 2015 Backendless Corp. Data Service Content-Type application-type 45 refer to the Setup section for information on how to obtain the values for the header. - the static value, should be set to application/json. This header is mandatory. - the static value, should be set to REST. This header is mandatory. Sample Request: Bulk update allows changing several data objects selected by the specified criteria. For instance, if you have the list of employees and need to update their salary info depending on their time of employment, you can do it by using the bulk update feature. To test the feature: 1. Create two persons/employees: one employed for 15 days curl -H application-id: application-id-value-from-console-H secret-key:secret-key-valuefrom-console -H Content-Type:application/json -X POST -d "{\"name\":\"Tom\", \"age\":35, \"salary\":0, \"workDays\":\"15\"}" -v https://api.backendless.com/v1/data/Person , another one employed for 20 days curl -H application-id:application-id-value-from-console-H secret-key:secret-key-value-from-console -H Content-Type: application/json -X POST -d "{\"name\":\"Bob\", \"age\":20, \"salary\":0, \"workDays\":\"20\"}" -v https://api.backendless.com/ v1/data/Person. Please note: salaries of both employees are zero. 2. To set new salary (1000) to all staff members that are employed for more than 10 days: specify the new salary in the -d argument as follows: -d "{\"salary\":1000}" set the value of <where clause> argument in URL to workDays>10 , that is: where=workDays>10 . The URL encoded query will look as follows: curl -H application-id:application-id-value-from-console -H secret-key:secret-key-value-from-console -H Content-Type:application/json -X PUT -d "{\"salary\":1000}" -v https://api.backendless.com/v1/data/bulk/Person?where=workDays% 3E10 As a result you will receive the response displaying the number of data object updated (2 objects). The salary of both employees will be changed to 1000. Sample Response: Server will return the number of the updated objects. 2.8 Deleting Data Objects The API completely removes an object from the persistent store. If the object is successfully delete, the API returns the timestamp of the exact deletion time in milliseconds. Deleting an Object Individually from a Native © 2015 Backendless Corp. 46 Backendless REST API Database Method: Example: Method: DELETE URL: https://api.backendless.com/<version>/data/<table-name>/<object-id> where: <version> <table-name> <object-id> - name of the application's version. Application versions can be managed using Backendless Console. Login to the console, select an application, click Manage, then Versioning. Backendless automatically creates version "v1" for any new application. - name of the table where the object needs to be deleted. - ID of the object to delete. The ID assigned by Backendless in the create object operation. Request Headers: application-id: app-id-value secret-key: secret-key-value application-type: REST where: application-id secret-key application-type - the ID of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Setup section for information on how to obtain the values for the header. - the key of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Setup section for information on how to obtain the values for the header. - the static value, should be set to REST. This header is mandatory. Request Body: None Sample Response Body: { "deletionTime" : timestamp in milliseconds } Example: © 2015 Backendless Corp. Data Service 47 curl -H application-id:application-id-value-from-console -H secret-key:secret-key-value-from-console -X DELETE -v https://api.backendless.com/v1/data/Orders/6C77C11B-E9B3-EB14FFA2-69F38CF48800 Deleting Several Objects at a Time (Bulk Delete) from a Native Database Method: Method will return the number of the updated objects. where: data_object condition - user class or assoc array for example ['table-name' => 'Contact' ] . - condition for selecting the objects for the bulk update in mysql format ( for example $condition = " age = 12", $condition = " name = 'Jack'" ) Example: Method: DELETE URL: https://api.backendless.com/<app version>/data/bulk/<table-name>? where=<where clause> where: <app version> <table-name> <where clause> - name of the application's version. Application versions can be managed using Backendless Console. Login to the console, select an application, click Manage, then Versioning. Backendless automatically creates version "v1" for any new application. - name of the table where the objects need to be deleted. - condition for selecting the objects for the bulk delete (please refer to the examples below in this section). Should be URL encoded. Request Headers: application-id: app-id-value secret-key: secret-key-value application-type: REST where: application-id © 2015 Backendless Corp. - the ID of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Setup section for information on how to obtain the values for the header. 48 Backendless REST API secret-key application-type - the key of your application generated upon its creation. You can find this header in the Manage > App Settings section of the Backendless Console. This header is mandatory. Please refer to the Setup section for information on how to obtain the values for the header. - the static value, should be set to REST . This header is mandatory. Sample Request: Bulk delete allows removing several data objects selected by the specified criteria. For instance, if you have the list of employees and need to delete some of them depending on their time of employment, you can do it by using the bulk delete feature. To test the feature: 1. Create three persons/employees: employed for 15 days curl -H application-id:application-id-value-fromconsole-H secret-key:secret-key-value-from-console -H ContentType:application/json -X POST -d "{\"name\":\"Tom\", \"age\":35, \"salary\":0, \"workDays\":\"15\"}" -v https://api.backendless. com/v1/data/Person employed for 0 days curl -H application-id:application-id-value-fromconsole-H secret-key:secret-key-value-from-console -H ContentType:application/json -X POST -d "{\"name\":\"Bob\", \"age\":20, \"salary\":0, \"workDays\":\"0\"}" -v https://api.backendless. com/v1/data/Person employed for 0 days curl -H application-id:application-id-value-fromconsole-H secret-key:secret-key-value-from-console -H ContentType:application/json -X POST -d "{\"name\":\"Brad\", \"age\":22, \"salary\":10, \"workDays\":\"0\"}" -v https://api.backendless. com/v1/data/Person 2. To delete all staff members that are employed for 0 days, set the value of <where clause> argument in URL to workDays=0 , that is: where=workDays=0 . The URL encoded query will look as follows: curl -H application-id:application-id-value-from-console -H secret-key:secret-key-value-from-console -X DELETE -v https://api.backendless.com/v1/data/bulk/Person?where=workDays% 3D0 As a result you will receive the response displaying the number of data object deleted (2 objects). The second and third employees (Bob and Brad) will be deleted from the database. Sample Response: Server will return the number of the deleted objects. 2.9 Retrieving Schema Definition Backendless supports API for data table schema introspection. The API provides information about table's columns and their data types, whether a value for a column is required or if there is a default value. © 2015 Backendless Corp. Data Service 49 Method: where: $table_name - name of the table to retrieve the schema for. Return value: Returns assoc array of object's properties. Each item in the array describes a column in the specified table using the structure below: { autoLoad: true or false, customRegex: value, defaultValue: null or value, isPrimaryKey: true or false, name: value, relatedTable: null or table name, required: true or false, type: data type } where: autoLoad customRegex defaultValue isPrimaryKey name relatedTable required type - applies only to relations. If true, the property is set to auto-load related data for the data retrieval queries. - a regular expression assigned to the column as a validator. The validator applies when a new object is saved in the table or an existing one is updated. - a default value assigned to any object saved/updated in the table where the column does not have a value. - true if the column is or is a part of a primary key. - contains the name of a property. - contains the name of the related table(s). - defines whether a property is optional or required for the requests which save the initial object or update an existing one. - defines the property type. Example: Variable $description will contain array: 2.10 Basic Search Backendless supports multiple basic search operations. These include finding an object by ID, finding first or last object in the collection or retrieving the entire persisted collection. Searching for a Data Object in a Native Database Retrieve all data objects of class $class_name . Find first data object of class $class_name . The first data object is the first one saved in the data store: Find last data object of type $class_name . The last data object is the last one saved in the data store: © 2015 Backendless Corp. 50 Backendless REST API Find a data object by its ID: where: $class_name - can will set as class, string or array. Example: $relations_depth - retrieving related objects by specifying the depth of the object hierarchy. Example: Consider the following class: The following code demonstrates various search queries: Find all contacts: Find first contact: Find last contact: Find contact by ID: 2.11 Advanced Search Advanced search use-cases supported by Backendless include: Search with query - a query is an SQL-92 expression (the where clause) referencing data object properties. Paged search - sets the page size and index (offset) to search from. Sorted search - lists the data object properties to sort the result collection by. Additionally, search requests may include special modifiers: Request for specific properties of the data objects returned in the result collection. Request to return related data objects attached to the 'parent' objects in the result collection. Searching for a Data Object Backendless supports the use-cases and modifiers listed above with a special class BackendlessDataQuery : Method Signature: where: query - an instance of BackendlessDataQuery - containing the search query and other search options. © 2015 Backendless Corp. Data Service data_object 51 - an instance of data class or string with class name. Return Value: The method returns a array of objects found as a result of the query execution. Example: Consider the following class: The code below stores an instance of the Contact class in the Backendless data store: The following code demonstrates various search queries: Find all contacts where the value of the "age" property equals 147: Find all contacts where the value of the "age" property is greater than 21: Find all contacts where the value of the "age" property is between 21 and 30: Find all contacts by name: Find all contacts by partial name match: Notice: Also class BackendlessDataQuery supports chained call: Find objects within certain distance from a geo point With the ability to link data objects with geo points, you can search for data objects by distance. This type of search returns all data objects located within the specified distance. Distance-based search uses a special function in whereClause of the search request. The syntax of the function is: where: <operator> units-function - Possible values are <, >, =, >=, <= - Defines the units of measure for the distance. Possible values are: ft( X ) - the distance value X is expressed in feet km( X ) - the distance value X is expressed in kilometers mi( X ) - the distance value X is expressed in miles yd( X ) - the distance value X is expressed in yards For example, the following expression searches for data objects located within 200 miles from the point at 30.26715, -97.74306. Each data object must have the "coordinates" property of type GeoPoint. The following example demonstrates a search-by-distance query. The example uses three data objects stored in the Friend table: Bob, Jane, and Fred who respectively live in Austin, Houston, San Antonio. The search query in the example finds all friends who love within the specified distance. Before running the search query, create the objects in the data storage with the corresponding geo points. Run the following query/code to store a data object representing Bob with a link to his home in Austin, TX: © 2015 Backendless Corp. 52 Backendless REST API Run the following query/code to store a data object representing Jane with a link to his home in Houston, TX: Run the following query/code to store a data object representing Fred with a link to his home in San Antonio, TX: Once the data is in the persistent object and geo location storage, run the following code/query to perform a distance-based search: The search returns all data objects within the specified distance. Each data object has the coordinates property containing the coordinates of a geo point associated with this data object. 2.12 Using Dates in Search There is a special consideration for the whereClause-based queries which reference a column of the DATETIME data type. Typically a DATETIME column is referenced in a comparison against a scalar value describing a specific date or a timestamp. The scalar value can be a number of milliseconds since the epoch (UNIX timestamp as milliseconds) or a string. Backendless supports a variety of date formats for the latter. For example, the queries below will find all the objects which were updated after March 23rd, 2015: updated > '23-Mar-2015' updated > '03/23/2015' updated > 1427068800000 Comparison Operators Backendless supports the following date comparison operators: Column's value is after the specified date/time: use either > or the after keyword: birthDate > '22-Dec-1980' birthDate after 1427068800000 Column's value is before the specified date/time: use either < or the before keyword: birthDate < '22-Dec-1980' birthDate before 1427068800000 Column's value is either at or after the specified date/time: use either => or the at or after keyword: birthDate >= '28-10-1988' birthDate at or after '10/28/1988 00:00:00 GMT-0200' Column's value is either at or before the specified date/time: use either <= or the at or © 2015 Backendless Corp. Data Service 53 before keyword: birthDate >= '28-10-1988' birthDate at or after '10/28/1988 00:00:00 GMT-0200' Note: the whereClause-based queries can be tested in the Backendless Console with the SQL Search turned on. Supported Date Formats Date/time string values may be in any of the following formats. The pattern letters have the same definition as in Java's SimpleDateFormat: EEE MMM dd HH:mm:ss zzz yyyy MM/dd/yyyy HH:mm:ss 'GMT'z MM.dd.yyyy HH:mm:ss 'GMT'z MM-dd-yyyy HH:mm:ss 'GMT'z MM.dd.yyyy HH:mm:ss MM-dd-yyyy HH:mm:ss MM/dd/yyyy HH:mm:ss MM.dd.yyyy MM-dd-yyyy MM/dd/yyyy HH:mm:ss z MM/dd/yyyy HH:mm:ss 'GMT'Z MM.dd.yyyy HH:mm:ss z MM/dd/yyyy HH:mm MM/dd/yyyy dd/MMM/yyyy dd-MMM-yyyy EEEEE, d MMMMM yyyy ddMyy d MMMMM yyyy, HH'h' mm'm' ss's' yyyy/MM/d/hh:mm:ss yyyy-MM-dd'T'hh:mm:ss EEEEE, MMMMM d, yyyy MMMMM d, yyyy yyyy-MM-dd yyyy M d yyyyMMMd yyyy-MMM-d yyyy-M-d, E yyyyMMdd 'Date' yyyy-MM-dd yyyy-MM-dd'T'hh:mm:ssZ yyyy-MM-dd'T'hh:mmZ yyyy-'W'w-d yyyy-DDD Example © 2015 Backendless Corp. 54 2.13 Backendless REST API Relations Overview A data object stored in a Backendless backend may reference other objects. These references are called relations. There are two types of relations: one-to-one and one-to-many. Relations may be declared manually in a table schema using the Backendless Console or derived (and added to schema) from the objects which are being saved. Additionally, Backendless supports bidirectional relations between the objects stored in the Data Service and other entities in a Backendless backend. For example, a data object may have a relation with a User object and/or Geo Point objects. Creating Relations Relations can be declared manually by using the Backendless Console. Creating a relation between objects involves two main steps: 1. Declaring a relationship between the tables where the objects are stored. 2. Establishing relations between the objects from the related tables. Declaring a Relation Between Tables The instructions below describe how to declare a relation between two tables: 1. Select a table where a relation should be declared. 2. Click the Table Schema and Permissions button in the top right corner of the user interface. 3. Click the Add Column button. The pop-up window will display as shown below: 4. Enter column name that will represent the relation. 5. Click the Type drop-down list and select the Data Object Relationship option. © 2015 Backendless Corp. Data Service 55 6. The pop-up window will display new menu options. Select a related table and the cardinality of the relations from the corresponding drop-down menus. The one-to-one relation means that a table's object can be linked with only one object from the related table. While the one-tomany relation means that a table's object can be linked with several objects from the related table. 7. Click Save to save the changes. Once a relationship column is declared, it will appear along other columns in the Data Browser view of the Backendless Console. Creating Relations Between Objects in Related Tables Once you have declared a relation between table schemas, you can establish a relation between objects © 2015 Backendless Corp. 56 Backendless REST API in these tables. Follow the instructions below to establish a relationship: 1. Click the table name where you declared a relation. Console displays the columns representing relations slightly different than the other ones. The header for these columns includes: - name of the related table; - relation type (cardinality) visualized as either a single line for one-to-one relations or three lines for one-to-many relations; - the "auto-load" checkbox. 2. Click the plus icon next to the object, for which you want to create a relation. The Set Related Object pop-up window will display the list of objects from the related table. 3. Each object in the displayed popup has either a radio button or a checkbox next to the © 2015 Backendless Corp. Data Service 57 object's data. Radio buttons are used for one-to-one relations, while checkboxes apply for the one-to-many relations. Select the object(s) which will be linked to the parent object. 4. Click the Set Related Object button to save the changes. The Data Service API can be used to link objects from different tables to form a relation. For more information see the Relations (Save/Update) section of the guide. Editing Relations You can edit the relations between the data objects via the Backendless Console: 1. Click the name of the table containing the object with relations. Click the plus icon next to the relation you want to edit: 2. The Set Related Object pop-up window will display. If you want to link a data object with different object(s), click the radio-button or check-box(s) next to the necessary object(s). 3. Click the Set Related Object button to save the changes. Refer to the Relations (Save/Update) section to learn how to update relations by using the API. Deleting Relations You can delete both relations between the objects and between the tables if necessary. Relations between the tables can be deleted only by using the Backendless Console. While relations between the objects can be deleted either via the Backendless Console or API. To delete relations between the tables by using the Backendless Console: 1. Click the name of the table that you want to unlink from another table. 2. Click the Table Schema and Permissions button at the top right. The Table Schema and Permissions page will display. 3. Click the check-box(s) next to the column associated with the relation(s) between the tables. © 2015 Backendless Corp. 58 Backendless REST API 4. Click the Delete Selected button. To delete relations between the data objects via the Backendless Console: 1. Click the name of the table, where you want to delete a relation. Click the plus icon next to the relation you want to delete. 2. The Set Related Object pop-up window will display. Click the Unlink Related Object button to delete the relation. Additionally, a relation between two objects (not tables) can be deleted by using the API. For more information see the Relations (Delete) section. © 2015 Backendless Corp. Data Service 2.14 59 Relations (Save/Update) Backendless Data Service supports a complete set of CRUD (create, retrieve, update, delete) operations for related objects. Handling Relations in a Native Database Consider the following class diagram: Notice the PhoneBook entity references Contact through two properties - "owner" (the one to one relationship) and "contacts" (the one to many relationship). Each contact entity also references Address. These entities will be used to demonstrate how Backendless handles related entities in all basic data persistence operations. Consider the following class definitions for these entities: PhoneBook Class Contact Class Address Class Consider the following examples of saving objects with related data: Constructing PhoneBook with the Owner and no Contacts: Constructing PhoneBook with the Owner and two Contacts: © 2015 Backendless Corp. 60 Backendless REST API Add Contact to an existing PhoneBook (uses the "savedPhoneBook" object created at the end of the example above): Update a property in the aggregated object (update the phone number in the "owner" of PhoneBook) and save PhoneBook: © 2015 Backendless Corp. Data Service 61 Removing one contact from PhoneBook, adding another and re-saving PhoneBook: © 2015 Backendless Corp. 62 2.15 Backendless REST API Relations (Delete) Backendless Data Service supports a complete set of CRUD (create, retrieve, update, delete) operations for related objects. Handling Relations in a Native Database Consider the following class diagram: Notice the PhoneBook entity references Contact through two properties - "owner" (the one to one relationship) and "contacts" (the one to many relationship). Each contact entity also references Address. These entities will be used to demonstrate how Backendless handles related entities in all basic data persistence operations. Consider the following class definitions for these entities: PhoneBook Class Contact Class Address Class Consider the following examples of saving objects with related data: Delete parent object (deleting a PhoneBook): © 2015 Backendless Corp. Data Service 63 Remove a contact from PhoneBook and save the change: 2.16 Relations (Retrieve) When a data object or a collection of objects is retrieved using the client API, Backendless does not automatically include related objects into the returned object hierarchy. The reason for this is it would make it very easy to load a lot of unnecessary data which could impact application's performance. There are multiple ways to retrieve related data: © 2015 Backendless Corp. 64 Backendless REST API Relations auto-load - a mechanism built-into Backendless Console for configuring specific relations to be included into responses with the parent objects. Single-step relations retrieval - initializing and including related objects into the response when running a find query for parent objects. Two-step relations retrieval - a process of retrieving relations where the first step is to load the parent object and the second step is to load specific relations for the given parent. Loading with relations depth - retrieving related objects by specifying the depth of the object hierarchy Loading related child objects by condition applied to parent - load related objects using a search query where the condition applies to the parent object properties. Please note: retrieving relations in a native database differs from retrieving relations in an external database. Relations Auto Load By default when an object is retrieved from Backendless using any of the find APIs (basic or advanced), its related objects are not included into the response, unless explicitly referenced in the request. This behavior can be easily modified using Backendless Console: For any two tables A and B where A has a relationship column linking it to B, the console includes the "auto load" checkbox for the relationship column. Selecting the checkbox instructs Backendless to return all related B objects when the parent instance of A is retrieved through an API call. For example, in the image above, the Order table has the one-to-many "items" relationship with the OrderItem table. When the "auto load" checkbox in the "items" column is selected, all related OrderItem objects will be included into the response for a find query for the Order table. Single Step Retrieval This approach allows to retrieve related objects along with the parent object in a single find request. Each relationship property (column) must be uniquely identified by name using the following API: where RELATED-PROPERTY-NAME - name of a related property to load. For example, if table class-name Person, has a relation "homeAddress" pointing to an object in the Address table, the value would be "homeAddress". The syntax allows to add relations of relations. For example, if the same Address table has a relation "country" pointing to the Country table, then "homeAddress.country" would instruct the related Country object to be loaded as well. - Class name which identifies the table from which the data is to be loaded. © 2015 Backendless Corp. Data Service 65 Two Step Retrieval With this approach a parent object is loaded first and then there is a separate API call to load specific related objects into the given parent object. For example, suppose the Order table has a one-to-many relationship column "items " pointing to the OrderItem table. The OrderItem table has a one-to-one relationship to the Manufacturer table, the code below loads first Order object and then loads related OrderItems and corresponding Manufacturers : Loading with Relations Depth The Data Service API supports a mechanism for loading related objects without identifying each by its name. Instead, the API includes a parameter which specifies the "depth" of the relations to include into the response. Consider the following diagram: The diagram shows a hierarchy for class structure - the Order class has two relations: with OrderItem and Customer classes. Each in turn has a relation to the Manufacturer and Address classes. When an instance or a collection of Order objects is retrieved from Backendless, the API may include a parameter specifying the depth of relations to include into the response. If the relation depth is 1, then all related instances of OrderItem and Customer will be included into each Order object. If the relation depth is 2, then not only OrderItem and Customer instances will be included, but the corresponding Manufacturer and Address objects as well. API methods supporting relations depth Example: Loading a Subset of Related Child Objects Backendless supports a special query syntax for loading a subset of child objects for a specific parent. Consider the following class diagram: © 2015 Backendless Corp. 66 Backendless REST API Notice the PhoneBook entity references Contact through two properties - "owner" (the one to one relationship) and "contacts" (the one to many relationship). Each contact entity also references Address. These entities will be used to demonstrate how Backendless handles related entities in all basic data persistence operations. Consider the following class definitions for these entities: PhoneBook Class Contact Class Address Class The general structure of the query to load a collection of child objects for a specific parent object is: ParentTableName[ relatedPropertyForChildrenCollection ]. parentColumnName COLUMN-VALUE-CONDITION When a query in this format is used to fetch a collection of child object, the table addresses in the request must be one which the "relatedPropertyForChildrenCollection" points to. The examples below demonstrate the usage of this syntax: Find all contacts in a city for a specific phone book: Find all contacts for the specific phone book where the city name contains letter 'a': Find all contacts where age is greater than 20 for a specific phone book: Find all contacts for a specific phone book where age is within the specified range: Find all contacts for a specific phone book where age is greater than 20 and the city is Tokyo: © 2015 Backendless Corp. Data Service 2.17 67 Relations with Geo Points Backendless Geo Service manages application's geo location data and provides APIs to work with Geo points. Backendless supports integration between data objects managed by Data Service and geo points for the scenarios when a logical connection between the two entity types must exist in an application. For instance, in a taxi ordering application a data object may represent a taxi car, while a geo point represents its location on the map. Link the two together provides great benefits such as retrieving both objects at once and managing as a consistent, cohesive object hierarchy. The Data-to-Geo integration is implemented through object relations. A data table schema may declare a table column with a special data type - "GeoPoint Relationship". As a result, the data objects in the table may contain a reference to one or more GeoPoints. When a data object with a related GeoPoint is saved, Backendless persists information about both the data object and the geo point in the corresponding persistent systems and sets up the relationship. Likewise, when a data object is retrieved by using the API, any related geo points can be retrieved using the same principle for loading data relations. The data-to-geo relation is bidirectional, it means a geo point may reference a data object in its metadata. You can learn more about it in the Relations with Data Objects section of the Geolocation documentation. The relationship between a data object and a geo point (or a collection of) can be established by using either the "code first" or the "schema first" approaches. With the former, the relationship is determined by the data structure persisted with the API. If a data object references a GeoPoint (or a collection of) in one of its properties, Backendless interprets it as a relation and, as a result, will create a relation column in the data table schema. With the latter ("schema first") approach, application developer can declare a relationship in the data table schema first. In either one of these approaches, once a relationship is declared, data objects and geo points may be linked together by using the Backendless console as well. Declaring a Data-to-Geo Relationship in Table Schema To declare a relationship in a data table schema: 1. Select a table where a relation should be declared. 2. Click the Table Schema and Permissions button in the top right corner. The Table Schema and Permissions page will display. 3. Click the Add Column button. The pop-up window will display: © 2015 Backendless Corp. 68 Backendless REST API 4. Enter the name of the column in the Name field. This column will represent a data-to-geo relationship. 5. Select the Geopoint Relationship option from the Type drop-down list. 6. New menu options will become available. Select the cardinality of the relation from the corresponding drop-down menu. The one-to-one relation means that a table's object can be linked with only one geo point, while the one-to-many relation means that a table's object can be linked with multiple geo points. © 2015 Backendless Corp. Data Service 69 7. Click the Save button to save the changes. Linking a Data Object with Geo Points Once a data-to-geo relationship is declared (see the instructions above), data objects from the table can be linked to geo point(s) as described below: 1. Click the name of the table containing an object that you want to link with a geo point. 2. Table columns representing the data-to-geo relationships are identified as "GEOPOINT relationship" in the header row. The cardinality of the relation is visualized as one red line for the one-to-one relations and three parallel lines for the one-to-many relations: 3. Click the plus icon next to the object, for which you want to create a data-to-geo relation. The Set Related GeoPoint pop-up window will display the list of the geo points. © 2015 Backendless Corp. 70 Backendless REST API 4. Use the Geo Category drop-down list to select a geo category from which the points should be displayed. 5. If you declared a one-to-one relation for a table the object belongs to, you will be able to link this object with only one geo point (by the means of a radio button). If it is a one-to-many relationship, the interface uses check boxes, which allow for multiple selection. Click a radiobutton or select check-boxes next to the geo points which you want to link with the data object. 6. Click the Set Related GeoPoint button to save the changes. Once a relation is established, it is shown in the data browser as a hyperlink. The hyperlink for the oneto-one relations displays the coordinates of the related geo point. For the one-to-many relations the link says "multiple Geopoints". In both cases, the link opens the Geolocation screen of the console which displays the related geo point(s). Updating Relations You can update a data-to-geo relation by following the steps shown below: 1. Click the name of the table containing an object that has a data-to-geo relation you want to edit . Click the plus icon next to the relation: © 2015 Backendless Corp. Data Service 71 2. The Set Related GeoPoint pop-up window will display. Use the radio-buttons (one-to-one relations) or check-boxes (one-to-many relations) next to select/deselect the geo points. 3. Click the Set Related GeoPoint button to save the changes. Deleting Relation Definition in Table Schema A data-to-geo relationship can be removed at the schema level. Removing the relationship is done by deleting the column which represents it. When a column is removed the relationships identified by the column between the data objects and geo points are removed as well. To delete a relationship definition between a data table and the geo points: 1. Click the name of the table which contains a "GeoPoint relationship" column you need to remove. 2. Click the Table Schema and Permissions button in the top right corner. The Table Schema and Permissions page will display. 3. Click the check-box next to the column you need to delete. © 2015 Backendless Corp. 72 Backendless REST API 4. Click the Delete Selected button. Deleting Relation between Data and Geo Point Objects To delete relations between a data object and geo point(s) via the Backendless Console: 1. Click the name of the table which contains a data-to-geo relationship you need to remove. Click the plus icon next to the relation you want to delete. 2. The Set Related GeoPoint pop-up window will display. Click the Unlink Relation button to delete the relation. Establishing Relations with Geo Points via API © 2015 Backendless Corp. Data Service 73 Creating a relationship between a data object and a geo point (or a collection of) uses the same API as saving a data object with a related entity. In the case of data-to-geo relations, the related entity is a geo point or a collection of geo points. Consider the example that below saves a data object with a related geo point. The geo point is also persisted in the Geo Service The example below demonstrates how to link a taxi (a data object) with its location (geo point). First, create TaxiCab class: To set one-to-one or one-to-may relation: 2.18 Security Data Service supports a very flexible security mechanism for restricting access to objects stored in Backendless. Security permissions apply to users and roles. A permission can either grant or reject an operation for a particular asset. In the context of Data Service, the asset is an object which your app can retrieve, update or delete. Permissions can be granted or rejected globally, where they apply to all tables and all objects in the data store. Additionally, every table may have its own permission matrix and owner policy – a special instruction whether object owners can or cannot retrieve/update/delete the objects they ‘own’. Finally, every object has its own Access Control List (ACL) which is a matrix of permissions for the operations applicable specifically to the object: The security system is multi-layered. For an API call to retrieve, update or delete object(s), the system goes through several where each can trim the scope of the operations. The layered order of the decision making is important and consists of the following: 1. 2. 3. 4. 5. 6. ObjectACL for the user who makes the call ObjectACL for user-defined roles assigned to the user who makes the call. Table permissions for the User account Table permissions for the user-defined roles Owner Policy ObjectACL for system roles © 2015 Backendless Corp. 74 Backendless REST API 7. Table permissions for system-level roles 8. Global user-defined roles 9. Global system roles Where: “User-defined roles” – roles created by the application developer “System roles” – roles built into Backendless (Authenticated User, NonAuthenticated User, SocialUser, etc) Consider the following guide which illustrates the decision making process: 1. Backend receives an API request to load data from a table (the Find operation). All objects become candidates for the retrieval. Backendless goes through the security permissions chain to determine which ones must be included. 2. ObjectACL for the user who makes the call. Backendless checks if there are any restrictions for the user account at the object level. Any object in the collection with ACL which rejects access to the user is excluded from the result. To see or modify the permissions for a particular object, click the ‘key’ icon in the ACL column in the data browser in management console. © 2015 Backendless Corp. Data Service 75 3. ObjectACL for user-defined roles assigned to the user who makes the call. This is the same check as the one above, except Backendless looks into the permissions for the roles defined by the application developer. If the user belongs to any of the custom roles, Backendless checks if these roles are allowed to perform the current operation. In the screenshot below, only the “MyRole” role will be checked in this step, since this is the only © 2015 Backendless Corp. 76 Backendless REST API custom role in the application: 4. Table permissions for the User account. Every table in Backendless may have its own set of permissions for users and roles. At this point Backendless checks if the currently logged in user is allowed to run the current operation. For example, if the Find operation is denied for the user, no objects would be returned. 5. Table permissions for the user-defined roles. This step is identical to the one described above with the exception that is checks custom roles for the table. Since this guide reviews the decision making process for the Find operation, Backendless checks the column for Find. If any of the custom roles deny access, the operation is rejected and no data is returned. 6. Owner Policy. When a new object is created in Backendless, the system automatically links it with the account of the currently logged in user. You can see that information in the ‘ownerId’ column in any of your tables in the data browser. With the association between objects and users, Backendless provides a way to control whether users can get access to the data they created. This is done through a concept we call ‘Owner Policy’. The policy is available on the ‘Schema and Permissions’ screen. Select a table in the data browser and click the ‘Table Schema and Permissions’ button in the upper right corner. Select the ‘Owner Policy’ menu item. Owner policy can be global (select ‘All Tables’ from the drop down in the upper right corner) or it could apply to a specific table. Granting a permission for an operation in Owner Policy, guarantees that the objects owned by the current user will be included in the resulting collection. Denying a permission, takes out the ‘owned’ objects from the collection of candidate objects to return. Consider the following: Granting Find permission in Owner Policy: © 2015 Backendless Corp. Data Service 77 Results in the following. The objects with bold border are guaranteed to be returned. All other objects will be subject to the subsequent permission checks. However, if the Owner Policy rejects a permission: The objects owned by the current user will be excluded from the resulting collection. All remaining objects will be decided by the subsequent permission checks. © 2015 Backendless Corp. 78 Backendless REST API 7. Object ACL for system roles. This check is identical to step 3 (Object ACL for custom roles). The difference is the system roles cover larger groups of users. For example, this step would make possible to restrict access to specific objects for all authenticated (or not authenticated) users, yet the object would be returned with a query made by the object’s owner if the Owner Policy (previous step) grants access. 8. Table permissions for system roles. Identical to step 5, this checks if any of the system roles reject the operation at the table level. 9. Global custom roles. Global policy applies to all tables and objects. By default all table level permissions inherit from the global policy. You can configure in the console at: Users > Security and Permissions. Create a new role and click it to configure the permission matrix: © 2015 Backendless Corp. Data Service 3 Messaging Service 3.1 Overview 79 Data Messaging is an essential function of mobile and desktop applications. It can be used for a multitude of functions including chat or private messaging, system update broadcast, maintaining game scores, etc. The Backendless Messaging Service provides API and software infrastructure enabling publish-subscribe message exchange pattern and mobile push notifications. The service consists of the following core concepts: channels, publishers, subscribers and registered devices: channel - a logical medium "carrying" the messages. publisher - a program using the Publishing API to send messages to a channel. subscriber - a program using the Subscription API to receive messages from a channel. registered device - a mobile device registered with a Backendless channel to receive push notifications. Publish-Subscribe Messaging With the publish-subscribe pattern, one part of the code (or an entire application) can subscribe to receive messages and another publishes messages. A message can be any data - Backendless supports messages of primitive or complex data types. To enable publish-subscribe messaging, Backendless supports the concept of a channel. Subscriptions are "attached" to a channel (or multiple © 2015 Backendless Corp. 80 Backendless REST API channels) and messages are published into a channel. By default Backendless sends all messages published into a channel to all the channel's subscribers. However, a subscription can include message filters, in this case Backendless delivers only the messages matching the filter. Push Notifications A message published to a channel can be tagged as a push notification, thus triggering the logic for distributing it to the registered devices. Backendless supports push notifications for iOS, Android and Windows Phone devices. Messages published as push notifications can target either a specific subscriber (as a device) or a group of subscribers. Subscribers can be grouped by operating system (for example, a message sent to all registered iOS devices) or as a collection of individual registrations. The Backendless messaging API supports different types of push notifications - badge updates, alerts, etc. 3.2 Setup PHP clients can consume the Backendless services using the class library provided in the Backendless SDK for PHP. Make sure the backendless directory with all the classes is located in the root of the project directory. Download SDK The SDK can be downloaded from the Backendless website. Include Backendless SDK In you project file add the following line to include Backendless SDK for PHP: Alternatively, you can use require_once or include for adding Backendless SDK. Before the php client uses any of the APIs, the code must initialize the Backendless Application using the following call: Example: Application ID and Secret Key Values for the application-id and secret-key headers must be obtained through the Backendless Console: 1. Login to your account and select the application. 2. Click the Manage icon from the vertical icon-menu on the left. 3. The "App Settings" section is selected by default. The interface contains the text fields for "Application ID" and secret keys for each supported client-side environment. 4. Use the "Copy" button to copy the value into the system clipboard. © 2015 Backendless Corp. Messaging Service 81 The version argument must contain the name of the targeted version. When a new application is created, the default version name is "v1" . To manage versions, login to the console, select the "Manage" icon and click "Versioning". 3.3 Core Classes The Backendless Messaging Service uses the following core classes: Backendless::$Messaging - is the central point for all Backendless Messaging APIs. Provides access to the device registration, subscription management and messaging publishing functionality. SubscriptionOptions - may be used in the subscription call to establish subscriber identity and set messaging filt PublishOptions - this class is the publishing counterpart for the SubscriptionOptions shown above. Can be use DeliveryOptions - used in the publishing API for targeted message delivery. Supported options include: tagging a m © 2015 Backendless Corp. 82 3.4 Backendless REST API Push Notification Setup (Android) Backendless can deliver published messages as push notifications to Android devices. Additionally, Backendless Console can be used to publish push notifications. In order to deliver a push notification to Android, the backend must be configured with Google API Key: 1. Login to Google Developers Console and select or create a project. 2. Click Credentials located under the APIS & AUTH menu. 3. If you don’t have “Key for server application”, you create it: Click Create new Key under the Public API access section; Choose Server key; Click Create; 4. Copy the API Key for server applications: 5. Open Backendless Console and select your application. 6. Click Manage and scroll down to Mobile Settings. 7. Paste the Google API Key into corresponding field located under the Android Push Notifications label: © 2015 Backendless Corp. Messaging Service 83 8. Click Save. At this point the backend is configured and is ready to publish push notifications to Android devices. In your project you should register the device in order to receive or send push notifications. To accomplish this, do the following: 1. Login to Google Developers Console and select your previously created project. 2. Copy the project number located at the top of the screen: © 2015 Backendless Corp. 84 Backendless REST API 3. Use this project number in Backendless.Messaging.registerDevice(...) method as GCMSenderID argument. For example: 3.5 Push Notification Setup (iOS) Setting up your backend to support Push Notifications for iOS requires a few steps, most of which are in Apple Developer Member Center and Keychain Access. The process consists of the following steps: 1. 2. 3. 4. Creating App ID Creating Certificate Request Generating an SSL Certificate Configuring Backendless App/Backend with the Certificate Creating App ID 1. First we are going to create an App ID for the mobile application which will receive Push Notifications. Login to Apple Developer Member Center. Click on “App IDs” in the “Identifiers” section. Use the plus sign “+” button to create a new ID: © 2015 Backendless Corp. Messaging Service 85 2. When prompted enter App ID Prefix. Make sure it is descriptive enough so you recognize it later when you return to the Member Center. 3. Select Explicit App ID in the “App ID Suffix” section and enter the same bundle ID which you will be using in the application: © 2015 Backendless Corp. 86 Backendless REST API 4. In App Services select the services which the application will use and click “continue”: 5. Make sure that Push Notifications are enabled and click “submit”. This will conclude the App ID creation for the app: © 2015 Backendless Corp. Messaging Service 87 Creating Certificate Request Push Notifications require a certificate which will be used on a device by the means of a provisioning profile. Also the same certificate (transformed to the Personal Information Exchange – .p12 format) will be used by Backendless to publish Push Notifications. If this makes little sense, do not worry, you will need to perform these steps only ones and then can move on to code and using the APIs. 1. In order to create a certificate a Certificate Signing Request (CSR) must be issued. To create a CSR, open Keychain Access and select Keychain Access >> Certificate Assistant >> Request a Certificate from the main menu: © 2015 Backendless Corp. 88 Backendless REST API 2. Enter your email address and Common Name (leave the CA Email Address field empty), select “Saved to disk” and click “Continue”: 3. Select a directory where to save the file and click Save. Generating an SSL Certificate The CSR file created in the section above will be used to create an SSL Certificate. That certificate will then be used by Backendless to publish push notifications. 1. Return to Apple Developer Member Center and select “All” under “Certificates”. Click the plus button “+” to add a new certificate: © 2015 Backendless Corp. Messaging Service 89 2. Select certificate type – there are two options Development and Production. For now select “Apple Push Notification service SSL (Sandbox)”: © 2015 Backendless Corp. 90 Backendless REST API 3. Select the App ID created earlier in these instructions: 4. Next you will see the instructions for generating a CSR which you have already created by now. Click Continue to proceed to the next step. 5. Select the CSR file created and saved to the disk earlier and click Generate: © 2015 Backendless Corp. Messaging Service 6. The certificate is ready now, click “Download” to download it: 7. Add the certificate file to Keychain Access. 8. Open Keychain Access and locate the certificate in the “My Certificates” section: © 2015 Backendless Corp. 91 92 Backendless REST API 9. Right click on the certificate and select the Export option: 10. Save the certificate in the p12 format: 11. Enter a password for the certificate. Make sure to make a record of the password – you will need to use it later in the instructions when you submit the certificate to Backendless: © 2015 Backendless Corp. Messaging Service 93 12. Enter your Mac OS X account password to confirm the action. At this point you have a certificate for Push Notifications. Configuring Backendless App/Backend with the Certificate Since Backendless provides the actual server-side integration for delivering Push Notifications for your application, it needs to have access to the certificate you created above. The steps below provide the instructions for uploading the certificate into Backendless: 1. Login to Backendless Console at: https://backendless.com/develop and create/select an application which you will use on the server-side: 2. Click Manage > App Settings. Locate the Mobile Settings section and upload the .p12 certificate created earlier. Make sure to enter the same password you used when created the certificate: © 2015 Backendless Corp. 94 Backendless REST API 3. Now your Backendless server is ready to publish Push Notifications. 3.6 Managing Registrations Application developers can manage device registrations using the Backendless Console. To see the device registrations: 1. Login to console at https://backendless.com/develop 2. Click the application for which you would like to see the device registrations. 3. Click the "Messaging" icon. 4. Select the "Devices" tab. © 2015 Backendless Corp. Messaging Service 95 The table displays all the current device registrations. Using the interface, you can: Search for device registrations. The search string applies to all columns Remove device registrations. To remove, use the check boxes and then click the "Delete Selected" button Deliver push notifications to the selected devices. Publish a Push Notification from Console Select the check boxes for the device you would like to send a notification to. Use the Publish Message section located below the table with the devices. Make sure to enter the message headers specific for the targeted operating systems. Make sure to click the "Selected devices" checkbox. Click the "Publish" button. © 2015 Backendless Corp. 96 3.7 Backendless REST API Message Publishing Application can publish messages to Backendless for subsequent distribution to subscribers. Backendless delivers published messages to subscribers as message objects and/or to devices as push notifications. A message must be published to a channel (or a group of channels). Backendless supports unlimited number of channels. Applications can use them as a filtering mechanism - channel subscribers see messages published only to that channel. Similarly, devices can specify a channel (or a group of them) when registering for push notifications. Message publishing supports the following scenarios: Publishing with message headers - headers is a collection of name = value pairs of arbitrary data. Subscribers can set additional filters expressed as SQL queries which Backendless applies to the headers. When the query matches the published data in headers, message is delivered to the corresponding subscriber. See example. Publishing to a subtopic - Subtopics provide an additional level of message filtering. Multiple subtopics can be defined within a channel. Both publishers and subscribers can specify a subtopic within a channel. Subtopic names can be defined using a multi-tiered format: maintoken[.secondaryToken][.additionalToken] To receive messages from more than one subtopic, subscribers can use the wildcard character (*) in place of any tokens in the subtopic name. For instance, a subscriber © 2015 Backendless Corp. Messaging Service 97 could subscribe to the following subtopic: "news..business.* ", and the publisher sends messages to "news.business.newyork " and "news.business.tokyo ". In this case the messages published to either subtopic will be delivered to the consumer. The wildcard character in the last position will match any token in that position as well as tokens after it. For instance, subtopic com.foo.* will match all of the following: com.foo. bar, com.foo.abc.def , etc. However, the wildcard character in any position other than the last will match only one token. For example, subtopic com.*.foo will match com. abc.foo and com.123.foo , but will not match com.foo . See example. Publishing a message only/also as a push notification - By default Backendless delivers published messages only to the "pub/sub subscribers", that is programs subscribed to receive messages using the Subscription API. However, published messages can also be delivered as push notifications to the registered devices. The publishing API provides a way to configure the delivery mode for the following three modes: API Subscribers (see example) Only as Push Notifications (see example) API Subscribers and Push Notifications (same example as above, see the comment in the example's code) Publishing a push notification to a group of devices - Backendless can deliver messages published as a push notifications to devices grouped by operating system. That is messages can be delivered only to Android devices, iOS or Windows Phone or a any combination of these. See example. Publishing a push notification and targeting specific devices - By default Backendless delivers published messages to all matched subscribers. (Subscribers may be matched by the topic name or a query). Alternatively, publishers can direct messages to specific subscribers by specifying the subscriber or device ID in message meta-data. See example. Delayed publishing - Backendless immediately processes any published messages and delivers them to subscribers without any delay. However, publishers can specify the time when the message should be processed. This is applicable to all the publishing options listed above. Message processing can be canceled at any time using the message cancellation API. See example. Scheduled (repeated) publishing - Backendless supports repeated message processing - a message is published once, but delivered to subscribers with the specified frequency. Repeated delivery can stop either at the specified time or they can be canceled using the message cancellation API. For instance, this could be used for reminders or scheduled tasks. See example . Method Signatures where: $msg $publish_options $delivery_options © 2015 Backendless Corp. - message text. - optional argument. An instance of the PublishOptions class. Contains publisher ID, message headers and subtopic name. - optional argument. An instance of the DeliveryOptions class. May specify message delivery policy (push, pub/sub or both), timestamp (in milliseconds) for publishing at the 98 Backendless REST API Return value: Array containing message ID and the status of the publishing operation: Errors: When the server-side reports an error, it returns array in the following format: Errors: The following errors may occur during the message publishing API call: Error Code Description 5003 Invalid repeatExpiresAt date in delivery options. 5007 User does not have the permission to publish messages 5030 Invalid publishAt date in the delivery options. Examples: Basic message publishing Publishing with message headers Publishing to a subtopic Publishing a message only as a push notification Publishing a message as a push notification and targeting specific group of devices (grouped by OS) Publishing a push notification and targeting specific devices Delayed publishing Repeated publishing Basic message publishing Publishing with message headers Publishing to a subtopic Publishing a message only as a push notification Publishing a message as a push notification and targeting specific group of devices The only difference between this example and the one above is the value of the pushBroadcast property in DeliveryOptions : Publishing a push notification and targeting specific devices Delayed publishing © 2015 Backendless Corp. Messaging Service 99 Repeated publishing 3.8 Publish Push Notifications Publishing a push notification is a specialized usage of the Message Publishing API. Push notifications have different graphical representation on different mobile operating systems. For instance, a push notification on an iOS device may be either an alert or a badge update, however a notification on a Windows Phone device may be either a toaster alert or a tile element update. Backendless supports different formats of the push notification delivery to various operating systems via specialized message headers. These headers must be added to the publish options object or in case of REST clients, they are plain message headers: Operating Headers System Description iOS "ios-alert":value Sets the text of the alert message. If the header is not present and the published notification targets the iOS devices, Backendless sets the header to the value of the "message" argument. To disable this behavior, set the ios-alert header to null . "ios-badge":value Sets the value to update the badge with "ios-sound":URL string or array of bytes Sets either a URL for the sound notification to play on the device or an array of bytes for the sound to play. Android © 2015 Backendless Corp. "android-ticker-text":value Sets the text of the ticker showing up at the top of a device's screen when the device receives the 100 Backendless REST API notification. "android-content-title":value Sets the title of the notification as it is visible in the Android Notification Center "android-content-text":value Sets the message of the notification which appears under androidcontent-title in the Android Notification Center. Windows Phone "wp-title":value, "wp-content":value Sets the title and the content of a toast notification. "wp-type":"TILE": "wp-title" : value, "wp-backgroundImage" : URL string, "wp-badge" : number value, "wp-backTitle" : value, "wp-backImage" : URL string, "wp-backContent" : value Sets the properties for a tile notification. "wp-type":"RAW", "wp-raw":XMLString Sets the properties for a raw notification Push notifications can be published directly from Backendless Console or using the API (see the examples in the Message Publishing section). 3.9 Cancel Scheduled Message Delayed or scheduled messages can be canceled using the API documented below. Backendless processes delayed messages at the time specified by the publisher. Scheduled messages are processed and delivered with a specified interval. Method Signatures where: message_id - ID of the message to cancel. Errors: The following errors may occur during the message cancellation API call: Error Code Description 5040 Message has already been canceled or does not exist. © 2015 Backendless Corp. Messaging Service 101 Examples: 3.10 Message Subscription In order to receive published messages, application must subscribe to a channel using the API below. Using the API, an application becomes an "API subscriber". Another form of subscription can be accomplished by using the Device Registration API which provides a way to receive push notifications. Note that the same mobile application can use both device registration and message subscription APIs. where: channel - channel name of the message to subscribe (if not set used "default"). subscriptionOptions - optional argument. An instance of SubscriptionOptions which can be used to set subscriber ID, subtopic or selector. Errors: The following errors may occur during the message cancellation API call: Error Code Description 5008 User does not have permission to create a subscription. 5009 General subscription error. See error message for additional details. 5010 Unknown messaging channel. Examples: Retrieving Messages Method Signatures: where: $channel_name $subscribe_id - channel name of the message . - id result of subscription ( $subscribe_id = Backendless::$Messaging->subscribe("default") ["subscriptionId"] ). Example: Message Filtering Backendless message filtering is a powerful mechanism enabling conditional message delivery, interestbased subscriptions and private messaging. A subscription request may include filters in the form of subtopics and selectors. Backendless applies subscriber's filters to every message published into the channel and they match, the message is delivered to the subscriber. Subtopics Multiple subtopics can be defined within a channel. Both publishers and subscribers can specify © 2015 Backendless Corp. 102 Backendless REST API a subtopic within a channel. Subtopic names can be defined using a multi-tiered format: maintoken[.secondaryToken][.additionalToken] To receive messages from more than one subtopic, subscribers can use the wildcard character (*) in place of any tokens in the subtopic name. For instance, a subscriber could subscribe to the following subtopic: "news..business.* ", and the publisher sends messages to "news. business.newyork " and " news.business.tokyo ". In this case the messages published to either subtopic will be delivered to the consumer. The wildcard character in the last position will match any token in that position as well as tokens after it. For instance, subtopic com.foo.* will match all of the following: com.foo.bar, com.foo.abc.def , etc. However, the wildcard character in any position other than the last will match only one token. For example, subtopic com.*.foo will match com.abc.foo and com.123.foo , but will not match com.foo . Selectors A selector is a query expressed using the SQL-92 syntax and formatted as the condition part of the SQL's WHERE clause. A query condition must reference the headers of the published messages. When a message is published and a subscriber has a selector query, Backendless executes the query on the headers of the published message. If the result of the query is true, the message is delivered to the subscriber. Consider the following example where the subscriber will receive only messages containing the "city " header with the value of "Tokyo ": Publisher: Subscriber: 3.11 Sending Email Backendless provides API for email delivery on behalf of your application. Before the API can be used, the Backendless backend must be configured with your own SMTP server information. This is an important requirement as the API will not work if the Manage > App Settings > Email Settings section in Backendless Console contains default values. Configuration To configure a backend: 1. 2. 3. 4. Login to Backendless Console. Select an app. Click Manage, then scroll down to Email Settings on the App Settings screen. Fill out the form with the SMTP server information © 2015 Backendless Corp. Messaging Service where: SMTP Server Port From User ID Password Security 103 - Hostname or public IP address of the server where the SMTP server is running. - The port number the SMTP server accepts requests on. - The Name which will appear in the From field of the sent out emails. - The user id or email address for the SMTP server connection authentication - The password for the SMTP server connection authentication. - Choose between SSL or TLS connection. Make sure to click Test before saving any configuration changes. The Discard button discards any unsaved changes. Sending Email API Delivers an email message using current server-side email settings to the recipient specified in the API call. Methods: where: $subject $body © 2015 Backendless Corp. - email message subject. - plain text or HTML body of the email message. 104 Backendless REST API to attachments - a collection or one email addressed to deliver the email message to. - an array of file paths for the file entries from the Backendless File Service. Referenced files will be attached to the email message. The path is calculated from the root of the file system (as it is seen in File Service browser in Backendless console) without the leading slash. For example, if file agreement.txt is located at /documents/legal/, then the path in the API call must be "documents/legal/agreement.txt". Example: 4 File Service 4.1 Overview Every Backendless backend/app is allocated a dedicated file storage space. The file storage is located remotely on the Backendless servers. The file storage can be used to store application's files and ondemand video streams. Backendless File Service provides the API to work with the file storage. The API supports the following operations: File Upload - upload files to the applications's file storage. The operation creates directories up the hierarchy if necessary. Returns file URL which can be used to download or share the file with others. File Download - download file using file's URL. The download operation is subject to the permissions from the File access control list (ACL). File Deletion - delete a file from the file storage. The delete operation is subject to the permissions from the File access control list (ACL). Directory Deletion - same as file deletion, but applies to the directories. File/Directory Security (File ACL) - assign/unassign user and roles permissions to upload, download and delete files and directories. This API is used to modify file or directory ACL. In addition to the API implementation, the File Service enables the following capabilities: Git Integration - application developers can interact with the file storage as with a git repository. Web Hosting - file storage can be used to host static web content. Custom Domain Name - a custom domain name can be mapped to the file storage in a Backendless backend. This feature in combination with the Web Hosting provides a way to host websites on Backendless. Custom Web Templates Hosting - includes HTML files and JS scripts for special pages used in various workflows such as user email confirmation, password change and session expiration. 4.2 Setup PHP clients can consume the Backendless services using the class library provided in the Backendless SDK for PHP. Make sure the backendless directory with all the classes is located in the root of the project directory. Download SDK © 2015 Backendless Corp. File Service 105 The SDK can be downloaded from the Backendless website. Include Backendless SDK In you project file add the following line to include Backendless SDK for PHP: Alternatively, you can use require_once or include for adding Backendless SDK. Before the php client uses any of the APIs, the code must initialize the Backendless Application using the following call: Example: Application ID and Secret Key Values for the application-id and secret-key headers must be obtained through the Backendless Console: 1. Login to your account and select the application. 2. Click the Manage icon from the vertical icon-menu on the left. 3. The "App Settings" section is selected by default. The interface contains the text fields for "Application ID" and secret keys for each supported client-side environment. 4. Use the "Copy" button to copy the value into the system clipboard. © 2015 Backendless Corp. 106 Backendless REST API The version argument must contain the name of the targeted version. When a new application is created, the default version name is "v1" . To manage versions, login to the console, select the "Manage" icon and click "Versioning". 4.3 Handling Files via Console Backendless Console includes a graphical file browser which supports the following operations: Creating new file Editing a file Getting public URL for a file Creating file archives Creating a New File You can create a file in Backendless Console with the following file extensions: .conf, ,css, .csv, .htm, .html, .ini, .java, .js, .log, .php, . properties, .py, .rb, .sh, .txt, .xml, .xsd To create a file: 1. Log in to Backendless Console. Select an application. Click the Files icon: © 2015 Backendless Corp. File Service 107 2. Select a directory where a new file should created. Click the New File button at the top of the file listing table. 3. Enter the name in the File name field and select a file extension from the Syntax highlighter drop-down menu: 4. Enter the contents for the file as necessary. Click the Save button. Editing a File Backendless supports in-browser editing of the files with the following extensions: .conf, ,css, .csv, .htm, .html, .ini, .java, .js, .log, .php, . properties, .py, .rb, .sh, .txt, .xml, .xsd To edit a file: © 2015 Backendless Corp. 108 Backendless REST API 1. Select a directory containing the file on the Files screen of the console. 2. Click the Edit file icon next to the file to open it for editing: 3. Once the changes in the file are made click the Save button. Getting Public URL for a File A file in Backendless File Storage has two URLs: a public URL which can be used to download the file outside of Backendless console. This URL accounts for any permissions assigned to the file or the directory where it resides. a private URL which makes the file accessible by the developer of the application. In order to obtain the public URL: 1. Select a directory containing a file on the Files screen of Backendless console. 2. Click the Get Public URL icon next to the file. Backendless console copies the file's public URL to the computer's clipboard: © 2015 Backendless Corp. File Service 109 Archiving Files Backendless Console includes a feature enabling to compress directories into a single ZIP file. The feature applies specifically to directories, meaning an individual file cannot be compressed - it must be placed into a directory first. Notice: archiving of directories with total content size greater than 100 Mb may take longer time; Backendless sends an email to the application developer upon successful completion of the operation. To archive a directory: 1. Log in to Backendless Console. Select an application and click the Files icon. 2. Navigate to a directory which should be compressed. 3. Click the ZIP Directory button: 4. Once the directory is compressed into an archive, it will appear in the parent directory: © 2015 Backendless Corp. 110 4.4 Backendless REST API File Upload The file upload operation delivers and saves a local file in the remote Backendless file storage. The return value of the operation is the file URL which has the following structure: https://api.backendless.com/<application id>/<version name>/files/ <path>/<file name> where: <application id> <version name> <path> <file name> - ID of the application which can be obtained from the Manage > App Settings screen of the Backendless Console - application's version name - directory path where the file is saved - name of the file The URL assigned to a file and returned as a result of the upload operation accounts for any security permissions assigned to the file (or the folder it is located in). Backendless Console includes a file browser with the management functions to upload files, create or delete directories and files. The file browser is available in the Files section of the console: © 2015 Backendless Corp. File Service 111 File browser also provides a way to see the contents of the files. Every file is a link which opens the file. The URL of files in file browser is not the same as the URL returned by the file upload operation. The reason file browser uses a different URL is to let the application developer see the file contents without any application security constraints. The only constraint applied to the URLs available in file browser is the application developer must be logged to the console. Method: where: file path - an instance of php File class or string with path to file. - directory path (without the name of the file) in the Backendless file storage where the file should be stored. If the path does not exist, Backendless File Service creates the directory structure. Return Value: The return value, which is the URL of the uploaded file. Additional API Classes: BackendlessFile Example: 4.5 Save Files From Byte Arrays In addition to the traditional file upload, files can be saved by uploading a byte array which becomes the content of the saved file. Method: where: file Additional API Classes: BackendlessFile © 2015 Backendless Corp. - an instance of php File class. 112 Backendless REST API Example: The example below describes how to save a file entitled "fox.txt" from the string "The quick brown fox jumps over the lazy dog." You will need to specify: content of a new file ("The quick brown fox jumps over the lazy dog") where to save a new file ("testfolder") a name of the newly created file ("fox.txt") whether a new file should overwrite the existing file, if any (true) Errors: Error codes returned on attempt to save a file from the byte array. Error Description Code 4.6 6016 When saving a new file from the byte array, the payload exceeds 2,800,000 bytes. 6003 A file you are trying to save already exists in the system and cannot overwrite since overwrite argument is ether set to false or omitted. File Download Downloading a File via the Backendless Console To download a file: 1. Log in to Backendless Console. 2. Select an application for which you want to create a new file. The application page will display 3. Click the Files tab on the left menu. The Root folder containing all files of an application will display. 4. Locate a file you want to download. Click the Download file icon next to this file. © 2015 Backendless Corp. File Service 113 Method: where: file - string with remote file path for example '/savedNote.txt'. Example: Downloading a File via API Downloading a file from the Backendless file storage is the basic HTTP GET operation. The operation should use the same URL which Backendless returned as the result of the file upload operation. Alternatively, if the file was uploaded manually using the console, the URL can be composed as: https://api.backendless.com/<application id>/<version name>/files/ <path>/<file name> where: <application id> <version name> <path> <file name> - ID of the application which can be obtained from the Manage > App Settings screen of the Backendless Console. - Application's version name. - Directory path where the file is saved. - Name of the file. Files fetched with the URL scheme defined above are subject to the security constraints and permissions established by the application developer. See the Files Security section for additional details on how to secure file storage. Fetching a file secured by an access control list (ACL) policy requires an additional HTTP header in the request: user-token:<value> © 2015 Backendless Corp. 114 Backendless REST API where: <value> - Value of the user token established for the current user session as a result of the user login operation. The token uniquely identifies the user session. It is used by Backendless to establish user identity for all operations where the token is present. This is necessary in order to determine permissions applicable to the user and the roles associated with the account. 4.7 File Deletion To delete a file from the Backendless file storage, it must be identified by the file path/name. Files in the Backendless storage have the following URL structure: https://api.backendless.com/<application id>/<version name>/files/ <path>/<file name> The API to delete a file uses the <path>/<filename> part to identify the file which must be deleted. Method: where: $file_path - Path of the file to delete. The path must consist of the file path and file name. Example: 4.8 Directory Deletion To delete a directory from the Backendless file storage, it must be identified by the its path. Directories in the Backendless storage have the following URL structure: https://api.backendless.com/<application id>/<version name>/files/ <path> The API to delete a directory uses the <path> element from the URL above. Method: where: $directory_path - path of the directory to delete. Example: 4.9 Git Integration Backendless file storage can also function as a git repository. This could be very convenient for deploying multiple files from the developer's computer with a single command. Git integration is disabled by default. To enable git for the file storage: 1. Open Backendless Console 2. Select your app/backend 3. Click Manage and scroll to the Enable .git support section 4. Use the toggle to turn git integration on or off: © 2015 Backendless Corp. File Service 115 When the git integration is turned on, all files present in or uploaded to the file storage are immediately committed to the repository. This integration is bi-directional. It means that any files committed into the git repository by the means of git, will also be copied into the file storage. When git integration is being turned off, the git repository is deleted with all the associated history (the files remain in the file storage). With the git integration enabled, a new folder (.git) appears in the File Browser on the Files screen. The folder contains the files from the git repository. When a file is uploaded to file storage either via the Upload API or using the File Browser, it is automatically committed to the repository. Likewise, when a file is pushed into the repository, it becomes available and visible in the file storage. The same applies to editing and deleting files either in the Backendless Console or in git repository. When git is enabled, the repository is available at the following address: https://git.backendless.com/<application id>/.git where: <application id> - application ID available in Backendless Console at Manage > App Settings . When the Backendless backend is configured with a custom domain name, the repository URL is: http://<custom domain name>/.git The repository uses the same authentication as Backendless Console. That means all git commands must use the same developer email address and password as for logging in to Backendless Console. It is important to note that any system level files created by git are also placed into the file storage (the . git directory). These files are accounted for when calculating the file space used by the app/backend. Configuring Local Environment You have no local files and there is a remote GIT repository: There are files in the Backendless storage and there are no files locally: Clone existing repository: mkdir /path/to/your/project cd /path/to/your/project git clone http://git.backendless.com/<your application id>/.git cd <your application id> Adding a file locally and pushing to Backendless git: > > > > echo "First file" >> file.txt git add file.txt git commit -m 'Initial commit with new file' git push -u origin master © 2015 Backendless Corp. 116 Backendless REST API You have with an existing GIT project in your local environment: This applies when you already have a local git project. You also enabled git integration in Backendless and need to "integrate" your local git project with the git repository in Backendless. > cd /path/to/my/repo > git remote add origin http://git.backendless.com/<your application id>/.git # pushes the repo and its refs for the first time to Backendless git > git push -u origin --all # pushes any tags to Backendless git > git push -u origin --tags You have an existing FILE project in your local environment. This applies when you have existing files locally and need to add them to the git repository you initialized in Backendless. > cd /path/to/my/repo > git init > git remote add origin http://git.backendless.com/<your application id>/.git > git pull -u origin master > git add * > git commit -m ‘merge with existing project’ > git push -u origin master 4.10 Web Hosting Backendless file storage includes a special directory which facilitates web hosting for the app/backend. The directory name is /web : © 2015 Backendless Corp. File Service 117 The /web folder serves as the web server root. The web server is available at the following URLs: With custom domain name enabled for the account: http://custom domain name Without custom domain name: https://api.backendless.com/<application id>/<version name>/files/ web where: <application id> <version name> 4.11 - ID of the application which can be obtained from the Manage > App Settings screen of the Backendless Console - application's version name Custom Domain Name Backendless File Service supports mapping of a custom domain name to the application's backend. As a result, once a domain name is mapped, the following backend's resources become available via the custom URL: Service API endpoint. The default endpoint for all Backendless services is: https://api.backendless.com With a custom domain name, the endpoint is also available at: http://<custom domain name>/api Web Hosting. Backendless file storage contains a special directory - /web , which serves as the web site root. When a custom domain name is mapped to a Backendless application/backend, the contents of the /web directory are served for the HTTP requests with the domain name. See © 2015 Backendless Corp. 118 Backendless REST API the Web Hosting section for additional details. git endpoint. When the Backendless git integration is enabled, the git endpoint with a custom domain name is: http://<custom domain name>/.git Before a custom domain name is assigned to a Backendless application: 1. Create a CNAME record for the domain name and map it to backendless.com. 2. Open Backendless Console and select your application/backend. 3. Click Manage and scroll down to the "Custom Domain" section. 4. Enter the domain name into the text field and click Save The Custom Domain mapping is a feature included into Backendless Plus package. The package enables multiple features for a flat monthly subscription fee. Backendless Plus can be enabled in console at Manage > Billing . 4.12 Custom Web Template Hosting A client-to-backend workflow may include interaction with web pages presented to the users of the application. Consider the following scenarios: User registration. When a user registers with an application, he receives an email with a link to a page. Clicking the link acknowledges that the email address is valid and the user account is confirmed. Password change. When a user requests password change (or password recovery), an email is sent to the user with a link to a web page where they can reset the password. Session expiration. When a user session with the application expires, he is redirected to a webpage. All these use cases have something in common - they all force the user to interact with a web page. The Backendless Plus package allows to customize the look and feel of these pages. Once Backendless Plus is enabled (use the Manage > Billing section in console to turn it on), Backendless puts the templates for these pages into the /web/templates path of the backend's file storage: © 2015 Backendless Corp. File Service The default style of these pages is neutral: Registration confirmation page: Password change page: © 2015 Backendless Corp. 119 120 Backendless REST API Session expiration page: The look and feel as well as the logic in the pages can be customized by modifying the HTML/CSS /JS files provided for each template. For example, the contents of the change_password folder is: © 2015 Backendless Corp. File Service 4.13 121 Files Security Access to files and directories can be restricted using permissions. Backendless supports the following permissions for files and directories: Read - permission to download a file. This permission can be applied to a directory, in that case it applies recursively to all files contained therein. Write - permission to upload a file or modify a directory by uploading files into it. Remove - permission to delete a file or a directory. To modify the permission matrix for a file or a directory, click the "Edit Permissions" link in file browser in console. The permission assignment screen contains allows to work with permissions for specific user accounts or for application roles. To assign permissions to a user account, type in userid in the "enter user name" field, select the user(s) and click "Add": © 2015 Backendless Corp. 122 Backendless REST API To modify a permission for an operation for a user, click the icon in the corresponding column. The icon has 3 states: - inherit GRANT permission from the global permission matrix. This is the default permission. - explicit GRANT of the permission for the operation. Allows the user to perform the operation. - DENY permission for the operation. Restricts the user from performing the operation. Managing permissions for roles is identical to users, except all roles are automatically listed in the table: 5 Geo Service 5.1 Overview Backendless Geolocation Service is a system supporting management and search of geo points. A geo point in the most primitive format consists of a pair of coordinates: latitude and longitude. Optionally a geo point may contain metadata, which is a collection of arbitrary key/value pairs. A geo point belongs to a category, which is a logical grouping of geo points. The diagram bellow illustrates these concepts: Backendless allows infinite number of geo points managed for an application. Geo points can be added via an API call or the import functionality in Backendless console. Once the backend is populated with geo points, the search API can be used to run the following types of geo queries: Radius-based search - Searches for geo points in a circular map area defined by the coordinates of the central point and a radius. Backendless returns all geo points within the area. © 2015 Backendless Corp. Geo Service 123 Search in a rectangular map area - Searches for geo points in a rectangular map area identified by the coordinates of two corners defining the area (North West and South East): Additionally, the geo search API supports the following search options available in the APIs: Filtering by categories - Both types of search (radius-based and rectangular) can specify the categories in which the backend should search for the geo points. Query-based search - The metadata associated with the geo points can be used in queries which should be formatted using the SQL-92 syntax. For example, the geo point shown in the image above can be discovered with the following queries: cuisine = 'French' cuisine LIKE 'Fr%' and Atmosphere = 'Casual' cuisine = 'French' and (Price = '$$$$' or Price = '$$$') Relative search - Runs a search for a subset of metadata key/value pairs to match up to the specified threshold value. The threshold must be expressed as a percentage of matches. © 2015 Backendless Corp. 124 5.2 Backendless REST API Setup PHP clients can consume the Backendless services using the class library provided in the Backendless SDK for PHP. Make sure the backendless directory with all the classes is located in the root of the project directory. Download SDK The SDK can be downloaded from the Backendless website. Include Backendless SDK In you project file add the following line to include Backendless SDK for PHP: Alternatively, you can use require_once or include for adding Backendless SDK. Before the php client uses any of the APIs, the code must initialize the Backendless Application using the following call: Example: Application ID and Secret Key Values for the application-id and secret-key headers must be obtained through the Backendless Console: 1. Login to your account and select the application. 2. Click the Manage icon from the vertical icon-menu on the left. 3. The "App Settings" section is selected by default. The interface contains the text fields for "Application ID" and secret keys for each supported client-side environment. 4. Use the "Copy" button to copy the value into the system clipboard. © 2015 Backendless Corp. Geo Service 125 The version argument must contain the name of the targeted version. When a new application is created, the default version name is "v1" . To manage versions, login to the console, select the "Manage" icon and click "Versioning". 5.3 Adding a Geo Category This API creates a geo category. A geo category is a logical grouping of geo points. Category name may contain the following literals: a-z, A-Z, numbers 0-9 and the underscore (_ ) character. The name must start with a literal. Category names can be inspected using Backendless Console (see the image below) or using the API call retrieving a list of categories. Adding Categories in Console Backendless Console supports adding a category via the graphical interface. To create a category: 1. Login to Backendless Console 2. Select your app/backend. 3. Click the Geolocation icon in the menu on the left. 4. Use the "plus" icon in the section containing the list of categories: © 2015 Backendless Corp. 126 Backendless REST API 5. Enter the category name in the popup and click "Save". The image below shows the Geolocation screen with categories in the app: © 2015 Backendless Corp. Geo Service 127 Adding Categories with the API Method: where: $category - can be array or string or GeoCategory calss object. Example: 5.4 Deleting a Geo Category This API deletes a geo category. If the category does not exist, the service returns an error. Removing Categories in Console Backendless Console supports category deletion via the graphical interface. To delete a category: 1. Login to Backendless Console 2. Select your app/backend. 3. Click the Geolocation icon in the menu on the left. 4. Use the "minus" icon in the section containing the list of categories: © 2015 Backendless Corp. 128 Backendless REST API 5. Select 'Yes' in the confirmation popup. Deleting Categories with the API Method: where: $category - can be array or string or GeoCategory calss object. Example: © 2015 Backendless Corp. Geo Service 5.5 129 Retrieving Geo Categories This API retrieves a list of all the application's geo categories. Methods: where: true - if set true method return multi array otherwise objects collection. Example: 5.6 Adding a GeoPoint This API adds a geo point to the backend geo location storage. Once a geo point is added, it becomes searchable through all search mechanisms supported by Backendless. At the present moment there are two ways to add geo points: (1) using this API or (2) using the Backendless console's import function. Method: where: $point - GeoPoint class object . Example: 5.7 Updating a GeoPoint Geo update API relies on the same methods used for Adding a Geo Point. The primary difference is in order to update a geo point it must have the objectId property assigned by Backendless. The semantics of the properties in an update request is as follows: objectId is a required property. All other properties (latitude , longitude , categories , metadata ) are optional, but at least one must contain a value. If latitude or longitude contain values, the new values replace the existing ones. If categories contains a value, the geo point is moved to the specified categories (with coordinates and metadata). If categories is null , the geo point stays in the current category. If metadata is null , the geo point keeps the current metadata. If metadata contains any key/value pairs, the new metadata replaces the existing one. If metadata is an empty object/dictionary, the existing metadata is removed. 5.8 Deleting a GeoPoint There are two ways to delete a geopoint from the Geolocation storage: Using the Backendless Console Using the API Deleting a GeoPoint using the Backendless Console To delete a geo point using the Backendless Console: 1. Log in to the Backendless Console, select your app and click the Geolocation icon. 2. Select the geo category from which the geopoint will be deleted. 3. Click the checkboxes next to the geopoint(s) which should be deleted. 4. Click Delete Selected from the button bar as shown below: © 2015 Backendless Corp. 130 Backendless REST API 5. Click Delete in the confirmation popup to confirm the deletion: 6. A confirmation notification will appear in the top right. The selected geopoint(s) are removed. Deleting a GeoPoint with API Method: where: $point - GeoPoint class object . Example: © 2015 Backendless Corp. Geo Service 5.9 131 Importing Geo Data Backendless console supports bulk import of geo points with metadata. The import procedure automatically places the geo points into the specified categories. The raw data must be in a comma separated values (CSV) format. A single line in the file defines one geo point as shown below: latitude,longitude,"category1,category2","key1=value1|key2=value2" where: - the latitude coordinate of a geo point longitude - the longitude coordinate of a geo point category1,category2 - comma separated list of categories. The value must be enclosed in double quotes. key1=value1|key2=value2 - Geo point metadata. Multiple key/value pairs must be separated with the pipe "|" character. The value must be enclosed in double quotes. latitude Consider the following example: 40.4165,-3.70256,"restaurants,popular","city=MADRID|cuisine=french| price=high" 41.38879,2.15899,"restaurants,popular","city=BARCELONA| cuisine=asian|price=low" To import geo points: 1. Open Backendless console. 2. Select the application/backend. 3. Click Manage, then Import. 4. Click the "add file" button next to "Geo Service" and select the file to import. 5. Click the "Import" button to initiate the import process. The import process runs asynchronously. When the process is complete, Backendless sends an email to the application developer. The email text includes the log entries informing about any errors which could have occurred during the import. Upon successful completion of the import, the Geolocation section of the console displays the categories, geo points and their metadata: © 2015 Backendless Corp. 132 5.10 Backendless REST API Search in Category This API supports two types of geo searches: Search in one or more geo categories. Search in one or more categories based on metadata properties. Methods: where: $geo_query - a query object encapsulating the search parameters. See the Running Search Queries section below for details. Return Value: A collection of GeoPoint objects matching the search query. The class properties are: objectId latitude longitude categories metadata - an ID assigned to geo point by Backendless when it is saved in the backend geo location storage. - latitude of the geo point. - longitude of the geo point. - an array of geo categories the point belong to. - metadata associated with the geo point. Accepted values for this parameter are: String, Number (integer and double), and Data Service objects. Date values © 2015 Backendless Corp. Geo Service 133 must be represented as number in the Unix timestamp format (number of milliseconds since January 1, 1970 at UTC). Learn more about using date in search queries for category, radius, or rectangular area search. Running Search Queries The geo query object includes multiple parameters, none of them are required. As a result, depending on which parameters contain values, the semantics of the search would change. Any search must be performed within at least one category. If no category names are provided, the search is performed in the Default category. Search in categories To search in one or more categories without any constraints on metadata or proximity to a center point, simply set the names of the categories in the query object. The request returns all geo points divided into pages of data, one page at a time. Search in categories with metadata Metadata-based search finds all geo points which match all specified metadata properties in the given categories. The example below searches for the geo points in the Restaurants category with metadata containing "Cuisine = French" and "Atmosphere = Romantic" . Search in categories by date The search query used to retrieve geo points may reference date values. These values must be stored as a number of milliseconds since January 1st, 1970 at UTC. The example below demonstrates the use of a date/time timestamp in a search query. Using dates in where clause when searching in categories The search query used to retrieve geo points may reference date values. These values must be stored as a number of milliseconds since January 1st, 1970 at UTC. The example below demonstrates the usage of a date/time timestamp in a search query: Requesting meta in response Geo points returned in the search results do not include their metadata properties by default. The search query object includes a property which can be used to request the metadata to be included. This property can be used with any search options described above. For example, the following code runs a search in a category and requests the metadata to be included: 5.11 Search in Radius This API supports multiple types of geo searches: Search for geo points located within specified distance (radius) from a given point. Search in radius based on metadata. Method: where: $backendless_geo_query © 2015 Backendless Corp. - instance of BackendlessGeoQuery class. 134 Backendless REST API Running Search Queries The geo query object includes multiple parameters, none of them are required. As a result, depending on which parameters contain values, the semantics of the search would change. Any search must be performed within at least one category. If no category names are provided, the search is performed in the Default category. Search in categories with radius Radius-based search establishes a circular area by setting the coordinates of a central point and a distance (radius). Backendless searches for geo points in the specified distance from the coordinates in the center and includes them into the search result. The value of the distance is interpreted based in the units parameter, which can be METERS , KILOMETERS , MILES , YARDS , FEET: Search in categories with radius and metadata This is the same as above, with the difference that the search result includes only geo points with the matching metadata: Search in radius by date The search query used to retrieve geo points may reference date values. These values must be stored as a number of milliseconds since January 1st, 1970 at UTC. The example below demonstrates the use of a date/time timestamp in a search query. Using dates in where clause when searching in radius The search query used to retrieve geo points may reference date values. These values must be stored as a number of milliseconds since January 1st, 1970 at UTC. The example below demonstrates the usage of a date/time timestamp in a search condition: Requesting meta in response Geo points returned in the search results do not include their metadata properties by default. The search query object includes a property which can be used to request the metadata to be included. This property can be used with any search options described above. The syntax for requesting metadata in response is described in the Search in Category section. 5.12 Search in Rectangular Area This API runs a search within a rectangular area of the map. The area is defined with the coordinates of the North West and South East corners of the map rectangle. Method: where: $backendless_geo_query - instance of BackendlessGeoQuery class. Running Search Queries The geo query object includes multiple parameters, however, only the coordinates defining the rectangular area are required. A search query must be performed within at least one category. If no category names are provided, the search is performed in the Default category. Search in a rectangle in categories Rectangle-based search establishes a geographic area by setting the coordinates of the North West and South East corners of the area. Backendless searches for geo points in the specified area and includes them into the search result: Search in categories in a rectangular area and metadata © 2015 Backendless Corp. Geo Service 135 This is the same as above, with the difference that the search result includes only geo points with the matching metadata: Search in rectangular area by date The search query used to retrieve geo points may reference date values. These values must be stored as a number of milliseconds since January 1st, 1970 at UTC. The example below demonstrates the use of a date/time timestamp in a search query. Using dates in where clause when searching in a rectangular area The search query used to retrieve geo points may reference date values. These values must be stored as a number of milliseconds since January 1st, 1970 at UTC. The example below demonstrates the usage of a date/time timestamp in a search query: Requesting meta in response Geo points returned in the search results do not include their metadata properties by default. The search query object includes a property which can be used to request the metadata to be included. This property can be used with any search options described above. The syntax for requesting metadata in response is described in the Search in Category section. 5.13 Geo Point Clustering Geo point search in a category, radius or a rectangular area may return too many geo points within close geographic proximity from each other. This might be difficult to view and process in a client application. To address this problem, Backendless supports the geo clustering feature. A geo cluster is a group of several geo points located close to each other. The two screenshots below demonstrate the advantages of clustering: the picture on the top displays search results in the Backendless Console with clustering turned off and the one on the bottom displays search results as clusters when clustering has been enabled: Geo Points View: Clusters and Points View: Backendless creates clusters by splitting the map into a grid of squares. Geo points which belong to a square are placed into the same cluster. When a square contains © 2015 Backendless Corp. 136 Backendless REST API only one point, it remains non-clustered. Enabling Geo Clustering in Backendless Console The Geolocation page displays non-clustered geo points by default. To enable clustering: 1. Log in to Backendless Console, select an application and click the Geolocation icon. 2. Click the Map-driven navigation toggle. The toggle changes how the geo points are loaded from the backend. In the map-driven mode console loads the geo points for the rectangular area shown in the map. 3. Click the Geo Clustering toggle to enable clustering. 4. Console reloads geo points and clusters for the current viewport of the map and displays the results. A cluster is visualized as a blue marker on the map with a number indicating how many geo points it represents. © 2015 Backendless Corp. Geo Service 137 Geo clustering is also available with the "Search in Radius" option, which searches for geo points in a circular area. To enable this functionality, click the Search in radius toggle: If you want to see the geo points in a cluster, zoom in the map or double-click a cluster's marker. Zooming the map in too much (when using the clustering along with the search in radius) may result that the search radius will be much bigger than the visible part of the map on the screen. In this case, the pop-up window will display offering you to resize (zoom out) the map. Clicking the Yes button zooms the map out. © 2015 Backendless Corp. 138 Backendless REST API Clicking a cluster's marker will reveal the coordinates and metadata of a cluster. Retrieving Clustered Geo Points Geo point clustering can be requested by setting clustering parameters in BackendlessGeoQuery, which is used in the calls to retrieve geo points from a category, radius or rectangular area: Method: where $west_longitude $east_longitude $map_width - the longitude of any point on the western boundary of the map in degrees. - the longitude of any point on the eastern boundary of the map in degrees. - the size of the viewing area of the map in pixels. © 2015 Backendless Corp. Geo Service $cluster_grid_size 139 - the size in pixels of the grid's squares used to group points into clusters. The default value is 100 pixels Example: Once the clustering parameters are set, the geo point search API will return clustered geo points. The return value is a collection of GeoCluster and/or GeoPoint objects. Instances of the latter may be returned when a geo point does not have any neighboring points within the grid's square it belongs to. The GeoCluster class extends from GeoPoint and supports all the inherited properties: latitude, longitude, categories and metadata. Additionally, geo cluster has its own property representing the number of points the cluster consists of. Since a GeoCluster object an instance of the GeoPoint class, the processing of search responses may look like this: 5.14 Relations with Data Objects Backendless Data Service manages application's data objects and provides APIs to work with data objects. Backendless provides integration between data objects managed by Data Service and geo points managed by Geo Service for the scenarios when a logical connection between the two types must exist in an application. For instance, in a taxi ordering app a data object may represent a taxi car, while a geo point represents its location on the map. It is logical to link the two together so they can be retrieved and managed at once. The Geo-to-Data integration is implemented through geo point metadata. A metadata property may reference one or more data objects. These relations may be created using the API or with Backendless Console. Once a relation is established, the console displays it in the Metadata column as a link to related data object(s). When a geo point is retrieved using the API, any related data objects can be retrieved by using the same principle for loading geo point metadata. The geo-to-data relation is bidirectoral, that is, a data object may reference a geo point through object properties (table columns). You can learn more about it in the Relations with Geo Points section of the Data documentation. Apart from linking with the data objects, you can also link a geo point with a user object. Establishing relations with a user objects is performed the same way as with a data object. Establishing Relations with a Data Object via Console To link a geo point with a data object: 1. Click the Geolocation icon to open the Geo location screen. 2. Select a geo category to get a list of geo points from it. 3. Click the plus icon for the geo point you want to link with a data object. © 2015 Backendless Corp. 140 Backendless REST API 4. The Add Related Object pop-up window will display. 5. Type in a metadata property name in the Metadata property name field. The new property will be associated with the related data object. 6. Select a data table from from the Data table drop-down menu. If you want to establish relation with a user object, select the Users option from the drop-down menu. A list of the data objects which belong to the selected table will display. 7. Select the check-boxes for the data object(s) you want to link with the geo point. 8. Click the Add Related Objects button to establish a relation and save the changes. Once the relation is established, the name of the property and the related data table will display next to the corresponding geo point. Updating Relations © 2015 Backendless Corp. Geo Service 141 You can update a geo to data relation (for instance, add or remove objects to/from the relation) by following the instructions below: 1. Select a geo category and locate the geo point. 2. To update a geo to data relation, click the link with the name of the data table in the geo point metadata column. 3. To add a new geo-to-data metadata property, follow the instructions above. 4. For both scenarios (2) and (3), use the Add Related Object pop-up window to make the necessary changes. 5. Click the Update Relation button to save the changes. Deleting Relations To delete a relation between a geo point and a data object: 1. Select a geo category and locate the geo point. 2. Click the link with the name of the data table in the geo point metadata column. The Add Related Object pop-up window will display. © 2015 Backendless Corp. 142 Backendless REST API 3. Un-check the check-boxes next to the data objects you want to unlink from the geo point. 4. Click the Update Relation button to save the changes. Establishing a Geo to Data Relation by using API Creating a relationship between a geo point and data objects uses the same API as saving a geo point with metadata. The data object is also persisted in the Data Service. 5.15 Geofence Designer About Geofencing Geofencing on the surface, comprises drawing a stationary geometric boundary around an area on a map. This action creates programmatically a set of simple or complex global coordinates which represent a shape. A boundary represents a “fence,” which surrounds the area. For Backendless, the boundary and area become meaningful when a Geopoint crosses the boundary or stays within the area. Geofences work with Geopoints. A Geopoint is the most elementary Geolocation concept in Backendless. It is a point (latitude and longitude coordinate pairs) on the map that is accessible via API and allowed to move (change coordinates), i.e., a user carrying a mobile device. In addition to the coordinates, the Geopoint includes metadata in context for the Geopoint. The Geofence Designer Geofence Designer is a feature of the Geolocation service available under Geolocation > Geofencing. It is a “design time” tool for drawing Geofences on an interactive global map and associating them with events and actions, which can be triggered based on the location of registered Geopoints. Backendless integrates the designer with Google Maps™, enabling the developer to design precise Geofence positions, locations, and shapes. The Design Tool includes line, rectangle, and circle drawing tools (the cursor changes from hand to crosshairs when selected) for creating Geofence boundaries. Boundaries can be geometrically symmetrical or irregular shapes and have no minimum or maximum size constraints. In use cases, a © 2015 Backendless Corp. Geo Service 143 Geofence conceptually “fences in” a city block, a shopping center, a sports stadium, or perhaps a mall; even smaller geographic areas are possible such as the shoe department in a retail store. The Line Tool To define an irregular Geofence, the line tool draws editable line segments and control points. For example, in the United States, the shape of Nevada is irregular. To create this shape, select the line tool to start drawing lines around it. Place the cursor on the map where the first control point should be and click. Drag the cursor to the next place and Click again. The first line segment appears. Repeat these steps until you have nearly completed the shape of your boundary. (It’s not a Geofence just yet.) Click the cursor on the last control point (which was the first one set). Backendless detects a closed shape and enables a new Geofence. NOTE: If you accidentally close the Geofence before completing the drawing, the New Geofence dialog box appears. If you click Cancel, the Geofence will be removed. To keep the Geofence, click Save, then re-edit the shape as needed. © 2015 Backendless Corp. 144 Backendless REST API Immediately after the shape closes, a popup appears prompting you to name the Geofence. Enter a name in the Geofence Name text box. Since this example uses the state of Nevada, it makes sense to name it Nevada. Click Save to enable the Geofence. (We will refer to this example again.) The result is a new item row in the List of Geofences. The Geofence area is filled with green, and the item row is highlighted in yellow when a Geofence is selected on the map or on the list. See the image below. Naming Geofences with intelligible names is a good practice. Any alphanumeric character or special character is permitted. An unusual scenario could be two cities with the same name, but in different states, such as Dallas, Texas and Dallas, Illinois. A solution and a best practice could be Dallas-Texas and DallasIllinois. This practice should apply to © 2015 Backendless Corp. Geo Service 145 all three tools. The Rectangle Tool The Rectangle Tool is self-describing. A fence can be drawn quickly around a square or rectangular area. After the Geofence is named and saved, the shape aspect can be adjusted by dragging a line segment or corner control point. Like the line tool, parameters can be entered in a dialog immediately after the shape is drawn. Should you need to edit the shape, an undo tool appears and to restore the previous edit. The Circle Tool The Circle Tool is also self-describing. A circle can be drawn quickly around an area, repositioned, and resized. Like the line tool, parameters can be entered in a dialog immediately after the shape is drawn. Deleting a Geofence A Delete button is positioned directly below the interactive map. For each selected checkbox next to the Geofence hyperlink, the Delete button removes those Geofences. Once a Geofence is deleted, it cannot be restored. List of Geofences and Locator Tool A map filled with Geofences can appear cluttered, especially if the design comprises numerous shapes across several remotely located areas. Backendless organizes the boundary data and actions in a table format below the map, the List of Geofences. The table contains a row for each Geofence along with parameter controls. © 2015 Backendless Corp. 146 Backendless REST API From left to right, the second column shows the Geofence name, which is hyperlinked to the Update Geofence dialog. The Geofence locator icon is next to the Geofence hyperlink (see image below). The tool repositions the map view to an optimal zoom-level, from which the Geofence boundary can be easily viewed, accessed, and edited. For example, two cities in Texas, Arlington and Plano, have several Geofences in each. In the image below the map is tightly zoomed on an area in Plano. The work on Plano is done, so the developer needs to reposition the interactive map to Arlington. Click the locator icon next to an Arlington Geofence. Backendless repositions the map and sets the optimal zoom level. Further, it does not matter whether the two Geofences are on different continents; the locator tool works the same either way. Geofence and Geopoints Events Geofences and Geopoints are integrated entities of Geolocation. As such, Backendless tracks three specific events: When a Geopoint enters a Geofence, crosses the boundary, On Enter action © 2015 Backendless Corp. Geo Service 147 executes. When a Geopoint stays inside a shape for a preconfigured amount of time, On Stay actions executes. When a Geopoint exits the Geofence, it crosses the boundary and is outside the shape, On Exit action executes. Geopoint Qualification Criteria: Exclusion/Inclusion Tracking every Geopoint within a Geofence is not desirable in every case. A Geofence plan could specify tracking only Geopoints of a certain nature, for example, visitors or preferred customers. Qualification Criteria, which identifies the types of Geopoints Backendless traces and tracks for a specific geogence, can be defined in the Update Geofence dialog. The Geofence hyperlink opens the dialog. A criterion, in this case, is a special string entered in the Geopoint Qualification Criteria text box. (The string format is the SQL 92 syntax, regular SQL as relates to a database query WHERE clause.) For example, if tracking only visitors, the SQL would need something like usertype=visitor . Where usertype is a Geopoints metadata property. visitor is the metadata property value. The string can be tested via the Validate button. Upon a successful validation, a success message displays. Conversely, Backendless could track only employees, excluding visitors, and function as a time clock action, such as clock-in and clock-out. Events and Actions Detecting, tracing, and tracking geopoints in relationship to a geofence establish the event clockwork for execution of developer defined actions. An event occurs as a Geopoint transports into and out of or stays in a Geofence. An action is a set of parameters the developer selects to perform a function, such as deliver a message to a mobile device or add a record to a database. Events Three event types are organized in columns in the List of Geofences. The events types are: On Enter – a Geopoint crosses the Geofence boundary into the defined area On Stay – a Geopoint remains in the Geofence area for at least a specified period On Exit – a Geopoint crosses the Geofence boundary out of the defined area © 2015 Backendless Corp. 148 Backendless REST API Actions For each of the above events, a developer can select an action and specify parameters to be executed from Backendless. There are four action types: Push notification Publish-subscribe (pub/sub) message Send a custom event Call a URL The scenarios for choosing an action are wildly different; however, they drive the action and parameter choices the developer makes. When an action type is selected for an event, a dialog appears where action parameters can be entered. The fields in the dialog are specific to the action type. Whenever an action is configured, visual elements indicate whether the parameters are complete. A gear icon and green checkmark indicate proper configuration, where as a red X in place of the checkmark indicates improper configuration. The configuration can be edited by clicking the gear to reopen the currently assigned action dialog. Push Notification Action All three Geofence events can trigger this action. Push Notification, in basic form, is a message sent to a mobile device associated with a Geopoint or to a group of devices registered with a channel. The Configure Push Notification Action dialog provides flexible parameter options: Content Configuration – configure Push Notification content look and feel for Android, iOS, or Windows Phone. Message Headers – allows header name and header value. Delivery – to individual Geopoints or those registered to a channel. © 2015 Backendless Corp. Geo Service 149 Send a Pub/Sub Message Action This action sends a publish/subscribe message. The developer enters the message parameters in the Configure Pub/Sub Message Action dialog. (Learn more about Message Publishing.) The dialog contains the following fields: Channel name – the name for a channel. Backendless creates the channel if it doesn’t exist. Topic name – the name of a topic used for filtered delivery. Message headers – optional. Use the key=value format. Comma delimited. Message body – written in JSON. The body of the message to be delivered. © 2015 Backendless Corp. 150 Backendless REST API A probation officer issues an ankle bracelet to a probationer. He needs to set area from which the probationer cannot leave, such as restricted to travel only within a state. The PO would set up a Geofence outlining Colorado’s state-line borders. For that Geofence, he would set the action event On Exit to send a notification to the application on his device that would provide metadata about the probationer such as location, the probationer’s photo, phone number, address, etc. Call URL Action This action executes an HTTP command on the specified URL. Supported commands are GET, POST, or PUT. The developer configures the call in the Configure Call URL Action dialog. The dialog contains the following fields: Command – choice of GET, POST, or PUT URL – a fully formed internet protocol URL. Request headers – any of the HTTP header types in the form of key=value. © 2015 Backendless Corp. Geo Service 151 Body – text message for calling the URL. Send Custom Event Provides a means for enabling Geofencing processing logic to execute your custom server-side code deployed to Backendless. Send Custom Event issues an event that you define in the Send Custom Event dialog box. See Custom Events under Business Logic. Backendless acts as a functional intermediary for your custom event handler which contains business logic specific to the application such as sending out an email or saving a record to a database. © 2015 Backendless Corp. 152 Backendless REST API Is Active - Geofence Monitoring Is Active is the final column in the List of Geofences. It indicates whether server-side Geofence monitoring can be activated. When monitoring is ON, Backendless tracks any movements of the Geopoints in relation to the corresponding Geofence. The list below shows item content: Missing Actions – look for red X next to the edit action gear. An action is improperly configured. ON/OFF Toggle – click to switch either on or off. ON activates the server-side monitoring for the selected Geofence. When an action is properly configured, i.e. complete, the Is Active toggle for the selected Geofence appears. When set to ON, a popup provides cautionary information and a checkbox option, which applies actions to Geopoints located within the Geofence at the time when the monitoring is turned on (i. e. the toggle is being set to ON). See the image below. © 2015 Backendless Corp. Geo Service 153 Once server-side monitoring is activated by setting the Is Active toggle to ON, a play button appears next to the gear icon. This button executes the action on-demand for any Geopoints within the Geofence. (This function can be useful when debugging.) View Geopoints in a Geofence For any Geofence that is currently active (i.e. is under server-side monitoring), a checkbox option displays Geopoints located within the Geofence. Geopoints located within the Geofence are represented by a marker for Google Maps inside the Geofence. The frequency of refresh on the screen is controlled by the refresh interval. The value is in seconds and can be set to a value from 10 to 300. You can force a refresh by clicking the refresh button. See the image below. 5.16 Geofence API The Geolocation service provides the following APIs: Run the OnEnter action © 2015 Backendless Corp. 154 Backendless REST API Run the OnStay action Run the OnExit action Retrieve geopoints from a geofence Run the OnEnter Action Requests the server to run the configured OnEnter action for a geofence either for all geopoints located within the geofence or for the specified geopoint. Method: where: $fence_name $point - name of the geofence for which the OnEnter action will run. - geopoint object ( or array with point coordinates ) for which the OnEnter action will run. Response body: Number of geopoints for which the action has been executed. Example: Run the OnStay Action Requests the server to run the configured OnStay action for a geofence either for all geopoints located within the geofence or for the specified geopoint. Method: where: $fence_name $point - name of the geofence for which the OnStay action will run. - geopoint object ( or array with point coordinates ) for which the OnEnter action will run. Response body: Number of geopoints for which the action has been executed. Example: Run the OnExit Action Requests the server to run the configured OnExit action for a geofence either for all geopoints located within the geofence or for the specified geopoint. Method: where: $fence_name $point - name of the geofence for which the OnExit action will run. - geopoint object ( or array with point coordinates ) for which the OnEnter action will run. Response body: Number of geopoints for which the action has been executed. © 2015 Backendless Corp. Geo Service Example: Retrieve Geopoints from a Geofence Retrieves a collection of geopoints currently located within a geofence. Method: where: $fence_name $query Example: © 2015 Backendless Corp. - name of the geofence for retrieve. - BackendlessGeoQuery object. 155 156 Backendless REST API Index -Bbackendless.jar 80, 104, 124 -IIdentity 6 -LLogin 11 Logout 19 -PPassword property recovery 6 22 -UUser Properties defining with API 6 defining with console 6 update user registration 16 User Registration API call 7 disable registration 7 email confirmation 7 registration with external system 7 © 2015 Backendless Corp. 157 Endnotes 2... (after index) © 2015 Backendless Corp. Back Cover