Some apps need to store and retrieve data. For example, consider the workflow of a project management app such as JIRA. When a user links a contact to an issue in JIRA, a relation between the contact ID and issue ID is stored, which when retrieved displays the details of the relevant JIRA issue along with the contact.
To enable the development of such apps, we provide a data store for apps to set (store) and get (retrieve) data. Also, data can be deleted when it is no longer required. The data store has the following limitations:
- The data is stored on a per account AND per app basis i.e the scope is on a per installation basis. This means that if two apps have been installed by an account, the data stored by one app is not accessible by the other app.
- A rate limit of 50 requests per minute applies with each set, get, and delete counting as one request. This rate limit is applied separately for each installed app which means that if two apps have been installed by an account, the rate limit will apply separately to each app. This limit is not affected by the number of users in the account.
Take a look at the Data Storage Freshdesk sample app for a demonstration of this feature. The same functionality is available in Freshsales.
Store
client.db.set(key, value, options) - Stores the key, value pair in the data store. UTF-8 characters are supported. If an entry with the key is already present, then the value will be updated. The options field is not mandatory and by default is an empty hash. Ensure that the following conditions are met while performing the set operation:
- The key should not be blank and its length should not exceed 30 characters.
- The combined size of the key and value should not exceed 8 KB.
- The value should be of type JSON and not blank or empty "{}".
- The following values in the JSON Object will be converted to null - empty strings, NaN, "+/- Infinity".
1 2 3 4 5 6 7 8 9 | client.db.set( "contact:101", { "jiraIssueId": 15213 }).then ( function(data) { // success operation // "data" value is { "Created" : true } }, function(error) { // failure operation console.log(error) }); |
Note: When testing, you may need to click the shield icon in your browser’s address bar and then click Load unsafe scripts. For more information, refer to the Test Your App section.
For Serverless Apps, you need to use the following format.
server.js Copied Copy1 2 3 4 5 6 7 8 9 | $db.set( "contact:101", { "jiraIssueId": 15213 }).then ( function(data) { // success operation // "data" value is { "Created" : true } }, function(error) { // failure operation console.log(error) }); |
Options: The following attributes can be specified in the options field.
- Time to live (ttl): Specifies the expiration period of the key in the data store in seconds. The ttl attribute supports both integer and float data types. If you do not set the ttl value or if the value is negative, the key will exist forever.
- Set If (setIf): The setIf attribute takes any one of the two values: exist or not_exist. The {setIf: "exist"} code stores the value if the key exists in the data store and throws an error if the key does not exist in the data store. Similarly, {setIf: "not_exist"} stores the value if the key does not exist in the data store and throws an error if it is an existing key.
app.js
Copied Copy1 2 3 4 5 6 7 8 9 10 | client.db.set( "contact:101", { "jiraIssueId": 15213 }, {ttl: 60}) .done(function(data) { // success operation // "data" value is { "Created" : true } }) .fail(function(error_data) { // failure operation console.log(error_data.status) console.log(error_data.message) }); |
This sample code sets the key to expire after 60 seconds.
app.js
Copied Copy1 2 3 4 5 6 7 8 9 10 | client.db.set( "contact:101", { "jiraIssueId": 15213 }, {setIf: "exist"}) .done(function(data) { // success operation // "data" value is { "Created" : true } }) .fail(function(error_data) { // failure operation console.log(error_data.status) console.log(error_data.message) }); |
Take a look at the Advanced Data Storage Freshdesk sample app for a demonstration of this feature.
Retrieve
client.db.get(key) - Is used to retrieve stored data. If the retrieval is successful, the JSON value can be accessed using the data parameter in the .then function.
app.js
Copied Copy1 2 3 4 5 6 7 8 9 | client.db.get("contact:101").then ( function(data) { // success operation // "data" value is { "jiraIssueId": 15213 } }, function(error) { console.log(error) // failure operation }); |
For Serverless Apps, you need to use the following format.
server.js Copied Copy1 2 3 4 5 6 7 8 9 | $db.get("contact:101").then ( function(data) { // success operation // "data" value is { "jiraIssueId": 15213 } }, function(error) { console.log(error) // failure operation }); |
Update
client.db.update(key, action, attributes) - Updates the corresponding key value in the data store. UTF-8 characters are supported. Ensure that the following conditions are met while performing the update operation:
- The key should not be blank and its length should not exceed 30 characters.
- The attributes object should be of type JSON and not blank or empty "{}".
- The following values in the JSON Object will be converted to null - empty strings, NaN, "+/- Infinity".
The action field can take any one of the following parameters listed below.
PARAMETER | DESCRIPTION |
---|---|
Increment | Adds a new value to the existing attribute value in the attributes object. |
Append | Appends a new value to the existing attribute value in the attributes object. |
Set | Adds one or more top-level or nested attributes and values to the key, value pair. |
Remove | Removes one or more attributes and values from the key, value pair. |
Note: For serverless apps, you need to use the following format: $db.update(key, action, attributes).
- Increment - client.db.update(key, "increment", attributes) - Adds the new value specified in the attributes object to the existing attribute value in the data store.
- If an attribute does not exist, the increment action adds the specified attribute and its value to the key in the data store.
- If the new value passed in the attributes object is a negative number, then it is subtracted from the existing value.
- If you execute the increment action on a key which does not exist in the data store, the attributes object is stored in the data store with the specified key. This is similar to the Store operation.
- Append - client.db.update(key, "append", attributes) - Appends the new value specified in the attributes object to the existing attribute value in the data store.
- If an attribute does not exist, the append action adds the specified attribute and its value to the key in the data store.
- If you execute the append action on a key which does not exist in the data store, the attributes object is stored in the data store with the specified key. This is similar to the Store operation.
- Set - client.db.update(key, "set", attributes) - Adds one or more attributes and values to the specified key, value pair in the data store. If the attributes exist, then they are replaced with the new values. You can use the set action to update both top-level and nested attributes.
- Remove - client.db.update(key, "remove", attributes) - Removes one or more attributes of the specified key, value pair in the data store. You can use the remove action to remove both top-level and nested attributes.
Note:
1. The attributes field takes an object containing the attribute name and value which you want to increment.
2. The increment action:
a. Supports only number data type.
b. Can be used on top-level attributes, not nested attributes.
Note:
1. The attributes field takes an object containing the attribute name and value which you want to append.
2. The append action:
a. Supports only array data type.
b. Can be used on top-level attributes, not nested attributes.
Note:
1. The attributes field takes a JSON object containing the path and value which you want to set.
2. The path should be of type string and should not be empty.
3. For a top-level attribute, the path refers to the name of the attribute in string format. For a nested attribute, the path refers to the attribute path from the top-level attribute in dot notation.
Note:
1. The attributes field takes an array containing paths of the attributes which you want to remove.
2. The path should be of type string and should not be empty.
3. For a top-level attribute, the path refers to the name of the attribute in string format. For a nested attribute, the path refers to the attribute path from the top-level attribute in dot notation.
Delete
client.db.delete(key) - Is used to delete stored data that is no longer needed.
Note:
When an app is uninstalled all the data stored by it will automatically be deleted and cannot be recovered.
app.js
Copied Copy1 2 3 4 5 6 7 8 9 | client.db.delete("contact:101").then ( function(data) { // success operation // "data" value is { "Deleted" : true } }, function(error) { console.log(error); // failure operation }); |
For Serverless Apps, you need to use the following format.
server.js Copied Copy1 2 3 4 5 6 7 8 9 10 | $db.delete("contact :101").then ( function(data) { // success operation // "data" value is { "Deleted" : true } }, function(error) { console.log(error) // failure operation }); |
Test
For information on how to test an app that uses the Data Storage feature, see Test your App.
Data that the app needs to store is saved in the .fdk/localstore file in the app's root directory.
Errors
In case of failure, a status code is displayed along with a message to troubleshoot the issue.
An example of a status code and message is given.
1 2 3 4 | { "status":400, "message":"Key length should not exceed 30 characters" } |
The following table lists the supported status codes.
STATUS | DESCRIPTION |
---|---|
400 | Is returned due to invalid input. For example, in the set request, if you provide an invalid input for value you may receive this status code. |
401 | Is returned if you performed an unauthorized request. |
404 | Is returned if the record is not found. |
422 | Is returned if the server does not recognize your request. This may occur due to incorrect syntax. |
429 | Is returned when the number of requests exceeds the threshold. |
500 | Is returned if the server encountered an unexpected condition which prevents it from fulfilling the request. |
502 | Is returned if the server cannot process the request due to request overload. |