What is Codeless?

Codeless is a new and exciting alternative to creating code without a programming language. Using an intuitive user interface you express the logic for the tasks while operating with basic programming constructs such as loops, objects, variables represented by graphical blocks. A user does not need to know the syntax of a programming language or understand the lower-level programming complexities. All that is required is an understanding of the algorithm you would be composing graphically.

 

Consider the following example which contains a loop with 10 iterations. Each iteration of the loop saves an object in the Backendless database:

codless-example-loop

 

 

Codeless can be used for:

Developing general purpose or specialized API Services, microservices and IoT services.
Adding business logic to a Backendless application in the form of API Event Handlers.
Adding logic for scheduled server-side jobs (timers) which run accordingly to a schedule.
Implementing reusable libraries of logic.
Learning basic and advanced programming techniques.

 

The Codeless development environment is built into Backendless Console. You can compose logic and test it right in your Backendless backend. Codeless API services, event handlers and timers are processed and handled the same way as those developed with a programming language. In fact, any logic composed with Codeless is translated into JavaScript, therefore from the execution perspective, it is equally functional, scalable and secure.

 

The Codeless system supports the entire set of the Backendless APIs. Every supported API operation is represented by a dedicated block. As a result, Codeless can be used to create complex, specialized business logic for a Backendless application. For example, the logic below retrieves an object representing a person from the Backendless database and sends an email to the email address from the object:

codeless-example

How it works

Creating Codeless logic is very a straight-forward process. Suppose you need to build an API Service, then you start by adding a new API service. Similarly, when adding Codeless logic for event handlers and timers, you would start on the Event Handlers and Timers screens. Once a service, an event handler or a timer is declared, you proceed to adding the logic using the Codeless Business Logic Designer. The Logic Designer is an interactive environment for expressing logic using "Codeless Blocks". A single codeless block represents an operation such as comparison, assignment, API call, etc. For more details on available blocks, see the Codeless Blocks section of this guide.

 

The diagrams below show the general workflow for different types of codeless logic:

 

Codeless API Service:

new-codeless-service

 

Codeless API Event Handler:

new-codeless-event-handler

 

Codeless Timer:

new-codeless-timer

 

Blocks can be snapped to each other to express programmable logic. Most of the blocks have input and output parameters. The input parameters work with the data of a particular type. For example, the "Save Object in Backendless" block has the "table name" input argument which must be a string value. If you try attaching a non-string block to that input parameter, it will not snap:

 

As the logic is composed, Backendless generates the code which will be executing it. You can see the code on the Code tab. It is updated in real-time as the changes are made:

 

The composed logic for event handlers and timers can be SAVED or DEPLOYED.

When the logic is SAVED - it is stored for editing later, any changes in the logic are not enabled for execution.
When the logic is DEPLOYED - it is both saved as described above and the code is put into production.

 

The logic for API services can only be deployed - there is no intermediate (non-deployed) storage for that logic type.

 

Deployed logic enables the following functionality:

Download native client SDKs (Android, iOS, JS) generated for the service.
Invoke service operations from the Backendless Console, REST or native clients (Android, iOS, JS). Invocation from a native client is possible using the generated SDK. See the Service Invocation section for additional details.
Restrict/secure service operations for the application's users and roles.
See the service operations invocations in Backendless Analytics (the Manage > Analytics section in console).
Event handler logic is executed before/after the corresponding API event.
Logic can modify incoming API arguments or change the outgoing return value.
Logic in the "before" handlers can stop API invocation from proceeding further.
Timer logic is executed according to the specified schedule.

Codeless Logic Designer

The Logic Designer interface supports a complete development life cycle for creating the Codeless logic. This includes development, testing and deployment. Logic Designer is available on the Business Logic screen - click Business Logic, then CODELESS.

 

It is important to become familiar with the interface so you can use it efficiently:

codeless-designer-not-shrunk.zoom40

 

Where the functional areas of the logic designer are:

 

Codeless Logic Browser

codeless-browser-panel
 
1. BROWSER Tab. The browser section provides an easy access to all types of codeless logic (API Services, Event handlers, Timers and Functions).

2. Current element. Highlights the element currently opened for logic editing.

3. Code tab. As you design a Codeless logic, Backendless automatically generates the code which will be executed once the logic is deployed. You can see the code in this tab.

4. New Function. Creates a new codeless function. See Function Library for more information on Codeless Functions.
 

Codeless Toolbar:

codeless-toolbar.zoom30

5. The toolbar contains multiple sections an categories. Each category contains blocks for the category. For additional information on available blocks, see the Codeless Blocks Reference section of the documentation.
 

6. Most frequent blocks - this is a dynamic category containing most frequently used blocks. It provides a convenient shortcut for the blocks you use most often, so you do not have to search for them.

 

7. Custom Functions - this is a category containing your reusable functions.

 

Control Toolbar:

control-toolbar-codeless.zoom30

8. Add Block/block search. A search bar which can help you finding a block using a text search. For example, type "text" for a list of all blocks performing some kind of function on text.

 
9. SAVE - saves the current logic for further editing (notice the SAVE functionality is not available for API Services, services can be only deployed).

 

10. DEPLOY - deploys the current logic to production and makes it live.

 

Main Editing Area:

codeless-main-editing-area.zoom30
 

11. Main logic canvas - this is the area where you drag and drop the blocks from the toolbar to. The main canvas always has at least one block, which is the root of the corresponding API service method, event handler or timer.

 

12. Context blocks. These are special blocks which represent values available in the context of an API method invocation (such as method arguments), an event handler invocation or a timer execution. For more information see the following sections:

 

13. Neutral zoom/Center. The main canvas contents can be moved around simply by dragging them out of the way. Additionally, you can zoom out/in and thus change the viewport. This button restores the neutral zoom level and centers the contents of the main canvas.

 

14. Zoom in/out. Using these buttons you can change the zoom level of the main canvas (similarly, the zoom level can be changed using the scroll button on your mouse).

 

15. Trash bin. Drag and drop a block you would like to delete to this trash bin.

Codeless Blocks Reference

Blocks is the foundation of the Backendless Codeless system. A single block represents one of the following:

a logical operation;
a programmable loop, which is a construct allowing to repeat one or more operations multiple times;
a scalar value (number, boolean, string, date)
a collection of values;
an object, which is a collection of properties. Each property has a name and a corresponding value. The value can be a scalar, a list or an object;
a variable which can be assigned a value;
a math operation (addition, subtraction, division, multiplication, power of, square root, etc);
a trigonometry function (sine, cosine, tangent, cotangent, etc);
a string operation (to upper case, to lower case, substring, etc);
a Backendless API call - there is a block for every single API available from Backendless;
an API Service method - every single API service available in the app is represented by a block;
a custom function;

 

Block Categories

All available blocks are grouped into categories in Logic Designer:

codeless-blocks-categories.zoom70

 

Most frequent - a dynamic group of most frequently used blocks. Can be used as a shortcut to find/get most frequently used blocks.
Custom Functions - contains library functions, which are general purpose custom blocks created for reusability. See Function Library for details.
API SERVICES - contains a list of API Services deployed into the backend application. Each API Service category contains blocks representing its operations. As an example, the image above shows two API Services - "SampleService" and "CodelessShoppingCartService".

 

SYSTEM blocks

Logic - blocks for executing conditional operations. Such as if/then, comparisons, negation, and the ternary operator.
Loops - blocks for creating loops
Date - blocks for date-related operations.
Object - blocks for creating new objects, retrieving and setting object's properties.
Math - math-related operations.
Text - text-related operations (literal string values, concatenation, upper/lower case, substrings, length, etc.
Lists - operations on lists and collection of data.
Variables - blocks for declaring a new variable, assigning a value to a variable, retrieving variable's value.
Functions - blocks for creating and using inner scope functions.

 

BACKENDLESS blocks

Users API - blocks for using Backendless Users API providing the functionality for registering app users, login, logout, password recovery, etc.
Data API - blocks for working with the Backendless database.
Messaging API - blocks for publish/subscribe messaging and push notifications.
Geo API - geolocation blocks - creating and retrieving geo points, geo searches.
File API - blocks for working with Backendless Hosting - creating, copying, renaming and deleting files and directories. Retrieving directory listings.
Logging API - block for logging a message in the Backendless log file.
Counter API - blocks for working with the server-side (centralized) counters.
Cache API - blocks for storing and retrieving data from the server-side cache.
Network API - blocks for creating HTTP/HTTPS requests and retrieving content from a remote resource.

Logic

Block name

Block rendering


If..else

if-else


Value comparison

value-comparison


Logical comparison

logical-comparison


NOT operator

not-operator


Constant boolean value

constant-boolean


Constant null value

null-value


Ternary operator

ternary-block


Check value type

check-value-type


Loops

Block name

Block rendering


Loop with limit

repeat-do


While/until loop

while-until-loop


Loop with variable, range and interval

loop-with-range-interval


For-each loop

for-each-loop


Break out of the loop,
Continue with next iteration

break-out-of-loop


Date

Block name

Block rendering


Date/time now

date-now


Offset date/time

offset-date


Get date property

get-date-property


Set date property

set-date-property
 
set-date-property-expanded


Convert date/time

convert-date


Object

Block name

Block rendering


Create object with properties

create-object


Set object property

set-property-in-object


Get object's property value

get-property-value


Delete object property

delete-object-property


Get object's property names

get-object-prop-names


Math

Block name

Block rendering


Basic arithmetic operation

math-arithmetic


Round a number

math-round


Mathematical operations

math-advanced-ops


Trigonometry functions

math-trigonometry


Mathematical constants

math-constants


Number checks

math-number-checks


Scalar value

math-scalar


Collection operations

math-list-operations


Remainder/modulo calculation

math-remainder-modulo


Limit constraint

math-limit-constraints


Random integer

math-random-int


Random float

math-random-float


Strings

Block name

Block rendering


Strings concatenation.

text-concat


Get a letter from text/variable value.

text-letter-extractor


Append text to variable value.

text-append


Get string length.

text-length


Check if text starts with, ends with or contains other text.

text-starts-endswith


Checks if the string contains any characters.

text-isempty


Finds a substring index in a variable value.

text-substring


Returns a substring.

text-getsubstring


A constant string value.

text-constant


Transforms text to upper case, lower case or title case.

text-uppercase


Trims text.

text-trim


Sends string to Backendless log.

text-print


Lists

Block name

Block rendering


Gets an object from a list.

list-getobject
list-getobject2


Gets object's index in a list.

list-getobject-index


Creates a list with an object.

list-create-list


Gets list size.

list-size


Checks if the list is empty.

list-check-ifempty


Creates a list with objects.

list-createlist


Creates an empty list.

list-create-empty-list


Sets/inserts an object at index into a list.

list-set-insert
 

list-set-insert2


Gets a sublist from a list.

list-sublist


Makes list from text or text from a list.

list-make-list-from-text


Sorts list.

list-sort


Creates a collection consisting of objects accessible through the named property in the original collection.

list-pluck

If the original collection contains objects A, B and C and each object has property foo, the resulting collection contains values accessible via A.foo, B.foo and C.foo.

Variables

Block name

Block rendering


Sets a value to a variable.

var-set-value


Gets variable's value.

var-get-value


Change variable's value by.

var-change-by

If the variable contains a numeric value, the specified value is added to it. Otherwise, the specified value is assigned to the variable.

Changes to another variable or renames or deletes a variable.

var-ops


Functions

The Functions category includes blocks for creating local functions, which can be used within the scope of a single API service method, an event handler or a timer. For reusable functions, see the Function Library section of the documentation.

 

Block name

Block rendering


Declares a function without a return value.

func-declare

To rename the function, click the do something area and enter a new name for the function.

Declares a function with a return value.

func-declare-with-return

To rename the function, click the do something area and enter a new name for the function.

Declares function arguments.

func-args

 

func-args2

To declare a function argument, click the gear icon and drag the input name block into inputs. The default argument name is x. To rename the argument, click x and enter new argument name.

Conditional return statement.

func-if-return


Calls the function declared above.

func-call-no-return

Notice the function declaration does not have a return value. As a result, the block to call the function has the appearance of a procedural block.

Calls the function which returns a value.

func-call


Errors and Exceptions

Block name

Block rendering


Throws an error with the error message.

error-throw


Constructs a new error object.

error-new-error


Creates a try/catch/finally block.

error-try-catch

If the logic in the Try section throws an error, it is caught and handled in the Catch with error section. The error variable contains the information about the error. The Finally block is executed after the logic in Try or Catch with error is done processing.

Backendless API

 

Users API

Block name

Block rendering


Returns currently logged in user.

users-get-current-user


Returns security roles of the currently logged in user.

users-get-current-user-roles


Initiates password recovery for the user.

users-recover-password


Saves/updates a user in the database.

users-save-userobject

users-save-userobject-return


Logs in a user.

users-login

users-login-return


Logout the current user.

users-logout


Removes a user identified by an objectId value.

users-remove


Finds user by objectId or identity.

users-findby


Data API

Block name

Block rendering


Saves object in a table in the database.

data-save-object


Deletes object from the database.

data-delete-object


Returns the first or the last object from the database.

data-get-first-last-object


Returns table schema.

data-get-table-schema


Returns objects from the database table.

data-get-table-objects

The objects are returned using paging - up to the number specified in the page size parameter per page.

Returns the total number of objects in the table or the number of objects matching the where clause condition.

data-get-object-count


Sets related objects for a relation column in the parent object.

data-set-object-relations


Adds related objects to a relation column in the parent object.

data-add-object-relations


Deletes related objects for a relation column in the parent object.

data-delete-related


Returns related objects for a relation column in the parent's object.

data-load-relations


Messaging API

Block name

Block rendering


Sends an email to one or more recipients.

messaging-send-email


Sends a publish/subscribe message.

messaging-send-pubsub


Sends a push notification.

messaging-send-push


Geo API

Block name

Block rendering


Saves a geopoint in the database.

geo-save-geopoint


Deletes a geopoint from the database.

geo-delete-geopoint


Creates a geo category in the database.

geo-create-geocategory


Deletes a geo category from the database.

geo-delete-geocategory


Returns a list of geo categories.

geo-get-categories


Returns the number of geopoints in a category optionally matching the metadata properties.

geo-get-count


Returns a list of geopoints from the categories optionally matching the metadata.

geo-find-points


Returns a list of geopoints within the specified radius from the center point optionally matching the metadata.

geo-find-points-radius


Returns a list of geopoints found in a geographic (rectangular) area identified by the specified coordinates, optionally matching the metadata.

geo-find-points-map


File API

Block name

Block rendering


Creates a file in the Backendless file system.

file-create-file


Renames a file or a directory.

file-rename-file


Moves a file or a directory to another directory.

file-move-file


Copies a file or a directory to another directory.

file-copy-file


Deletes a file at the path.

file-delete-file


Deletes a directory at the path.

file-delete-directory


Return a list of directory entries (files and directories) matching the pattern using paging.

file-get-directory-listing


Retrieves a property from an object returned in the list from the directory listing block.

file-get-listing-object-property


Logging API

Block name

Block rendering


Logs a message in the Backendless logging system.

log-a-message


Counter API

Block name

Block rendering


Increments a counter and optionally returns the current or the previous value of the counter.

counter-inc


Decrements a counter and optionally returns the current or the previous value of the counter.

counter-dec


Sets counter value if the counter contains an expected value. Optionally returns the current value of the counter.

counter-set-conditionally


Returns the current value of the counter.

counter-get-current


Resets the counter to zero.

counter-reset


Cache API

Block name

Block rendering


Puts an object (or a primitive value) into cache.

cache-put


Returns an object (or a primitive value) from cache.

cache-get


Checks if the data is present in cache. Returns true or false.

cache-check


Deletes data from cache.

cache-delete


Extends data life in cache.

cache-extend


Network API

Block name

Block rendering


Makes an HTTP request and optionally returns the server response.

http-request


Returns an HTTP method which can be used in the block above.

http-method


Constructs a parameterized URL using the template and the object's values.

url-builder

Consider the following example:

url-builder-example

 

The block will construct the following URL:

http://foo.bar.com/value1/value2

Errors

Block name

Block rendering


Creates and returns an error object which can be thrown using the Throw error block.

new-server-code-error


API Services

API Services represent independently operating logic which follows the request-response pattern. An API service contains one or more operation which has a dedicated endpoint available on a network. An operation may have zero or more arguments and may return a value which is the result of the operation.

 

An API Service may be specific for a backend application or may provide general purpose functionality. For example, an API service which implements specific business rules for a hotel booking app has a specialized purpose. However, an API service which generates QR codes for the given input would be considered general purpose.

 

Backendless supports both types of services, though it does not distinguish between them as it is the logic inside of a service which makes it either a specialized or a general purpose one.

What is a Codeless API Service

An API Service is a logical unit with one or more API endpoints. These endpoints are available in two formats:

via HTTP REST endpoint URI
via native SDK

 

The logic of a Codeless API service is created with the Backendless Codeless Logic Designer. A service is identified by a name and must contain at least one operation/method. An operation has a name which must be unique within the service, optionally there may be method arguments and it may explicitly declare a REST route. When a service is deployed, Backendless generates an API endpoint for each operation. If you are not familiar with these concepts, do not worry, most of them are optional - you will still be able to create API services without any coding.

 

Backendless automatically generates both REST endpoints and native SDKs for the deployed service logic. Access to an API Service is secured by Backendless security, where individual service operations can be granted or denied access for application's users and roles. Additionally, Backendless gathers analytics for the service' API usage. The diagram below visually demonstrates these concepts:

codeless-api-service-diagram

Quick Start Guide

This guide will walk you through the process of creating a codeless API service. By the time you finish the guide, you will know how to:

create a codeless API service and add methods to it.
edit codeless logic for a method.
deploy logic changes.
invoke codeless method from console.
generate client side SDK.
invoke the service from a JS client.

 

The video below shows all the steps described in this guide:

Creating API Service

1. Register and login to your Backendless account at https://develop.backendless.com. Click the Business Logic icon.
2. The API SERVICES section is selected by default. Click the "+" icon and select CODELESS.
new-codeless-service-quick-start.zoom50

 

3. Enter TimeService into the Service Name field and click SAVE. Backendless creates a service definition and wil prompt you to create the first method.
4. Enter the values as shown below, specifically:
 
getServerTime for Method Name,
GET for REST Operation,
/servertime for REST Route
 
Click SAVE to create the method:
add-codeless-method.zoom50

 

5. Backendless creates codeless method declaration and displays the main anchor block. Click the EDIT button to edit the method's logic:
codeless-method-view.zoom50

 

6. Backendless opens Codeless Logic Designer, which is a visual environment for creating logic for your service's method. The service appears in the BROWSER panel located on the right side of the screen. The logic is composed using "blocks". All blocks are grouped into categories, which are listed on the left side of the screen. The central area contains the root block of the getServerTime method. This block cannot be removed and it will contain the logic of the method. It also contains a special return connector which is used to identify the value returned from the method.
codeless-logic-editor-service.zoom30

 

7. This guide does not go into a lot of details on learning blocks and composing logic. Instead it will walk you through specific steps for composing a minimalistic service logic.
 
Click the Date category under SYSTEM and drag and drop the Date Now block into the main (central) editing area. Snap the Date Now block to the return connector of the root block:
get-server-time-method

 

8. Click the DEPLOY button to deploy the logic changes. Backendless deploys the logic and confirms with a status popup in the upper right corner of the browser.
9. Click the CLOSE button to return to the API Services screen. At this point the service is ready for invocations.

Invoking Service Method

REST Client

1. To invoke the service method from Backendless Console, click the API SERVICES section and select the getServerTime method. Click the INVOKE button. Console makes a REST request to the service and displays the result:
codeless-method-invocation.zoom50
 
The method in this guide does not have any arguments, however, for other methods you will create, you can enter argument values on the PARAMETERS tab.
2. For any invocation made in console a cURL command is generated so you can invoke the operation from a command line. Click the CODE tab and copy its contents. Paste it into a terminal/command prompt window and run the command:
running-curl-codeless.zoom50
 

 

Generated SDKs (Android, iOS, JS)

1. Backendless generates a client SDK for each API service. To download the SDK, click the download icon as shown in the image below:
download-sdk-for-codeless
2. Click the JavaScript option from the drop-down menu. You will download a zip file with the generated client-side code. Unzip the file into a directory. This directory will be referred to as <project-root> throughout this guide.

This guide reviews service invocation from a JS client, however, similar instructions are applicable for other client types/languages.

3. Open <project-root>/TimeService.html in a text editor and add the following <script> block. Make sure the code is added after the line which imports TimeService.js:
<script>
    TimeService.getServerTime().
            then( function( serverTime ) {
        console.log( "Server time is " + serverTime );
    })
</script>

Notice the TimeService class (which is generated by Backendless) has the blocking and non-blocking implementation of the getServerTime method. Invoking your codeless method from a client is as simple as a local object invocation.

4. Save the file and run it in a browser. When the page loads, open the Console tab for the browser developer tools, you will see the following output, which is a response from your codeless service:
browser-invoking-codeless-service

 

This concludes the quick start guide. Happy Codeless Coding!

Service Declaration

To create a codeless API service navigate to the Business Logic section of the Backendless console and click the "+" icon on the API SERVICES screen. Select the CODELESS tab in the New Service popup. You will be prompted to enter a name for the service. The name of the service is significant - it will be used in the REST route for the service operations and in the generated client code. The name cannot start with a number and cannot contain space characters:

new-codeless-service-quick-start.zoom50

 

Clicking SAVE creates the service definition and you will be prompted to create first service method. A "method" is the minimal unit of executable logic. It has a name and may optionally have argument, which represent data sent to the service from the client. See the section below on adding service methods.

 

Logic must be created/edited at the method level, that is every method must have its own logic. It is possible to create re-usable logic through the Function Library. When editing method's logic, it can be either saved or deployed. Saving logic persists it for future editing, but the logic is not available for runtime execution. To make it executable, logic must be deployed. For additional information, see the Codeless Development section of this guide.

Adding Methods

Backendless console automatically prompts you to create a method as a part of the workflow for creating a new service. This is done because of a requirement that a service must have at least one method:

new-codeless-method

 

Method Name - must be unique for a service. Method name cannot contain spaces and must not start with a number. Method name becomes a part of the generated REST route unless it is overridden with the REST Route parameter.
REST Operation - an optional parameter. If specified, identities an HTTP operation which the method will respond to. Available options are:
GET - indicates that the method must returns a value. The method should not change any internal state of the application. This is strictly a data retrieval operation.
POST - represents an operation responsible for creating a new resource or storing some initial content/state.
PUT -  this type of operation is used for updating existing resources/content/state.
DELETE - is used to delete resources stored in the application.
 
If a REST operation is not explicitly set, Backendless selects one based on the method name prefix using the rules below:

method name prefix

HTTP operation

addXXX

POST

setXXX

PUT

deleteXXX

DELETE

getXXX

GET

none of the above - foobar

POST

 

REST Route - an optional parameter. If specified, becomes part of the URL used for RESTful service invocations. Otherwise, the value is the method name in lower case.

 

Additional methods can be added at a later time. Use the "+" icon under the service name:

add-codeless-method-iconn

Method Parameters

The New Codeless Method popup is used to declare method parameters. A parameter represents a value sent to the service from the client. A parameter has a name and a type. The name of the parameter is used in the method's logic to reference the value sent by a client. The type identifies the format of the data which can be used the client. For example, the image below shows a method declaration with two parameters: name of the String type and grades which is an array of numbers:

addStudent-method

 

Backendless supports the following parameter types:

Boolean - represents binary values such true and false.
String - is a sequence of characters representing text.
Number - a numeric value.
Array - a linear collection of values. The types of values must also be selected when defining parameter type.
Any Object - a value without a specific type. This is a "catch all" data type which can accommodate all supported types.
Data Object - a value with the structure mapped to a data table from the Backendless database.

 

Both parameter name and type are significant for the following purposes:

1. Backendless console generates a dynamic form used for method invocation. Both name and type are used to create an appropriate form element which can accept parameter value.
2. Client SDKs generated by Backendless for a service include the code used to invoke the service methods. The generated code relies on the parameter information in order to create client code in a client language (Java/Objective-C/Swift/JavaScript) which closely matches what's expected on the server-side.

Service Logic Designer

Backendless Logic Designer must be used for creating logic for Codeless API services. To open the Logic Designer for a Codeless method, select it from the list of methods on the API SERVICES screen, click the LOGIC tab and click the EDIT button:

edit-button-codeless-method

 

See the Codeless Logic Designer section for additional information.

Context Blocks

The Context Blocks area in Codeless Logic Designer includes blocks which provide access to the "contextual" information. For the API services these include:

Method arguments blocks (if any are declared)

If a service method is created with parameters, they can be accessed using special blocks. Consider the following service method declaration which includes a parameter:

codeless-method-with-args

 

When editing the method's logic in the Logic Designer, it shows the block for the argument in the Context Blocks section:

logic-designer-context-with-arg

 

When using the "method argument" block, it returns the value sent by the client in the method invocation.

 

Request Info Blocks

Application ID - id of the application in which context the method is invoked.
app-id-block
 
User ID - objectId of the currently logged in user whose identity is used to invoke the method. A value for this parameter is not present if there is no logged in user (or if the user-token header is not passed for the REST invocations).
user-id-block

 

User Roles -  an array/list of the role names of the logged-in user (if any) who made the API service call.
user-roles-block

 

User Token - value of the user-token header sent by the client application when invoking the service
user-token-block

 

Device Type - the type of the device (as a string value) which initiated the method invocation. Possible values are "IOS", "ANDROID", "JS", "REST", "BL" (business logic)
device-type-block

 

Request Path - path in the request URL which identifies the invoked method. This is the part of the URL which comes after <service version>: in the complete service request URL:
https://api.backendless.com/<App ID>/<REST API key>/services/<service name>/<service version>/<method's REST route>?params
request-path-block

 

Request Headers - HTTP headers sent by the client application when invoking the service.
request-headers-block

 

Request Path Parameters -  if the service operation is declared with a parameterized custom REST route, the parameters can be accessed with the following block:
request-path-params

 

Request Query Parameters - all parameters for the methods recognized or declared as HTTP GET must be sent in the URL's query string. Service logic can use the following block to get access to these parameters:
request-query-params-block

Service Invocation

 

Using Generated SDKs

Backendless instantly generates native client side SDKs when a service is registered. This applies to all API services, regardless of the language used to implement them. The SDKs can be downloaded using the Download Client SDK icon:

download-client-sdk-codeless

 

The generated client-side code is very easy-to-use and is self-explanatory. There is a class representing client-side proxy of the remote service. The class contains the same methods as the service. The implementation of the methods hides the complexity of the remote method invocation. To call an API operation, simply create an instance of the proxy class and invoke its methods.

REST API

Backendless Console provides a visual interface for invoking service operations via the generated REST interface. To invoke a service operation, click its name. Console renders operation arguments based on the argument type information from the service declaration.

 

Backendless Console uses the generated REST API when invoking service methods. As a result, you can also see the details of an invocation using the Network tab in the browser's developer tools.

 

HTTP GET operations

Parameters for the HTTP GET operations must be sent as URL's query params. Consider the following example:

getitem-codeless-method

Since the method name starts with "get", Backendless will generate an HTTP GET route for the operation. When the method is selected in console, the parameter is rendered as shown below:getitem-parameter-form-codeless.zoom70

Notice that you can specify additional parameters on the PARAMETERS tab. This is allowed because it is an HTTP GET operation and all parameters are sent to the server in the URL's query string - thus any parameters not explicitly defined by the method can also be sent to the service. Any "dynamic" parameters can be obtained in the logic with the following context block:

request-query-params-block

HTTP POST|PUT|DELETE operations

Parameters for POST\PUT\DELETE operations must be sent in the payload/body of an HTTP request. Console renders the parameters based on their declaration when a method is created. Consider the following example:

post-method-codeless For methods with more than one argument, Backendless combines them into a JSON object on the request side:

addnote-codeless-args.zoom70

 

Clicking the body schema area copies its contents into the body field where it can be edited. To invoke the method click the INVOKE button which sends a service invocation request to Backendless.

Security

Access to service APIs can be restricted with the user/role-based security of the application where the service runs. A permission either allows or denies invocation of a method for a specific user or all users who belong to a role. Follow the steps below to configure service security:

1. Login to Backendless console, select the application where the service is deployed and click the Business Logic icon.
2. Select a service from the list in the API Services section.
3. Click the Set Permissions icon in the toolbar:set-permissions-codeless

The permissions management user interface has two sections: User Permissions and Roles Permissions. Both sections use the same principle for applying permissions to users/roles for all or specific service methods. Select a method which should be secured using the method selector list or if the permission assignment for a user/role is going to be the same for all methods, use All Methods:

api-services-permission-method-selector.zoom80

 

To change permission assignment, click the icon at the intersection of a user/role row and the Method column. The icon represents the current permission and has three states which can be changes by clicking the icon.

ico-grant - Represents a permission allowing method invocation for the specified user or role.

ico-reject   - Represents a permission denying method invocation for the specified user or role.

ico-checkmark-gray - Represents "inherited" permission allowing method invocation. Since service permissions do not have the concept of global assignments, the gray check mark essentially is the same as the green one.

 

Runtime Permission Handling

The NotAuthenticatedUser role applies to any API request which does not have a user identity identified by the user-token HTTP header. The value of the user-token header is obtained on the client side from the result of the login API.

 

When Backendless receives a service API call, it uses the value from the user-token header to determine the user's identity and all the roles the user belongs to. Once a list of roles is identified, Backendless checks all assigned permissions for the user and his roles for the invoked method. If any of the permissions deny access, the invocation will be denied and an error is returned back to the client.

 

When testing service invocations with Backendless console, an authenticated request can be performed by logging in a user on the HEADERS page for a method:

login-to-impersonate-codeless

 

Once a user is logged in, Console uses the assigned user-token for all service method invocations made through console.

Analytics

Backendless automatically tracks service API usage. Every service method invocation is captured by the Backendless Analytics module and can be viewed using Backendless Console:

1. Login to Backendless Console and select the app where the service is deployed.
2. Click the Manage icon, then Analytics.
3. Click the Service Name and Method Name checkboxes.
4. Select the service(s) from the Service Name dropdown list to see the usage of the service APIs:
analytics-codless.zoom70

The API usage is categorized by the type of clients initiated method calls. To see a chart corresponding to a specific client type, service and method simply click the checkbox for that row. The Total Calls column shows the number of API calls made by the specific client type (the All Clients rows show the total calls across all client types).

Backendless Event Handlers

An event handler is a custom, server-side code which responds to an API event. For every API call Backendless generates two types of events - "before" and "after". The before event is fired before the default logic of the API implementation is executed and the "after" event is triggered right after the default API implementation logic. An event handler can respond to either one of these events. A synchronous (blocking) event handler participates in the API invocation chain and can modify the objects in the chain's flow. For example, the "before" event handlers can modify arguments of the API calls, so the default logic gets the modified objects. Similarly, an "after" handler can modify the return value (or exception) so the client application which made the API request receives the modified value. The diagram below illustrates the flow:

backendless-incocation-chain

All built-in Backendless services emit the "before" and "after" events for every API call.

What is a Codeless Event Handler

A Codeless event handler is implemented using the Backendless Codeless system. There are no restrictions on the type of logic one could add into a Codeless event handler. Most common use-cases are:

Validating data before it is saved in the database. This applies to user registrations, creating new data objects or updating existing ones.
Enforcing a login policy.
Monitoring data object changes.
Injecting dynamic properties into objects before they are saved in the database.
Injecting dynamic properties into server responses.
Sending out push notifications based on a condition.
Integrating with a 3rd party service.

 

Consider the following example. It is an event handler for the "user registration" event. The logic runs every time a user registers with the application. It checks if the user's email address ends with "yahoo.com" and if so, returns an error. This is the example which is reviewed in the Quick Start Guide:

sample-before-register-handler

Quick Start Guide

By the time you complete this guide, you will have a codeless event handler which will process user registration API requests. The event handler will reject any user registration where user's email ends with @spammer.com:

1. Register and login to Backendless Console. Create/select an app.
2. Click the Business Logic icon and switch to the EVENT HANDLERS section.
event-handlers-screen-codeless.zoom70
 
3. Click the New Event Handler link/button and make the selections as shown in the image below:
new-event-handler-codeless
If you are not familiar with Backendless event handlers, the selections you made are:
 
Model: default - This is the deployment model, which may group multiple event handlers, timers and API services into one unit. In most of the cases you can use the default model.
 
Category: Users - This indicates that the event handler is created for an event from the Backendless Users service.
 
Event: register - The event handled by the event handler is "register", which is a short form of "user registration".
 
Timing: before -  The event handler will run before the default Backendless logic which registers application users.
 
Non-blocking: turned off - This means the event will be running in the "blocking" mode, which means any other logic in the API handling pipeline will wait for the event handler to be done.
 
4. Click SAVE to create the event handler. The event handler is created in the "Draft" mode, which means it is available for editing and is not deployed to the server for the runtime execution
event-handler-created-codeless.zoom70
 
5. Click the open logic designer link to open the event handler for logic editing. The logic designer opens the event handler with the placeholder block where you will be adding the logic throughout this guide:
event-handler-codeless-step1.zoom70
 
6. Now it is time to add logic to the event handler. The logic you will add will execute the following rule:
 
Reject any user registration where user's email ends with @spammer.com
 
To implement the rule, the logic will follow the algorithm below:
 
1. Obtain the email address of the user registering with the app.
2. Check if the email address ends with the '@spammer.com' text.
3. Return an error to the client application if the previous step is 'true', otherwise the API call must proceed.
 
The instructions below will walk you through each step of the algorithm.
 
7. Obtain the email address of the user registering with the app.
The user registering with the app is represented by the Request User block available in the Context Blocks area. Drag the request-user-block block into the Main Logic Canvas (do not try attaching the block to anything yet). If you are wondering why the Request User block is available in the Context Blocks, it is because the user object is an argument of the beforeRegister event (the one you are adding the logic for). Generally speaking, event handler arguments are always available in the Context Blocks area.
 
To obtain the email address from the user object, you will use the Get property block. The block is available in the Object category under the SYSTEM group. Click the Object category and drag the get-property-block block onto the main canvas. The block allows to obtain the value of a property for an object. The object in your logic will be Request User. Drag the request-user-block block which you already have on the Main Logic canvas into the opening in the Get property block so it looks as shown below:
get-property-user-object
 
The property you need to obtain is called "email". Type in email into the "string" part of the Get property block and press Return, so it looks as shown below:
get-property-email-user-object
This completes the current step of the algorithm.
 
8. Check if the email address ends with the '@spammer.com' text.
Codeless includes a special block that checks if a string ends with a specific text. The block is available in the Text category under SYSTEM. Click the Text category and drag the ends-with-block block onto the main canvas. Connect the Get property block from the previous step to the text input so when combined, it looked as shown below:
text-ends-with-email-from-user
The block has a drop-down list where you can select the "ends with" option. Make that selection and enter @spammer.com into the string block right after that:
complete-ends-with-block
This completes the current step of the algorithm.
 
9. Return an error to the client application if the previous step is 'true', otherwise the API call must proceed.
The final step of the algorithm is to add the condition logic. Since the step of the algorithm includes the "if" statement, it naturally maps to the if block located in the Logic category under SYSTEM. Click Logic and drag the if-do-block block onto the main logic canvas. Connect the block from the previous step to the input next to if:
if-with-email-check
 
The entire block structure at this point includes a complete if statement. It retrieves the email address from the user who is registering, and checks if the user's email address ends with the @spammer.com text. When the email address ends with the specified text, the if block executes the action in the do section. Our algorithm requires that in that case an error is thrown. All error-related blocks are available in the Exceptions category under SYSTEM. Click Exceptions and drag the throw-error-block block onto the Main Logic canvas. You can attach it to the connector in the if/do block:
if-do-without-error
Enter the text of the error message into the string block attached to the New Error block:
if-do-with-error
 
The final step is to place the entire structure into the API Event Handler placeholder block. Drag the if/do block, which will pull the rest of the structure and attach it to the event handler placeholder as shown below:
complete-logic-event-handler.zoom80
 
At this point the logic for the event handler is complete.
 
10. Click the DEPLOY button to deploy the logic to the servers. Once deployed, the console confirms with an information popup. The event handler can now respond to the user registration API events.
11. Click CLOSE to return to the event handlers listing. You can confirm that the event handler is now deployed to production:
deployed-codeless-event-handler.zoom80
 
12. To see the event handler in action you need to run the user registration API call. If you already gave a client application, try registering a user with the email address ending with @spammer.com. Otherwise, you can run the following cURL command from a command prompt window (make sure to put your application ID and REST API Key into the URL):

curl -X POST \
http://api.backendless.com/YOUR-APP-ID/YOUR-REST-API-KEY/users/register \
 -H 'content-type: application/json' \
 -d '{
 "email":"developer@spammer.com",
 "password":"superduper"
}'

 

The server sends the following response, which comes from the event handler:

{"code":0,"message":"Cannot register user. Email address is not allowed."}

Context Blocks

The Context Blocks area in Codeless Logic Designer includes blocks which provide access to the "contextual" information. There are two types of blocks which appear for event handlers:

1. General blocks - they are available for all event handlers
2. Handler specific blocks. Each"before" event handler gets its own set of blocks for the values received in the corresponding API event. The "after" blocks get access to both request values and the response values.

General Blocks

These blocks are present for all event handlers:
 

Application ID - id of the application in which context the event handler is invoked.
app-id-block
 
User ID - objectId of the currently logged in user whose identity is used to make the API call which triggered the event handler. A value for this parameter is not present if there is no logged in user (or if the user-token header is not passed for the REST invocations).
user-id-block

 

User Roles -  an array/list of the role names of the logged-in user (if any) who made the API call.
user-roles-block

 

User Token - value of the user-token header sent by the client application when making an API call.
user-token-block

 

Device Type - the type of the device (as a string value) which made the API invocation. Possible values are "IOS", "ANDROID", "JS", "REST", "BL" (business logic)
device-type-block

 

Request Headers - HTTP headers sent by the client application when invoking the API.
request-http-headers-block

Handler Specific Blocks

An event handler corresponds to an API operation. Every API operation receives specific arguments and returns a specific return value. As a result, every "before" event handler gets specific blocks representing operation's arguments and every "after" handler can access the return value via a dedicated block.

 

All "after" event handlers also get access to the arguments for the corresponding "before" event.

 

User Service Event Handlers

User Registration API

 

beforeRegister

argument blocks:

Request User - user object with all the properties for the user registration.

 

afterRegister

return value block:

Response User - user object representing registered user.


User Login API

 

beforeLogin

argument blocks:

Request Login - contains user identity property.

Request Password - contains user's password used for logging in.

 

afterLogin

return value block:

Response User - contains the User object if the login operation is successful.


User Update API

 

beforeUpdate

argument blocks:

Request User - user object with the updated properties.

 

afterUpdate

return value block:

Response User - updated user object.


User Deletion API

 

beforeRemove

argument blocks:

Request User ID - objectId of the user object to delete.

 

afterRemove

return value block:

Response Result - a timestamp when the object is deleted.


Get Users Table Schema API

 

beforeDescribe

argument blocks:

None

 

afterDescribe

return value block:

Response UserProperties - a collection of objects describing columns of the Users table. For the details on the response see the Retrieving Schema Definition section in the REST API documentation.


Restore Password API

 

beforeRestorePassword

argument blocks:

Request Email - email address of the user requesting password recovery.

 

afterRestorePassword

return value block:

None


User Logout API

 

beforeLogout

argument blocks:

None

 

afterLogout

return value block:

None


Update Multiple Users API

 

beforeUpdateBulk

argument blocks:

Request WhereClause - the whereClause statement defining the condition for the objects which must be updated.

Request Changes - an object containing property values which will be applied to all objects matching the provided whereClause.

 

afterUpdateBulk

return value block:

Response Result - number of updated objects.


Remove Multiple Users API

 

beforeRemoveBulk

argument blocks:

Request WhereClause - the whereClause statement defining the condition for the objects which must be deleted.

 

afterRemoveBulk

return value block:

Response Result - number of deleted objects.


User Confirms Email Address

 

beforeEmailConfirmed

argument blocks:

Request EmailConfirmKey - a key identifying the user account, is a part of the link the user clicks to confirm the email.

 

afterEmailConfirmed

return value block:

None


User Registers through a Social Network

 

beforeSocialRegister

argument blocks:

Request UserProperties - an object with the key/value pairs defining the user.

Request SocialType - a string value identifying the social network. Possible values are "TWITTER", "FACEBOOK", "GOOGLE_PLUS".

 

afterSocialRegister

return value block:

Response Result - registered user object


User Logs in through a Social Network

 

beforeSocialLogin

argument blocks:

Request UserProperties - an object with the key/value pairs identifying the user.

Request SocialType - a string value identifying the social network. Possible values are "TWITTER", "FACEBOOK", "GOOGLE_PLUS".

 

afterSocialLogin

return value block:

Response Result - logged in user object


 

Database Event Handlers

Save New Object API

 

beforeCreate

argument blocks:

Request Item - object to be saved in the Backendless database.

 

afterCreate

return value block:

Response Item - object saved in the Backendless database.


Update Existing Object API

 

beforeUpdate

argument blocks:

Request Item - an existing object to be updated in the Backendless database.

 

afterUpdate

return value block:

Response Item - object updated in the Backendless database.


Delete Object API

 

beforeRemove

argument blocks:

Request ItemId - objectId of the object to be deleted in the database.

 

afterRemove

return value block:

Response Result - a timestamp when the object was deleted.


Find Object by ID

 

beforeFindById

argument blocks:

Request ItemId - objectId of the object to retrieve from the database

Request ItemRelations - a collection of related properties to initialize and return along with the parent object.

 

afterFindById

return value block:

Response Item - object retrieved from the database.


Find Objects with a Query

 

beforeFind

argument blocks:

Request Query - a query object with the data retrieval properties (whereclause, sorting options, paging options, relations, relations depth)

 

afterFind

return value block:

Response Result - a collection of objects matching the request query.


Find First Object in the Table

 

beforeFirst

argument blocks:

None

 

afterFirst

return value block:

Response Result - the first object in the table


Find Last Object in the Table

 

beforeLast

argument blocks:

None

 

afterLast

return value block:

Response Result - the last object in the table


Get Schema for a Table

 

beforeDescribe

argument blocks:

Request ItemName - name of the table to get the schema definition of.

 

afterDescribe

return value block:

Response ItemProperties - a collection of objects describing table's columns. For the details on the response see the Retrieving Schema Definition section in the REST API documentation.


Load Object's Relations API

 

beforeLoadRelations

argument blocks:

Request Item Id - objectId of the parent object.

Request Entity Name - name of the table where the parent object is stored.

Request Item Relation - name of the relation to retrieve.

 

afterLoadRelations

return value block:

Response Result - a collection of child objects for the identified parent object and the named relation column.


Update Multiple Objects API

 

beforeUpdateBulk

argument blocks:

Request WhereClause - the whereClause statement defining the condition for the objects which must be updated.

Request Changes - an object containing property values which will be applied to all objects matching the provided whereClause.

 

afterUpdateBulk

return value block:

Response Result - number of updated objects.


Remove Multiple Objects API

 

beforeRemoveBulk

argument blocks:

Request WhereClause - the whereClause statement defining the condition for the objects which must be deleted.

 

afterRemoveBulk

return value block:

Response Result - number of deleted objects.


Get the Number of Objects in a Table API

 

beforeCount

argument blocks:

Request Query - the whereClause statement defining the condition for the objects to be counted. If the condition is not specified, the API will count all objects in the table.

 

afterCount

return value block:

Response Result - object count


Get the Object Count for a Table/Query API

 

beforeCount

argument blocks:

Request Query - the whereClause statement defining the condition for the objects to be counted. If the condition is not specified, the API will count all objects in the table.

 

afterCount

return value block:

Response Result - object count


Add Related Child Objects to a Parent API

 

beforeAddRelation

argument blocks:

Request ParentObjectId - objectId of the parent object in the relation.

Request Column Name - specification of the relation column name. Includes name of the 'child' data table, column name and cardinality in the following format columnName:childTableName:cardinality. The cardinality parameter is expressed as 1 for a one-to-one relation or n for a one-to-many relation.

Request Children Array OR Where Clause - either a collection of child object IDs or a whereClause identifying the objects in the child table which should be added to the relation.

 

afterAddRelation

return value block:

Response Result - number of objects added to the relation


Set Related Objects for a Parent API

 

beforeSetRelation

argument blocks:

Request ParentObjectId - objectId of the parent object in the relation.

Request Column Name - specification of the relation column name. Includes name of the 'child' data table, column name and cardinality in the following format columnName:childTableName:cardinality. The cardinality parameter is expressed as 1 for a one-to-one relation or n for a one-to-many relation.

Request Children Array OR Where Clause - either a collection of child object IDs or a whereClause identifying the objects in the child table which should be set in the relation.

 

afterSetRelation

return value block:

Response Result - number of objects set for the relation


Delete Child Objects from a Relation

 

beforeSetRelation

argument blocks:

Request ParentObjectId - objectId of the parent object in the relation.

Request Column Name - name of the related column.

Request Children Array OR Where Clause - either a collection of child object IDs or a whereClause identifying the objects in the child table which should be deleted from the relation.

 

afterSetRelation

return value block:

Response Result - number of objects deleted from the relation

Messaging Event Handlers

Send Email API

 

beforeSendEmail

argument blocks:

Request Subject - subject line of the email message.

Request BodyParts - a collection of the bodypart objects. For the details on the bodypart structure see the 'Request Body' section of the Send Email API documentation.

Request Recipients - a collection of email addresses where the email will be sent to.

Request Attachments - a collection of file paths (from the Backendless File Storage). The referenced files will be attached to the email message.

 

afterSendEmail

return value block:

Response Result - a MessageStatus object with the id assigned to the request.


Device Registration API (for Push Notifications)

 

beforeDeviceRegister

argument blocks:

Request DeviceRegistration - a device registration object containing device type, id and token. For the details on the object structure see the Request Body section of the Device Registration API.

 

afterDeviceRegister

return value block:

None


Subscribe for PubSub Messages API

 

beforeSubscribe

argument blocks:

Request Channel - name of the channel to subscribe to.

Request Options - subscription options object. For additional details see the Request Body section of the Message Subscription API documentation.

 

afterSubscribe

return value block:

Response SubscriptionId - an ID assigned to the subscription. Can be used to poll for messages or to cancel the subscription.


Publish a Message (used for Pub/Sub and/or Push Notification message delivery)

beforePublish

argument blocks:

Request Message - message object or a primitive value to publish.

Request Publish Options - a publish options object. For additional details see the Request Body section of the Message Publish API documentation.

Request Delivery Options - a delivery options object. For additional details see the Request

 

afterPublish

return value block:

Response PublishStatus - a MessageStatus object containing message ID and message publish status. The ID can be used to retrieve message status.


Poll for Messages (Pub/Sub)

beforePoll

argument blocks:

Request SubscriptionId - a subscriptionId identifying the subscription to get any pending pub/sub messages for.

 

afterPoll

return value block:

Response Messages - a collection of messages returned from the server.


Cancel Published Message

beforeCancel

argument blocks:

Request MessageId - ID of a message to cancel.

 

afterCancel

return value block:

Response MessageStatus - a message status object containing the status of the cancellation operation.

 

File Service Event Handlers

File Upload API

 

beforeUpload

argument blocks:

Request File Path - URL pointing to the location where the file will be stored.

 

afterUpload

return value block:

Response Result - URL of the location where the file is stored.


Create File from Byte Array

 

beforeUpload

argument blocks:

Request File Path - path to a directory where the file will be stored located

 

afterUpload

return value block:

Response Result - URL of the saved file.


Get Directory Listing API

 

beforeUpload

argument blocks:

Request File Path - path in the application's file storage to get a listing for.

Request File Pattern - a pattern which the returned files and directories must match.

Request File Recursive - a boolean value of true or false. If present and is true, requests that the listing must be retrieved recursively for all directories contained within Request File Path.

Request Page Size - if present, identifies how many items should be returned in the response.

Request Page Offset - if present, indicates the index of an item in the response from which to get the Request Page Size items.

 

afterUpload

return value block:

Response Result - A collection of files and directories matching the specified pattern. For more information, see the Return value section of the Directory Listing API documentation.


Get File/Directory Count

 

beforeCount

argument blocks:

Request File Path - path in the application's file storage to get a listing for.

Request File Pattern - a pattern which the returned files and directories must match.

Request File Recursive - a boolean value of true or false. If present and is true, requests that the listing must be retrieved recursively for all directories contained within Request File Path.

Request Page Size - if present, identifies how many items should be returned in the response.

Request Page Offset - if present, indicates the index of an item in the response from which to get the Request Page Size items.

 

afterCount

return value block:

Response Result - A collection of files and directories matching the specified pattern. For more information, see the Return value section of the Directory Listing API documentation.


Delete File or Directory

 

beforeDeleteFileOrDirectory

argument blocks:

Request File Path - path to a file or a directory to delete.

 

afterDeleteFileOrDirectory

return value block:

None.


Copy File or Directory

 

beforeCopyFileOrDirectory

argument blocks:

Request File Source Path - a path identifying a file or a directory to be copied. The path starts with the root directory of the application's file storage.

Request File Target Path - a path to a directory where the source file or directory should be copied to. If the directory does not exist, it will be created.

 

afterCopyFileOrDirectory

return value block:

Response Result - a path to the copied file or the directory.


Move File or Directory

 

beforeMoveFileOrDirectory

argument blocks:

Request File Source Path - a path identifying a file or a directory to be moved. The path starts with the root directory of the application's file storage.

Request File Target Path - a path to a directory where the source file or directory should be moved to. If the directory does not exist, it will be created.

 

afterMoveFileOrDirectory

return value block:

Response Result - a path to the moved file or the directory.


 

Backendless Timers

Backendless Timers contain server-side business logic which executes according to a schedule. A timer schedule is configured by the application developer/administrator and instructs Backendless to launch the timer's logic at the pre-defined time/day/date/week/month. A timer can use the Backendless API to work with the data/users/files in the Backendless storage, execute any kind of business logic and communicate with external services/resources.

What is a Codeless Timer

A codeless timer is implemented with the Backendless Codeless logic. A developer uses the Codeless Logic Designer to add logic to a Backendless timer. For example, the following codeless timer runs daily

reminder-timer-listing

 

the timer's logic retrieves reminder objects due today from the database (the ToDo table) and sends an email to those responsible for the item:

reminder-timer-codeless

Schedule

A timer must have a schedule describing how frequently it runs. The schedule is initially configured using Backendless Console when a timer is created and can also be edited later. Schedule configuration is available on the Run property in the New Timer and Edit Timer popup windows:

timer-schedule

 

Scheduling options

once - the timer will execute only once on the date/time specified in the Start property.
custom - the timer will run with the specified seconds-based frequency:
timer-custom-option
daily - the timer will run with the specified days-based frequency:
timer-daily-option
weekly - timer's execution frequency is based on weeks, the timer will run on the selected week days:
timer-weekly-option
monthly - the timer will run on the specified months and the selected dates:
timer-monthly-option
 
or alternatively, the specified months/weeks:
timer-monthly-options2

Function Library

The Backendless Codeless system promotes the concept of logic re-use through the Function Library. Any reusable logic can be implemented as functions. Each function has a name, a list of input parameters and an an optional return value. Once a function's is implemented, it is represented by a block in the Custom Functions category. The block can be used in any other Codeless logic in the application such as API services, API event handlers, timers or other functions.

Quick Start Guide

This guide will walk you through creating a reusable function which calculates a Fibonacci number for its sequential position. You will learn how to declare a function, add an input parameter, add Codeless logic and re-use the function.

 

1. Login to your Backendless application and click the Business Logic icon.
2. Click the CODELESS tab and click Add New under Functions in the BROWSER panel.
new-codeless-function.zoom70
3. When visiting the Function Library section for the first time, a new function placeholder is automatically created for you. In the function block, click the doSomething label, change it to fibonacci:
fib-function-name
4. The function will have one input, which identifies the position of the Fibonacci number to calculate. To add the input, click the gear icon in the upper left corner of the Function block. Drag the input name block into inputs, then change the name of the input from x to position as shown in the video below. Notice the declared input is automatically added to the Context Blocks area:

 
5. The function developed in this guide will return a value (the actual Fibonacci number), however, when you develop other functions which do not need to return a value, you can control it through the interface behind the "gear" icon:
control-return-codeless-function
6. The algorithm which will be implemented in the function assumes that the first two numbers in the sequence are 1 and 1. All other numbers are the sum of the previous two. Thus the logic of the algorithm is going to be:
 
If the position argument is less than or equals 1, then the function should return 1. Otherwise, the function should recursively get the result for position - 1 and add it to the result for position - 2.
 
7. Since the logic of the function will use recursion (the function will call itself), make sure to click SAVE so that the function shows up in the Custom Functions category:
fibonacci-in-custom-functions.zoom70
 
8. The final logic should look as shown below. Notice the function is re-used recursively:
fibonacci-impl
The video below demonstrates the process of composing the logic for the function:

 
9. When finished composing the logic, click the SAVE button. At this point the function implementation is complete. To see the function in action, you will create an API Service which uses the function. Click CLOSE and switch to the API Services screen.
10. Click the "+" icon to create a new service and select the CODELESS tab. Enter MathService for the Service Name field and click SAVE.
11. In the New Codeless Method popup enter calculateFib for the method name and N for the parameter 1 field. The type of the parameter must be Number. Click SAVE:
calculatefib-method
 
12. Click EDIT to edit the codeless logic for the calculateFib method:
edit-calculate-fib
13. In the Business Logic Designer drag the fibonacci block from the Custom Functions category and attach it to the return connector of the calculateFib method. Drag the Method Argument N block from Context Blocks and attach it to the position connector of the fibonacci block. Click DEPLOY to deploy the logic.

 
14. At this point the service method is ready. It uses the custom function and can be tested with real data. Click the CLOSE button in the Business Logic Designer. Click the PARAMETERS tab. Enter a value for the argument N and click INVOKE. Backendless Console invokes the service and displays the result. For example, the screenshot below shows that the Fibonacci number for the 10th position in the sequence is 89:
calculate-fib-result.zoom80
 
15. This concludes the guide. You have developed a custom reusable function and built an API service which uses the function.

 

Developing Functions

Development of re-usable codeless functions follows the same process as with other codeless programs such as API Services, API Event Handlers and Timers. Once a function is saved, even before it has any logic in it, it can be used elsewhere in the application. A codeless function consists of the following elements:

Function name
Arguments
Return value
Function block color
Function tooltip
Function help URL

 

All elements except for the function name are optional.

Creating New Function

To create a new codeless function:

1. Click the Business Logic icon and select the CODELESS tab.
2. In a new app, which has no codeless logic, the Add New link under Functions in the BROWSER panel.
new-codeless-function-menu.zoom70
 
3. Click the link to create a new function. The new function will have the doSomething name:
new-do-something-function.zoom61

Function name

To set or change the function name:

1. Click the text area next to the word "Function" and type in the new function name.
set-function-name.zoom70
 
2. Click the SAVE button to save the changes. Once the function is saved, it appears in the Custom Functions section of the toolbox and under Functions in the BROWSER panel:
saved-function.zoom68

 

Function name requirements:

Function name cannot start with a number
Must consist of only letters from the classical Latin alphabet (a-z and A-Z) and numbers (0-9)
Cannot contain spaces, non-printable characters and punctuation characters.
Cannot be a JavaScript reserved word, future reserved word or a JavaScript literal.

Arguments

Function arguments can be added, deleted or modified using a special popup available through the "gear" icon located left of the word "Function":

function-args-clickfunction-args-show

Adding New Arguments

To add an argument drag the block from the left side of the popup into the block on the right side until they snap to each other. For example, the image below shows a function with an argument:

argument-x-added

 

A block representing the function (used when the function will be called from other logic) will render a connector point for every argument. For example, for the function shown above, the function block will have the following appearance:

mycoolfunction-example

Modifying Arguments

To rename an argument:

1. Click the area showing "x" (or the modified argument name) in the block on the right side of the popup.
2. Enter the new argument name and press Enter.

 

When your function has two or more arguments, you can the argument order. All arguments are ordered vertically. The position of each block representing an argument, defines the argument's position. To change the order of the argument, drag a block representing the argument on the right side of the popup and place it into the desired position.

 

Deleting Arguments

To delete an argument, drag the block representing the argument from the right side of the popup to the left side.

Arguments in the Context Area

When an argument is added, a block representing argument value automatically becomes available in the Context Area. The argument blocks in the Context Area can be used within the function's logic in order to access the argument values passed into the function. The image below shows a function with two declared arguments: arg1 and arg2. Notice the blocks in the Context Area representing argument values.

function-with-two-args

Return Value

A function can return a value which is the result of a function call. When a function is initially created, it contains a connector for the returned value:

function-return-value

Some functions may not return any value. To remove the "return value" connector:

1. Click the "gear" icon next to the word "Function".
2. In the popup which appears, click the checkbox next to "with return".
3. The return value connector is removed:
removed-return-value

 
When a function is configured not to return a value, the block representing the function (on the side of the logic which calls the function) will have the following appearance (with the function name and arguments as configured):

dosomething-no-return

Using Codeless Functions

As soon as a function is saved, it automatically appears in the Custom Functions category of the Logic Designer's toolbox:

saved-custom-functions

 

To use a function drag the block representing it into the Main Logic Canvas area. Functions can be used in all types of Codeless logic: API Services, API Event Handlers, Timers and other custom codeless functions. A function can be used within its own logic to implement recursive behavior.