pabulo_sdk 1.0.12
pabulo_sdk: ^1.0.12 copied to clipboard
Pábulo: The future of Loyalty, Merchants & Wallet Platforms, Today
Pabulo Platform Dart Library #
Pábulo: The future of Loyalty, Merchants & Wallet Platforms, Today.
Provides APIs for seamlessly connect to the Pabulo Platform and build rich Flutter UIs in no time.
Motivation #
✅ To provide ability to quickly build front-ends in the shortest possible time.
✅ Simplifying complex JSON data models into standard Request & Response objects.
✅ Providing efficiency to reduce network traffic by validating data before doing a server
round trip.
Get Started #
Future<void> main() async {
await AppConfig.initialize();
/// Initialize th Globals for the base framework.
/// This is a singleton so enable it in the main
/// for early initialization.
PabuloGlobals(
baseUrl: AppConfig().appConfig.baseUrl,
requestTimeOut: AppConfig().appConfig.defaults.getRequestTimeOut(),
language: AppConfig().appConfig.defaults.language,
apiKey: AppConfig().appConfig.apiKey,
); // You code after this.
}
Initialize the PabuloGlobals() with the parameters:
baseUrl: this is the path to the backend where the core platform is running , i.e.https://api.domain.comorhttps://api.domain.com:8080requestTimeOut: Optional The time as [Durations] to wait for backend to respond. If ignored the default is 30 seconds.language: Optional This is the language 'en-US' or 'fr-FR' to be used for communicating to the backand. If ignored the default is 'en-US'.apiKey: Optional This is the API Key that is assigned by the backend administrator to perform special operations that requires elevated security.
🫡 That is all !!! You are now wired up to start using the SDK.
Usage #
Once you have wired the SDK in the main() the next step is to use the repositories{^1} for the
business flow that you are working on.
Use case 1: you are building a Login Screen for users to login.
class LoginBloc extends Bloc<LoginEvent, LoginState> {
// Wire the SDK Repository for Administration Functions.
final RepoAdmin _repoAdmin = RepoAdmin();
// On Login Pressed call the api
Future<void> onLoginPressed() async {
try {
RspLogin? rspLogin = await _repoAdmin.letMeIn(
ReqLogin(consumerEmail: email, consumerPassword: password),);
} catch (error) {
// ... handle errors
}
// ... reset of your code.
}
}
Use case 2: you are building a list of items to show with a input field.
/// By extending the DTO objects from the SDK you can now add
/// input fields on top of the backend response.
class LoyaltySpendData extends LoyaltySpendDto {
late TextEditingController minimumSpendAmountController;
late TextEditingController minimumSpendPointsController;
late TextEditingController incrementSpendAmountController;
late TextEditingController incrementSpendPointsController;
LoyaltySpendData({
super.currency,
super.incrementSpendAmount,
super.incrementSpendPoints,
super.minimumSpendAmount,
super.minimumSpendPoints,
super.symbol,
}) {
minimumSpendAmountController = TextEditingController(
text: minimumSpendAmount?.toString() ?? "",
);
minimumSpendPointsController = TextEditingController(
text: minimumSpendPoints?.toString() ?? "",
);
incrementSpendAmountController = TextEditingController(
text: incrementSpendAmount?.toString() ?? "",
);
incrementSpendPointsController = TextEditingController(
text: incrementSpendPoints?.toString() ?? "",
);
}
}
Concepts & Conventions #
Naming conventions:
- Request Objects: Objects that are used as part of the
POST,PUT,PATCHoperations to send data to the backend begin with a prefixReqand these classes are under the pathsrc/models/request. - Response Objects: Objects that receive the data as part of the
response.bodybegin with a prefixRspand these classes are under the pathsrc/models/response. - Data Object: Data Transfer Objects (DTO) are objects that hold the actual data, they are part
of the
RequestandResponseobjects, these classes are suffixed withDtoand implementvalid()andcopyWith()functionality or additional helper functions to simplify the use of these objects, and these classes are under the pathsrc/models/factory. - Repositories: these are API functions that directly communicate with backend without you
needing to understand the security, uri end-point parameters etc., these classes are prefixed
with
Repoand are under the pathsrc/repositories. - Uri: Universal Resource Indicator are classes with
staticmethods that help you call the backend directly if there is a need to bypass the SKD repo operations, these classes begin with a prefixUriand follow by the Swagger grouping name. e.g.UriConsumerwill have all the end-points related to consumer interactions.{^2} Under theUriclasses there are two types ofstaticdefinitions:- uri => statics starting with prefix uri are end-points that do not have
RequestParamin the uri. - url => statics starting with prefix url are end-points that will need
additional
ReqestParamto call the backend.
- uri => statics starting with prefix uri are end-points that do not have
example of URI vs URL:
class UriConsumer {
static Uri urlIsEmailExists({required String email}) =>
Uri.parse('$_rootBaseUri/is-duplicate?consumerEmail=$email');
static final Uri uriReferFriend = Uri.parse('$_rootBaseUri/referral');
}
Concepts
The SDK is build keeping in mind the KISS principles with a standard Input=> Process=> Output paradigm.
- Show a screen to user to interact with.
- Collect the data in a
Request. - Call the respective repository function with the request.
- Receive a
Responseback from the server.
Request: are objects that define the business input, each request will be different as it will be closely tied with the business operation and the data that the backend is expecting.
e.g.: a request to create a new user (sign-up)
{
"consumerEmail": "string",
"loginPassword": "string",
"mobilePhone": "string",
"fullName": "string",
"age": 100,
"interests": [
"string"
],
"referralCode": "string"
}
the corresponding request object for this is: ReqConsumerSignUp, so the above request would just
be:
class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
// Wire the SDK Repository for Consumer Functions.
final RepoConsumer _repoConsumer = RepoConsumer();
// On Sign Up Pressed call the api
Future<ReqConsumerSignUp?> onSignUpPressed() async {
try {
RspConsumerSignUp? rspConsumerSignUp = await _repoConsumer.createUser(
ReqConsumerSignUp(consumerEmail: email,
loginPassword: password,
mobilePhone: mobilePhone,
fullName: fullName),);
} catch (error) {
// ... handle errors
}
// ... reset of your code.
}
}
^1 All repositories are Singleton's, that way they are safe to wire any number of times and
anywhere in your code.
^2 Ideally you will not need to use the Uri directly, you should use the Repo instead.
© Adhvent Consulting Ltd.