Dart client for Altogic backend apps.
This package is for pure Dart. If you use it in the Flutter application, you can use the altogic package. The altogic package uses the
altogic_dart
package and includes some flutter-specific methods and improvements.
Altogic is a backend application development and execution platform, enabling people and businesses to design, deploy and manage scalable applications. It simplifies application development by eliminating repetitive tasks, providing pre-integrated and ready-to-use execution environments, and automating key stages in the application development process.
For detailed API documentation go to Client API reference
In order to use the Altogic client library you need to create an app and a client key in Altogic. Additionally, if you will be using the Authentication module of this library, you might need to do additional configuration in your app settings.
dart pub add altogic_dart
And import it
import 'package:altogic_dart/altogic_dart.dart';
Then you can use it from a global altogic
variable:
AltogicClient altogic = createClient('http://fqle-avzr.c1-na.altogic.com', 'client-key');
This guide will show you how to use the key modules of the client library to execute commands in your backend app. For more in-depth coverage, see the Client API reference.
- You can see the authentication basics with Quickstart Guide
- You can try all methods and see the code blocks in the Example/Test Application
- Also you can see the basics with the Example TO-DO Application
If email confirmation is enabled in your app authentication settings then a confirm sign up email will be sent to
the user with a link to click and this method will return the user data with a
null
session. Until the user clicks this link, the email address will not be verified and a session will not be
created. After user clicks on the link in confirmation email, Altogic verifies the verification token sent in the email
and if the email is verified successfully redirects the user to the redirect URL specified in app authentication
settings with an access_token
in query string parameter. You can use this access_token
token to get authentication
grants, namely the user data and a new session object by calling the getAuthGrant
method.
authFunctions() async {
//Sign up a new user with email and password
var errors = await altogic.auth.signUpWithEmail(email, password);
if (errors != null) {
// success
}
// After the users are created and their email verified, the next time the users wants to sign in to their account, you can use the sign in method to authenticate them
var userSession = await altogic.auth.signInWithEmail(email, password);
// You can check errors. If ``errors`` is null, signIn is success.
if (userSession.errors != null) {
// success
var user = userSession.user;
var session = userSession.session;
} else {
// Error
}
//... after email address verified, you can get user and session data using the accessToken
var authGrant = await altogic.auth.getAuthGrant(accessToken);
}
Note: Check altogic package for learning how to handle redirect urls.
If phone number confirmation is enabled in your app authentication settings then a confirmation code SMS will be
sent to the phone. Until the user validates this code by calling verifyPhone
, the phone number will not be verified.
authFunction() async {
//Sign up a new user with mobile phonec number and password
var errors = await altogic.auth.signUpWithPhone(phone, password);
if (errors != null) {
// success
}
//Verify the phone number using code sent in SMS and and return the auth grants (e.g., session)
UserSessionResult userSession = await altogic.auth.verifyPhone(phone, code);
//The next time, the users wants to sign in to their account, you can use the sign in method to authenticate them
UserSessionResult userSession = await altogic.auth.signInWithPhone(phone, password);
}
See altogic package for designed for Flutter.
To create a new object in one of your models in the database, you have two options. You can use the query manager shown below:
createObject() async {
//Insert a new top-level model object to the database using the query builder
var response = await altogic.db.model('userOrders').create({
productId: 'prd000234',
quantity: 12,
customerId: '61fbf6ceeeed063ab062ac05',
createdAt: '2022-02-09T10:55:34.562+00:00',
});
// Or you can use `createMany` to create multiple object(s).
if (response != null) {
//success
print(response.data); // created object
}
}
Or you can use an object manager:
createObject() async {
//Insert a new top-level model object to the database using the object manager
var response = await altogic.db.model('userOrders').object().create({
productId: 'prd000234',
quantity: 12,
customerId: '61fbf6ceeeed063ab062ac05',
createdAt: '2022-02-09T10:55:34.562+00:00',
});
if (response != null) {
//success
print(response.data); // created object
}
}
You can use two ways to update an object in the database. You can use an object manager shown below to update an object.
updateObject() async {
//Upates a users address identified by '61f958dc3692b8462a9d31a1' to a new one
var result = await altogic.db
.model('users.address')
.object('61f958dc3692b8462a9d31a1')
.update({
'city': 'Chicago',
'street': '1234 W Chestnut',
'zipcode': '60610',
'state': 'IL',
'country': 'US',
});
//Increments the likeCount of a wallpost identified by id '62064c7eff64b91975a599b4' by 1
var result = await altogic.db
.model('wallposts')
.object('62064c7eff64b91975a599b4')
.updateFields(FieldUpdate(field: 'likeCount', updateType: UpdateType.increment, value: 1));
}
Or you can use a query manager to perform update operation. Below examples perform exactly the same updates as the above methods.
updateObject() async {
//Updates the an object using a query builder
var result = await altogic.db
.model('users.address')
.filter('_id == "61f958dc3692b8462a9d31a1"')
.update({
'city': 'Chicago',
'street': '1234 W Chestnut',
'zipcode': '60610',
'state': 'IL',
'country': 'US',
});
//Increments the likeCount of a wallpost identified by id '62064c7eff64b91975a599b4' by 1 using the query builder
var result = await altogic.db
.model('wallposts')
.filter('_id == "61f958dc3692b8462a9d31a1"')
.updateFields(FieldUpdate(field: 'likeCount', updateType: UpdateType.increment, value: 1));
}
deleteObject() async {
//Delete an order identified by id '62064163ae99b3a645705667' from userOrders
var result = await altogic.db.model('userOrders').object('62064163ae99b3a645705667').delete();
//Alternatively you can use a query builder to delete an object
var result = await altogic.db
.model('userOrders')
.filter('_id == "62064163ae99b3a645705667"')
.delete();
}
query() async {
// Gets the first 100 orders with basket size greater than $50 and having more than 3 items and sorts them by descending orderDate
await altogic.db
.model('userOrders')
.filter('totalAmount > 50 && totalQuantity > 3')
.sort('orderDate', Direction.desc)
.limit(100)
.page(1)
.get();
}
In Altogic, you can define your app RESTful endpoints and associted services. You can think of services as your cloud functions and you define your app services in Altogic Designer. When the endpoint is called, the associated service ( i.e., cloud function) is executed. The client library endpoints module provide the methods to make POST, PUT, GET and DELETE requests to your app endpoints.
get() async {
//Make a GET request to /orders/{orderId} endpoint
//...
var orderId = '620949ee991edfba3ee644e7';
var result = await altogic.endpoint.get('/orders/$orderId').asMap();
}
Endpoint methods (get
,post
,put
,delete
) returns a FutureApiResponse
.
FutureApiResponse
has some methods like asMap()
, which type of return your endpoint the methods will cast to that type. E.g. asMap()
returns result as Future<APIResponse<Map<String,dynamic>>>
. So you can read data with var data = result.data
, the data
will be Map<String,dynamic>?
.
post() async {
//Make a POST request to /wallposts/{postId}/comments endpoint
//...
var postId = '62094b43f7205e7d78082504';
var result = await altogic.endpoint.post('/wallposts/$postId/comments', body: {
'userId': '620949ee991edfba3ee644e7',
'comment': 'Awesome product. Would be better if you could add tagging people in comments.',
}).asMap();
}
delete() async {
//Make a DELETE request to /wallposts/{postId}/comments/{commentId} endpoint
//...
var postId = '62094b4dfcc106baba52c8ec';
var commentId = '62094b66fc475bdd5a2bfa48';
var result = await altogic.endpoint.delete('/wallpost/$postId/comments/$commentId').asMap();
}
put() async {
//Make a PUT request to /users/{userId}/address
//...
var userId = '62094b734848b88ff50c2ab0';
var result = await altogic.endpoint
.put('/users/$userId/address', body: {
city: 'Chicago',
street: '121 W Chestnut',
zipcode: '60610',
state: 'IL',
country: 'US',
}).asMap();
}
This module allows you manage your app's cloud storage buckets and files. You store your files, documents, images etc. under buckets, which are the basic containers that hold your application data. You typically create a bucket and upload files/objects to this bucket.
createBucket() async {
//Creates a bucket names profile-images with default privacy setting of
//public, meaning that when you add a file to a bucket and if the file
//did not specify public/private setting, then it will be marked as
//publicly accessible through its URL
await altogic.storage.createBucket('profile-images', isPublic: true);
}
uploadFile() async {
//Uploads a file to the profiles-images bucket
var file = File('path/to/file');
var bytesToUpload = await file.readAsBytesSync();
var result = await altogic.storage
.bucket('profile-images')
.upload('file_name.ext', bytesToUpload);
//If you would like to have a progress indicator during file upload you can also provide a callback function
var result = await altogic.storage
.bucket('profile-images')
.upload(fileToUpload.name, fileToUpload, FileUploadOptions(
onProgress: (uploaded, total, percent) =>
print('progress: ${uploaded}/${total} ${percent}')
));
}
listFiles() async {
//Returns the list of files in bucket profile-images sorted by their size in ascending order
var result = await altogic.storage.bucket('profile-images').listFiles(options: FileListOptions(
returnCountInfo: true,
sort: FileSort(FileSortField.size, direction: Direction.asc),
));
//You can also apply filters and paginate over the files. Below call returns the first 100 of files which are marked as public and sorted by their size in ascending order.
var result = await altogic.storage.bucket('profile-images').listFiles(
expression: 'isPublic == true',
options: FileListOptions(
returnCountInfo: true,
limit: 100,
page: 1,
sort: FileSort(field: FileSortField.size, direction: Direction.asc),
));
}
You can use the Altogic client library to cache simple key-value pairs at a high-speed data storage layer (Redis) to speed up data set and get operations.
//Store items in cache
var result = await altogic.cache.set('lastUserOrder', {
productId: 'prd000234',
quantity: 12,
customerId: '61fbf6ceeeed063ab062ac05',
createdAt: '2022-02-09T10:55:34.562+00:00',
});
//Get the item stored in cache
const result = await altogic.cache.get('lastUserOrder');
The queue manager allows different parts of your application to communicate and perform activities asynchronously. A message queue provides a buffer that temporarily stores messages and dispatches them to their consuming service. With the client library you can submit messages to a message queue for asychronous processing. After the message is submitted, the routed service defined in your message queue configuration is invoked. This routed service processes the input message and performs necessary tasks defined in its service flow.
submitMessage() async {
//Submit a message to a queuer for asychronous processing
var result = await altogic.queue.submitMessage(queueName, messageBody);
var info = result.info;
//Get the status of submitted message whether it has been completed processing or not
var result = await altogic.queue.getMessageStatus(info.messageId);
}
The client library task manager allows you to manually trigger service executions of your scheduled tasks which actually ran periodically at fixed times, dates, or intervals.
Typically, a scheduled task runs according to its defined execution schedule. However, with Altogic's client library by
calling the runOnce
method, you can manually run scheduled tasks ahead of their actual execution schedule.
runOnce() async
{
//Manually run a task
var result = await altogic.queue.runOnce(taskName);
var info = result.info;
//Get the status of the manually triggered task whether it has been completed processing or not
var result = await altogic.queue.getTaskStatus(info.taskId);
}
You can use the following resources to learn more and get help
- ๐ Quick start
- ๐ Altogic Docs
- ๐ฌ Discord community
- ๐ฐ Discussion forums
Think youโve found a bug? Please, send us an email support@altogic.com or open issue on GitHub.
altogic_dart
package repository
altogic
package repository
For issues with, questions about, feedback for the client library, or want to see a new feature please, send us an email support@altogic.com or reach out to our community forums