Table of Contents

Wizzdi Cloud User Guide

Welcome to the Wizzdi Cloud documentation.

Wizzdi Cloud simplifies application development by enabling users to deploy products anywhere without code dependencies.

  1. You Built It; You Own It: Wizzdi Cloud differsfimport from almost all no-code platforms because it doesn’t restrict users to its ecosystem. After creating an App with Wizzdi Cloud, you can deploy it elsewhere. You can take your code and work on it independently without returning to Wizzdi Cloud. Choose to modify or build upon your project outside of Wizzdi Cloud. You can do so easily. Especially with the Spring Boot runtime, your code will be free from Wizzdi-specific dependencies, ensuring standard coding practices are maintained. Once you choose to develop outside the Wizzdi Cloud while keeping the use of Wizzdi Cloud available, the system automatically integrates any external code, allowing you continuous access to Wizzdi Cloud’s advanced visual tools.
  2. Wizzdi Cloud provides a comprehensive, no-code backend development platform; front-end development is coming soon. Here’s what it offers:
    1. Quality Assurance: The backends created are top-notch, aligning with industry standards.
    2. Flexibility: Wizzdi Cloud is feature-rich yet flexible. Backend systems can optionally be refined and extended outside the system.
    3. Tailored Solutions: While the platform caters to a wide range of needs, specific requirements might arise based on an organization’s unique technical background. Wizzdi Cloud is designed to be a starting point, allowing for such external enhancements. However, accessing standard libraries and code is supported in the platform, including a code editor for users preferring to code some parts of the system.
    4. Risk-Free: Choosing Wizzdi Cloud carries no risk. It serves as a robust foundation, ensuring that users have the flexibility to expand and enhance their projects as required.
  3. AI integration: Wizzdi Cloud offers seamless integration with ChatGPT, allowing users to transition from problem descriptions to diagrams easily.
  4. Deployment: Users can transition from diagrams to deployment on the Wizzdi customer high availability cluster without coding. Or pull their code and deploy it elsewhere using the included Docker script.
  5. UI Builder: A UI builder tool will be available in H2 2024. Wizzdi Cloud User Interface builder is designed to create Flutter-based mobile and web applications.
  6. Hosting Options: The backend system can be hosted on-premises, in a user’s cloud, or the Wizzdi Cloud. It includes a one-line Docker boot option for easy Linux, Windows, and Mac deployment.
  7. Repository Integration: The platform integrates with popular repositories like GitHub, GitLab, and Bitbucket.
  8. Development Patterns: Wizzdi Cloud supports multiple development strategies: full no-code development, a combination of no-code with traditional development, or using the no-code system as an assistant tool in the development process, allowing Wizzdi Cloud to contribute to the code base like any developer.
  9. Reusability: Wizzdi Cloud is intended to facilitate reuse on a broad scale. This encompasses projects created by yourself and others using Wizzdi Cloud and the ability to access available artifacts from private or public repositories such as Maven Central. Maven Central houses over one million software artifacts.
  10. External Services: Wizzdi Cloud includes extensive support for accessing services such as Google, SendGrid, and others; additionally, importing the definitions for every available external service is supported.
  11. MarketPlaces: Wizzdi Cloud supports public and private marketplaces; when apps are published to a marketplace, eligible users can access the apps, import the app to any of their workspaces, and use some or all app elements in their apps.
  12. Runtimes and Multi-tenancy: Wizzdi Cloud has three run-times: Pure Spring Boot, FlexiCore Boot, and FlexiCore. FlexiCore Boot and FlexiCore are extensions of Spring and come with an integrated multi-tenancy system. This system allows role-based access control to both data and API endpoints. Both are open-source and can be found on FlexiCore.The multi-tenancy in FlexiCore allows authorized users to combine data from different tenants and supports hierarchical structures. However, the Pure Spring run-time doesn’t have this multi-tenancy feature. All FlexiCore-based run-times work with standard Spring Boot libraries and development patterns.
  13. Security In pure Spring runtime: Role-based access to API endpoints is also supported, and optionally so, users have access to data they have created only. App builders can define the roles and their access to the API endpoints.

Note On Hierarchical Multi-Tenancy: 

Hierarchical multi-tenancy refers to a structured, tree-like organization of tenants within a system. Unlike the traditional flat model, where all tenants are at the same level, the hierarchical approach allows for nested multi-tenancy. In the context of Wizzdi Cloud and its support for hierarchical multi-tenancy, tenant administrators can create additional tenants within their primary tenant. This nesting can occur to any depth, depending on the organization’s needs, application, and system policies. For instance, consider a large organization that operates globally. The top-level tenant could represent the global enterprise. Beneath that, regional tenants could be created for North America, Europe, Asia, etc. Within the Europe tenant, further sub-tenants could be established for individual countries like France, Germany, and the UK. And even within those country-level tenants, you could have more granular tenants representing different departments or offices.


Login/Register

When starting Wizzdi Cloud, you will see a similar screen; you may sign up using your email and password or your Google/GitHub accounts.

Wizzdi Cloud Sign-in Sign-up

 


My Apps

You can search for your apps in the ‘My Apps’ view. Apps are arranged in Workspaces, and you can invite other users to your workspace while controlling their permissions. The latest workspace used will be the default one when you log in.

previous quality (92)
quality (100)

The Walkthrough

When starting the system the first time, you will be offered a walkthrough of the system, where you will be guided in building a simple yet complete backend.  You can always start the walkthrough from the top right menu. When stopped, the current walkthrough can always be resumed unless discarded.

Opening screen with a Walkthrough prompt

App

In the context of Wizzdi Cloud, an “App” represents a holistic software solution, encompassing its back-end and front-end facets.

  1. Back-end Components:
    • These form the engine room of your app, managing the underlying logic, databases, and integrations.
    • Deployment Flexibility: With just a click, these components can be deployed either on Wizzdi Cloud’s infrastructure, your cloud setup, an on-premises server, or even directly on a laptop.
  2. Front-end Components:
    • This refers to the user interface – what the end-users interact with.
    • Deployment Options: For mobile applications, the front end can be rolled out on platforms like the Apple App Store or Google Play. Conversely, for web apps, the front end is deployed as static files residing on the back-end infrastructure.
    • The current version of Wizzdi Cloud doesn’t include the front-end tools; these are planned for Q3 2024.
  3. UI Development & Integration:
    • While Wizzdi Cloud’s UI builder is in the pipeline, users aren’t limited in their choice of interface design tools. You can craft the UI using your preferred software and subsequently integrate it with Wizzdi Cloud, which serves as a backend.
  4. API Exposures:
    • The deployed back-end doesn’t exist in isolation; it provides a REST API suite, allowing for flexible integrations and interactions with other software or systems.
    • For ease of understanding and testing these APIs, they are accessible via our integrated Swagger interface, offering a clear, interactive representation of the available endpoints.

In essence, Wizzdi Cloud offers a platform that encapsulates an app’s operational core (back-end) and user-facing layer (front-end), allowing developers and organizations a streamlined approach to app development and deployment.

 Domain-First Approach

A domain-first approach emphasizes the importance of understanding the data structure of the system you want to create. Here’s how it works:

  • Begin with the Basics: Using Wizzdi Cloud’s intuitive diagramming tools, you’ll begin by outlining your domain model. This means identifying the core entities or ‘Things‘ that your system will interact with.
  • Intuitive for Domain Experts: The appeal of this approach is its accessibility to domain experts — those who understand the requirements of an application from a functional perspective rather than a technical one. Take, for instance, a school principal: She would intuitively know that managing a school involves entities like Class, Classroom, Teacher, Student, Subject, etc.  See: Wizzdi Cloud for Domain Experts
  • Seamless Backend Generation: Once you’ve established the entities and their interrelationships, Wizzdi Cloud takes over. A functional backend gets generated automatically, with all necessary APIs to manage these entities. This can be visually grasped when running the Walkthrough.

 Contract-First Approach

The contract-first method flips the script by focusing on user interaction first. Here’s the breakdown:

  • UI as the Starting Point: Instead of diving deep into the domain model, this approach starts with the user interface design. This design process inherently outlines the services that the backend needs to provide.
  • Service Definition through OpenAPI: Post UI design, the next step usually defines the services. This often culminates in creating an OpenAPI document, a contract for what services the backend should offer.
  • Direct Integration with Wizzdi Cloud: Wizzdi Cloud can directly import and recognize the OpenAPI document. Upon importing, a set of exposed APIs materializes in the system. Subsequent steps involve fleshing out these APIs — linking them to specific business logic, integrating with other systems, drawing up custom queries, and aligning them with the eventual domain model.

Whether you’re a domain expert wanting to shape a system around core entities or a designer aiming to sculpt backend services based on user interfaces, Wizzdi Cloud accommodates both avenues, providing a robust platform for achieving your visions.

Creating an App

Click on the + new APP button and fill in the required fields for the app.

The New App button.

Once clicked, the Create New App dialog is presented; enter a name for the app.

The advanced section is discussed later in this document.

The App creation may take a while (20-30 seconds); thanks for being patient.

Overview

App Overview.

App Details

The App details are displayed at the top left corner of the APP Overview.

At the top right, you can see the current version you are working on and the APP runtime; Wizzdi Cloud supports three different runtimes. See below in this document.

Maven Coordinates

Each App has a unique designation comprising two values and the version. These are called Maven Coordinates:

  • the GroupId and the Artifact Id. The group Id is usually in the form yyy.xxxxxx.
    where the [yyy] is one of com, org, tv, etc. This is similar to the suffix of a URL.
    The [xxxxx] is usually the name of the company or organization owning the App.
  • The Artifact Id uniquely designates the App within the group.

Package Name

Regardless of whether you ever look at the code, Wizzdi Cloud generates code. This is done under the hood; most users need not be concerned.
The code for the backend App is structured in packages, where the package name across all parts of the App typically begins with a predetermined prefix.
The convention is similar to the Group ID.

Color

The color for the App in several locations in Wizzdi Cloud.

Icon

This is the App’s icon, randomly assigned by Wizzdi Cloud. Follow the steps below to select a different icon.

Static UI

The current version of Wizzdi Cloud does not have a UI builder for the client-facing side of the application. However, once the initial version of the server is available, you can develop a front-end web application using any available tools and upload it here. Once the back-end application is deployed, the front-end application will be served to users.

Editing the App Details

Click on edit details to edit most of the above items.

Editable items

App Name.

App Description.

Group Id.

Package Name.

Artifact Id.

App Color.

App Icon.

static files.

Deployment Status

This is a collapsible panel providing information on the deployed app.

It is possible to access the Commit operation from this area.

Deployment Panel when the app has never been deployed.

When an App is committed successfully, it becomes ready for deployment.

Deployment panel: when the app is deployed, uninstall becomes available.

Click on the small arrow (marked by a yellow rectangle) to open the panel.

Deployment Panel when the App has never been deployed.

If the App was deployed at least once and has not been uninstalled, the deployment panel has more information:

Deployment Panel is when the app has been deployed at least once.

App Url

When deployed on the Wizzdi Customer Cluster, this is the URL of the static files, in case these were uploaded.

Swagger Url

This URL should always be available and provide the standard Swagger interface for accessing the exposed API of the deployed server.

App Version

The currently deployed version. For information only.

Docker Image

The currently created docker image that was deployed on the Kubernetes cluster. For information only.

Chart Version

A chart is a collection of files describing a set of Kubernetes resources.
The displayed version designates the version used for deployment. For information only.

The App Building Process

This panel provides access to some of the editors related to the back-end app-building process. This list is for first-time users who need help understanding the next step. You can access the Walkthrough from the top-right menu to see the order of using the editors.

Create your domain model

If you’re not using the contract-first approach, preparing your domain model is the first and mandatory step. Once your domain model is ready, you can commit and deploy your app. After deployment, the back end will include the API endpoints that manage the entities within the domain model.

 

Add business logic

In most cases, the API endpoints resulting from the domain model will not be sufficient to meet all the project requirements. Therefore, you may need to add additional business flows to enhance the functionality of your application.

Business logic diagrams can help you add extra logic triggered by various events such as data creation or updates, scheduling, webhooks, other business logic events, or messages arriving through Kafka, Websocket, and MQTT.

Add Consumed API

We utilize the Consumed API module to access external services like SendGrid or Google. You have two options for the creation of the full API: either use the OpenAPI import support or define the external API endpoint one by one by following the documentation provided by the external service. This step is only required if you need to access these external services.

The Business Flow diagram tools currently offer several predefined External API endpoints. If a service is unavailable in the already imported APIs, you can always import or create it yourself.

Setup your GIT repositories

This step is mandatory before deploying the created app or accessing the code on a repository. You must grant Wizzdi Cloud access to a remote repository available on Github or a similar service.

Marketplaces

Additional panels.

You can publish a committed App in your marketplaces to share your work with others. Unlike workspaces where several people can work and access the same App, publishing to a marketplace saves a frozen version of the App. This allows others to clone the App, modify it, or access its functionality from their apps. You can find more information about marketplaces in the marketplaces section.

Data visualization

This section contains statistics about the current application.

Click the small arrow to the right of ‘Data Visualization’, and a similar view to the image below should appear:

Data Visualization when hovering over the Entities slice.

Hover over a pie slice to view statistics on the element type it represents.

Statistics

Provides some statistics on the created code. It should be noted that Wizzdi Cloud generates code before an App can be deployed. Some users will enhance the code; others will never see it as they prefer a full, no-code workflow.

Code Generated example.

 

Domain Model

The domain model is a conceptual framework that outlines the different entities, their attributes, relationships, and constraints that govern the problem domain of a specific application or system. It acts as a blueprint for comprehending, documenting, and communicating the structure and semantics of the application domain space.

Critical aspects of a domain model include:

  1. Entities  These are the primary elements within the domain. For example, in a banking application, entities might include Account, Customer, Transaction, etc.
  2. Fields: Characteristics or properties of entities. For example, a Customer entity might have fields like name, address, and phone number.
  3. Relationships are connections between entities that indicate how they interact or are related to each other. For instance, a Customer may have one or more Orders.
  4. Inheritance Associations: This refers to the relationship between two entities, where a child entity inherits fields from a parent entity.

Creating a domain model is often one of the initial steps in the design phase of software development. It helps stakeholders understand the system and provides a foundation for the development of the system’s architecture and functionality. This approach is especially prevalent in methodologies like Domain-Driven Design (DDD), which focuses on developing a rich understanding and model of the domain as a core to the software development process.

Application Domain Experts can create the domain model using the tools provided by Wizzdi Cloud as long as the concepts of entities, fields, and relationships are understood. It is easy to apply changes to the existing and deployed App, reflecting changing requirements or a more profound and better understanding of the application domain.

The domain model in Wizzdi Cloud is managed through one or more Entity Diagrams. This arrangement depicts the app’s data architecture and the relationships between different data entities.

Upon finalizing the domain model, the app is ready for deployment. This process exposes a CRUD  API, which facilitates the management of the entities defined in the domain model. Any adjustments made to the domain model automatically result in updates to the API endpoints, reflecting the changes without manual intervention. This early version of the APP includes the required API endpoints to manage the created entities.

Users will likely introduce additional APIs, services, and functionalities using Wizzdi Cloud’s built-in tools or incorporate custom code using their preferred development tools. Regardless of the method chosen, updates to the domain model and the corresponding APIs are seamlessly integrated into the app. Wizzdi Cloud maintains continuous synchronization with the developers’ modifications, ensuring the app remains consistent with the evolving domain model.

  • Entity Diagrams: You can create multiple entity diagrams within the domain model section. These visual representations help you understand and design your system’s core data architecture.
  • Creation and Import Options: Entities can be manually created or imported from various sources, such as other projects. Entities can be referenced from other workspace projects or marketplaces you can access.
  • Extensibility and Inheritance: An entity isn’t restricted to a standalone structure. It can extend or inherit from other entities, cascading down properties and features from its parent or super-entities. This inheritance mechanism allows for a layered and hierarchical design, minimizing redundancy. Support for mapped Superclasses is provided.
  • Relationships: Entities can be interconnected in various ways, reflecting their real-world relationships. Wizzdi Cloud supports diverse relation types:
    • One-to-Many: A single instance of one entity relates to multiple instances of another.
    • Many-to-One: Multiple instances of one entity associated with a single instance of another.
    • Many-to-Many: Instances of one entity can relate to multiple instances of another and vice-versa.
  • Backend Representation: Entities typically translate to tables within a database in traditional backend structures for those who want a peek behind the curtain. The relational database used in Wizzdi Cloud is PostgreSQL.
  • Relational Database Integration: When deployed, Wizzdi Cloud is engineered to leverage the power of relational databases. So, in essence, each entity you design likely corresponds to a table in this database, establishing the groundwork for your backend’s architecture.
A typical Entity Diagram View

 

Overview

Start the domain model editor by clicking on Domain Model in the app’s side menu.

The Domain Model Editor
  1. This is the diagram’s name; you can use #10 to edit the name. The small [x] lets you remove the diagram from the view; the diagram is NOT deleted and is still available when adding a new diagram.
  2. Add a new diagram; if diagrams have been removed, they appear for selection.
  3. Zoom out. You can also zoom out using the mouse wheel.
  4. Restore the view to 100% zoom.
  5. Zoom in. It’s worth noting that you can also zoom in using the mouse wheel.
  6. Undo
  7. Redo
  8. Auto-arrange the current diagram.
  9. Make the view larger; the left-side menu is made invisible.
  10. Rename the diagram.
  11. Add a description to the diagram.
  12. Add a new Entity.
  13. Import an Entity or an Enum; Import items from the current or referenced projects into the current diagram.

Entities

Create an entity using right-click

The new entity selection from the right-click menu

The New Entity has a name field. Entity names must start with a Capital letter. The right-side menu provides a Description field for the currently selected entity.

New Entity dialog

Once an entity is created, the following tools and actions are available. The same action is often available from multiple places.

Options available on the created Entity
  1. Warning indicator: hover over the icon for more information about the warning.
  2. Additional actions menu.
  3. The entity can be renamed by double-clicking on the name; editing is then available. Renaming an entity is also available from the right-side menu.
  4. New field button. Add a new field to the entity.
  5. Connect to other entities, which will be discussed later in this guide.

This menu is available from the three dots button on the entity.

Entity three dots menu.
  1. Add a new field. This option is available from the bottom of the entity thumbnail and the right-side menu.
  2. Entities can have indexes added to improve data retrieval speed. Refer below for additional information.
  3. When creating an entity relationship involving entities from multiple diagrams, copying and moving entities to another diagram is necessary. This operation concerns only the arrangement of entities on diagrams.
  4. Move to another diagram, similar to the previous section, but the entity is removed.
  5. Change the color of the entity in the top bar. It helps in better organizing the diagram.
  6. Remove from diagram; Remove the entity from the diagram. The entity is not deleted.
  7. Delete the entity. The entity is deleted and removed from all diagrams.

Inheritance

Wizzdi Cloud supports inheritance, a cornerstone of Object-Oriented Programming (OOP). In data modeling and entity structures, inheritance allows one entity to inherit attributes or characteristics from another, establishing a hierarchical relationship between them.

For example, if there’s a base entity named ‘Vehicle‘ with attributes like speed and weight, a derived entity such as ‘Car‘ can inherit these attributes and might introduce new ones specific to it, like trunk size. By supporting inheritance in Wizzdi Cloud, users can create data models that depict these structured, hierarchical relationships, ensuring a more organized and intuitive representation of data. Furthermore, Wizzdi Cloud adeptly manages the underlying complexity of handling inheritance at the database level, abstracting these intricacies from the user and providing a seamless experience.
Furthermore, it’s important to note that inheritance is crucial in reusing domain models you or other users created on the Wizzdi cloud or available from the Wizzdi or other marketplaces. Through inheritance, you can modify and improve upon the original design of these models.

 

Inheritance example: Vehicles Cars, and Motorcycles

To create an inheritance link between an entity and its Super Entity, select the entity, drag the small circle on top of the Entity shape, and release it above the name of the Super Entity.

An entity can have only a single Super Entity.  A single Super-Entity can have multiple ‘children‘ entities.

Click on the three dots menu to detach an entity from its Super Entity. When an entity extends a super entity, all fields from the super entity are automatically inherited and visible within the extending entity. This inheritance can cascade through multiple levels or layers of hierarchy. It’s important to note that once fields are inherited, they become unchangeable on the child entity. To modify these fields, one must navigate to the original super entity where they are defined, even if this means moving up several levels in the inheritance chain.

The parent entity in the inheritance hierarchy can be a Mapped Super Class. 

A Mapped Superclass is a model from which other entities can inherit properties and mappings but is not itself an entity. It does not have its database table; instead, it allows its subclasses to inherit its properties, ensuring that these properties are mapped to the columns of the subclasses’ tables. This approach helps define standard fields (like id, name, description, createdAt, and updatedAt) across multiple entities without duplicating the mapping information in each entity class. This option should be preferred if you never need to manage the mapped superclass directly. For example, suppose the Mapped Super Class Base is defined to hold standard fields across multiple entities such as name, description, createdAt, and updatedAt. In that case, there is no need to manage the Base entity directly, as this entity is created only to save extra typing and make the refactoring of standard fields easier.

When a Superclass is not a Mapped Superclass, it and all its subclasses share the same table, with a discriminator column to differentiate between them.

Remove/Edit Inheritance

When entities are related through inheritance, lines connect the super-entity with its children. These lines can be hidden to simplify the diagram.

Double layer inheritance

A child entity shows its super-entity to the right side of its name; in the example above, Base extends Country, and SuperBase extends Base. When the inheritance line is clicked, a menu pops up. The inheritance can be deleted or hidden.

All inheritance lines up to the top become invisible when hidden, yet super-entity names remain visible on the entity top bar.

Click the name of the super-entity on the right side of a ‘Child’ entity name to display a menu for showing the inheritance line up to the next level by Show or show all the inheritance lines through the top by Show All.

Super-Entity names on Children entities.
Context menu by clicking on super-entity name

 

External Entities

to import an external entity from a dependency (see project dependencies) by using either the import external button on the right side or by using the context menu on a visible space of the diagram,

Import an entity or enum
Import from the diagram context menu.

 

Use Internal to import Entities from the current App.

Use External to import from dependent apps.  These are Apps added to the Dependencies section.

Enums

When creating a domain model, we sometimes prefer predefined values over entities. For instance, for Gender, we might list:

  • Female
  • Male
  • Undisclosed

Enums should be utilized in scenarios where the set of possible values is determined at the time of the application’s development, and there’s no anticipation of modifying these values post-deployment. Altering an enum necessitates updates to the application or its underlying code, reflecting a more static or immutable approach to handling certain data types.

Conversely, a dedicated table or entity structure provides a dynamic framework for managing possible values. This approach allows authorized users to add, remove, or modify the values as required without requiring direct App changes. It offers flexibility and adaptability.

Enum names must start with a Capital letter.

New Enum Dialog

You can add Enums using the button on the screen’s right side area.

Adding Entity Or Enum from the right side

 

 

Type a capitalized name, click the green checkmark, or hit the “enter” key.

To add values to an Enum, select it and click “add value”. You can continue adding values by hitting the “enter” key after each one.
Enum values can begin with either a capital or non-capital letter.

To rearrange Enum values, drag and drop to a new position.

Importing Enums

 

Use Internal to import Enums from the current App.

Use External to import from dependent apps.  These are Apps added to the Dependencies section.

Fields

To add a field, select the entity and click the ‘+New field’ button.

Type the new field name in the text box. Then, hit the ‘Enter’ key if you want to add another field, hit the ESC key to cancel, or click on the green check mark button to finish.

By default, fields are of the String type; this is a text field, limited in size unless the Lob option is used; see fields’ purpose below.

Click on the field type to change the type.  Start typing to search for the required type.

Click on the type to change it.

 

Search for the type and select it.

The field type can be changed from the right-side menu once the field is selected.

Search for type on the side menu.

Click on the three dots (…) to access a more powerful tool for searching for a type.

Filter results by type name using the search box above, or use the drop-down to search by type’s grouping or origin.

The grouping includes Basic Types, Entities, Enums, and Types defined elsewhere in the current App or any library or App it references.

Note: other entities can be searched for when searching for a type. When another entity is selected for a field type, a reference to this entity is created. Below, you can see other ways to associate entities by reference.

Note: When adding multiple fields using the ‘enter’ key after each field, the type selected for any field becomes the default for subsequent fields until the type changes. When stopping multiple field entries using the ‘Esc’ key, The default type becomes String again.

Purpose

Select a field to highlight it, then select the Purpose drop-down on the right-side menu.

Field purpose selection.

 

Normal Field

Most Fields have no particular purpose. There is no need to set a purpose in such a case.

Id

This is similar to a unique identification number for an entity’s instance. Every entity should have this field, which can be inherited from a Super Entity. See below.

In Wizzdi Cloud, an id is a String or a long. You can designate any field as an id field, but only one can be designated as such. You can select the purpose of the field as an id from the menu on the right side or use the “id” special purpose name to automatically set it as an ID.

Password

The password is stored in an encrypted format within the password field, ensuring it remains secure and inaccessible. This encryption applies when any entity, such as a User entity, is retrieved by a front-end client, and the password field is included in the retrieval. Consequently, the encrypted password cannot be deciphered or used to infer the original password. Furthermore, even if the application operates outside the Wizzdi cloud environment and the database is directly accessed, the encryption safeguards the passwords against any attempts to deduce them.

The type of a Password field must be a String.

LOB

A LOB (Large Object) field is designed to store substantial amounts of text, significantly surpassing the capacity of standard text fields, which typically cap at a few hundred characters. This makes LOB fields ideal for accommodating large documents, extensive descriptions, or any other form of data that requires more space than what is offered by conventional text fields. The LOB purpose applies to String-type fields only.

Creation Date

The system automatically records the creation date for any newly created instance when a field is designated as the OffSetDateTime type and its purpose is configured as a Creation Date. 

Update Date

The system automatically records the last update date for any instance when a field is designated as the OffSetDateTime type, and its purpose is configured as an Update Date.

Note: You must ensure the purpose aligns with the field type, as this isn’t done automatically.

Field Ordering

Dragging a field to a new position

To rearrange the fields of an entity, click on the field and drag it up or down to the desired position.

Entity Relationships

In Wizzdi Cloud’s architecture, entities can be linked using different association types, resulting in diverse relationships and data mappings. Specifically, the available association types are:

One-to-Many

A one-to-many relationship between entities occurs when a single record in one entity (often referred to as the “parent”) can be associated with multiple records in another entity (referred to as the “children”). This type of relationship is commonly used to model scenarios where an entity needs to be linked to multiple instances of another entity. For example, in a database modeling a library system, a single Author entity might have a one-to-many relationship with a Book entity, indicating that one author can write multiple books. This relationship is typically implemented in databases by adding a field in the child entity that stores the reference to the parent entity’s identifier, establishing a clear link between each child and its parent.

Many-to-One

A many-to-one relationship between entities is the inverse of a one-to-many relationship, where multiple records in one entity (the “children”) are associated with a single record in another entity (the “parent”). This type of relationship is commonly utilized to represent scenarios where several instances of one entity are linked to a single instance of another entity. For example, in a company’s departmental structure database, multiple Employee entities (children) could have a many-to-one relationship with a Department entity (parent), meaning that many employees belong to one department. This relationship is typically facilitated by including a field in the child entity (Employee) that references the parent entity (Department), thus establishing a connection from many children to one parent.

Many-to-Many

A many-to-many relationship between entities occurs when multiple records in one entity can be associated with multiple records in another entity. This relationship type represents complex scenarios without a simple one-to-many correspondence between entities. For example, in a university system, a Student entity might have a many-to-many relationship with a Course entity, indicating that each student can enroll in multiple courses, and each Course may include multiple students. A connection entity is typically used to implement this relationship in a system. This entity contains references to the two entities it connects, effectively linking multiple records from both entities and enabling the many-to-many association.

Examples

In the diagram below, we have two entities, City and State.

Although a City may reside in only one State, multiple Cities can belong to the same State. This creates a ‘Many-to-One’ relationship from the City perspective, meaning many Cities belong to the same State. However, from the viewpoint of the State entity, it’s ‘One-to-Many’ — one State is linked to many Cities. When defining such relationships, it’s important to establish the association from the ‘many’ side. Therefore, it’s necessary to include a ‘state‘ field within the City entity. Here’s how we can achieve this:

One-to-Many

Click on the one-sided entity, which in this example is the Country. We start with the one-side, but as you will see, the many-side holds the definition.

The state entity. The id field is selected.

 

Drag the small circle onto the name of the other entity, in this case, the State entity. Release it when the pointer is over the other entity’s name.

Drag and release from the id field.

A field named country has been added to the State entity to indicate ownership of the connection. A list of State instances has also been added to the Country entity.

Two Entities relationship

When a one-to-one relationship is needed, create a many-to-one relationship instead.

 

Alternatively, it is possible to create the relationship using the Arrow button.

The entity-relationship tool

Click on the 90-degree bent arrow to open an entity search dialog. This should be done on the many-to-one side entity.

Search for the one-to-many side entity.

Search for the one-to-many side entity, and click on the selected entity in the above image, the Student entity.

A relationship is created between TeacherToStudent and Student entities.

In the many-to-one entity, a new student field is created. in the one-to-many side entity, a List of StudentTeacherToStudents is created.

This field facilitates more flexible joins when using the Custom Query tool. When this entity is retrieved, the list is never populated. The opposite approach is considered inefficient.

 

Many-To-Many

Consider the following entity diagram.

A simplified teacher and student diagram

This diagram illustrates three entities: Student, Teacher, and Subject. A Many-to-Many relationship is formed when a single teacher instructs multiple students, and a student may receive guidance from multiple teachers. In Wizzdi Cloud, you can establish a many-to-many relationship between entities by dragging the id field circle of one entity onto the id field of the other. Drag the small circle of the id field of the first entity (Teacher) and release it over the id field of the other entity (Student) when it becomes selected.

Start dragging from the first entity id field.

 

release when the second entity id field is selected.

A new connection entity is generated.

A new Connection Entity is automatically created.

A connection entity is automatically generated when you create a many-to-many relationship between two entities. However, if you prefer, you can create this entity manually and link it to both associated entities as the ‘One’ side. It’s important to note that this connection entity is a primary participant in the schema, not a secondary one. For instance, the absence of a field serving the ‘id’ purpose is indicated by a yellow flag above it.

A common way to improve the information about a connection is by adding extra fields describing the nature or features of the relationship. For example, when arranging a class, it would be helpful to include fields that indicate the day of the week, start time, and end time of the class. So, let’s add these fields to enhance the information about the class. We have already added an entity called subject, which can be dragged (from the id circle) onto the connection entity head to include the Subject in the connection.

Connections among multiple entities

Remove/Edit Relationship

When hovering over a relationship line, the line becomes emphasized. Click on the line to get a menu for deleting or hiding the line.

The relationship line menu.

If you delete a relationship line, the fields linked on either end of the line will also be deleted.

Hiding lines can improve view clarity by reducing overlaps.

To show a hidden relationship line, access the field on the many-to-one entity and use the available menu to make the relationship visible.

Select Show to make a hidden line visible.

 

Indexes

Indexes can significantly enhance query performance in a database by facilitating faster search operations. While it’s common practice to define indexes on frequently queried fields to optimize performance explicitly, it’s not required to manually index fields that are used to associate the Many-Side entity with another entity. The underlying database engine automatically indexes these fields.

Setting an Index on an Entity

Indexes are attributes of an Entity, and multiple indexes can be added. They can enforce uniqueness and may also be composite. Composite indexes are beneficial for data requiring multi-level sorting.

To set an index, select an entity and click ‘manage indexes’:

Manage indexes

When creating an index, you can designate it as unique. A field indexed as unique will ensure that no two entity instances have the same value in the field associated with the index. Adding a duplicate value to such a field at runtime will result in a runtime error.

 

Add entity fields to the index.

To create a composite index, you can add multiple fields. Adjust the sequence of these fields by dragging them, as the order can be crucial for querying and sorting operations.

Consider this example involving a composite index:

In an e-commerce application, purchases are tracked in a database, each with fields such as ‘date‘ and ‘totalCost.’

If you want to retrieve all purchases between Date A and Date B and within a cost range of X to Y, a composite index encompassing both ‘date‘ and ‘totalCost‘ can enhance the query’s performance. If questions frequently specify a specific date with a range of costs, then ‘date‘ should be the first field in the index, followed by ‘totalCost.’

Also, if the primary requirement is to sort the results by ‘date’ and then by ‘totalCost,’ then the ‘date’ field should precede the ‘totalCost’ field in the index.

Additionally, if there’s often a need to query just based on the ‘date‘ without specifying ‘totalCost,’ having ‘date’ as the first field in the composite index would also be beneficial, as databases can effectively use the “prefix” of the index for such queries.

 

Diagrams

Wizzdi Cloud supports multiple diagrams for large domain models.

Click “+” in the bottom left corner to add a new diagram.

 

Diagram Name Context Menu (right click)

Access the context menu by right-clicking on the diagram name to rename or delete a diagram.

The context menu is active for the currently selected diagram only.

Rename an Entity Diagram

Rename a diagram

Deleting an Entity Diagram

You can permanently delete the selected diagram from the context menu. This action is irreversible and cannot be undone.

Entities and Enums created in the diagram persist and can be imported into a new diagram.

Closing an Entity Diagram

You can close a diagram from #2 here.

When a diagram is closed, it can be reopened from the Add Diagram button.

Add a closed diagram.

When a diagram becomes too large, you can create a new one and transfer or duplicate some entity shapes onto the new diagram. However, note that only the entity’s delegate on the diagram will be copied, not the entity itself. This makes it easy to divide large diagrams into smaller ones.

To connect entities on separate diagrams, you must first move or copy one of the entities to the diagram where the other entity is located. After the entities are connected, you may remove one of the entity shapes from one of the diagrams to simplify it.

Moving, removing, and copying entity shapes can be done from the three-dot menu on the entity shape.

 

 


Consumed APIs

Consumed APIs refer to the specific definitions of external services offered by vendors such as Google, SendGrid, and WhatsApp. These APIs enable the integration and access of their services directly from your applications. Additionally, consumed APIs facilitate the interconnection of various applications on the Wizzdi cloud, utilizing the principles of Service-Oriented Architecture (SOA).

Consumed APIs can be used to:

  • Broaden Functional Scope: By integrating with external services, your app can extend its capabilities without building every feature from scratch.
  • Streamline Processes: Utilizing pre-existing and well-established services like SendGrid ensures that specific processes, such as email delivery, are handled efficiently.

Consumed APIs can be defined in two ways:

  • OpenAPI Import: Most service providers provide definitions of OpenAPI (previously known as Swagger). These documents present a structured explanation of each of the API’s endpoints, responses, request formats, and other essential details. Wizzdi Cloud streamlines the import process of these files, automating the setup of the used API endpoints. This helps save time and guarantees that your backend conforms to the recommended standards and constructions of the external service.
  • Manual Definition: If an OpenAPI file is unavailable, Wizzdi Cloud allows you to set up and define the consumed API endpoints manually. This must be done to match the documentation of the said API accurately.

The Consumed APIs section in Wizzdi Cloud serves as a bridge, connecting your backend to the broader ecosystem of web services. Whether you plug in manually or import an OpenAPI specification, this integration ensures your application remains versatile, dynamic, and capable of leveraging the best of what the digital world offers.

 

Import Open API

Select Consumed Apis from the left side menu.

Select the MANAGE option; two options are presented; use the pointer to see and select an option.

This menu offers two options: manually adding an endpoint or importing an OpenAPI file. However, the former should be avoided if the latter is available.

This is the top option; select it, and you should see this dialog.

Importing an API from a provided URL

  • If an OpenAPI JSON file URL is available, paste it into the top text box and click ‘Save Changes.’ For instance, we will use the URL from OpenAPI’s GitHub account:

https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/link-example.json

Importing an API From a File

Sometimes, if a URL is not provided, you can directly upload the API definition JSON/YAML file into the system. An example file is available here.

 

After a short while, you should see the following screen

Each API, whether imported or manually built, appears as one line.

Click on Manage to view the imported endpoints, including their type, input objects, and parameters. You should see a screen like the one :

API endpoints are specific URLs that software clients (web apps, mobile apps, other systems) use to request specific actions or data. Think of them like particular addresses within a city (the API) where each address offers a different service or information, accessed usually using methods like “GET” (retrieve data) or “POST” (submit data).

Click on EndPoints To Access the API endpoints.

 

You should see a screen similar to this one: 

Refraining from modifying imported APIs is crucial, as it represents a binding agreement between the provider and any system using their services.

 

Manual API definition

Click the ‘ADD API +’ button to manually add an API.

The new API dialog appears.

Update the following mandatory fields:

  • Name: The name should start with a capital letter.
  • Package Name Suffix: This should be the suffix used for the package of this API and can be any valid part of a Java package name, such as the API name.
  • Base Path: The API owner must provide the base path, which cannot be modified arbitrarily. For instance, the base path for Apps in the Wizzdi Customers’ cluster is:
  • https://[app-name].[user].[workspace-name].cluster.wizzdi.com/ 
  • Description: Describes the API. This field is mandatory and cannot be left blank.
  • Theme Color: Select a color for the API icon. This field cannot be left empty.

Endpoints

Select the endpoints menu option and then click on Add Endpoint:

 

Once you click on +ADD ENDPOINT, a dialog similar to this appears:

Fields description

Endpoint: this is the unique definition of the ‘address’ of the endpoint, for example,/api/ActiveOnCall/createActiveOnCall 
When defining an external service’s endpoints, the definition must match the external service behavior.

Name: This is the name assigned to the endpoint method. It must start with a non-capital letter and conform to Java method naming conventions.

Method: Select one of the available options matching the required method as documented in the external (consumed) API. See here.

Description: This is for internal documentation of the endpoint.

Tags: Endpoints within an API can be categorized using multiple labels known as tags. Generally, a tag represents a collection of APIs with a common theme or function. An endpoint may be associated with several tags, facilitating better organization and more straightforward navigation of related API functions. When adding a tag to an endpoint, you can use an existing tag or add a new one. Tags are case-insensitive.

When the App runs, regardless of location, the Swagger interface can access the API; below is a sample screen capture of the Swagger interface of a set of endpoints under a single tag, WeeklyTime.

 

Endpoint Management

An endpoint is displayed under all of the associated tags in a similar way to Swagger:

 

 

Use the pencil icon to edit the fields above or click on the arrow down to define other properties of the endpoint.

 

Once the arrow-down is clicked, a dialog like this is opened:

This dialog manually defines the endpoint to match the consumed API details fully.

We have selected to edit the login endpoint. Our imaginary external service (the consumed API) uses basic authentication, and the username and password need to be defined in a Request rather than in the endpoint headers. Consequently, our method type should be POST.

POST method requires a Request  (sometimes called a Body).

Defining a Request object

Select the ‘select’ menu for the Request object:

define a request object

When clicking on Select, the following options are available:

Select Existing: This option allows you to reuse objects you have already defined elsewhere in the app or dependent apps. In the current version of Wizzdi Cloud, when such an object is referenced. One should not change it.

When Select Existing is selected, a dialog like this one appears. Use the Search text box to find the object you need.

Create Custom: Use the tools described below to build a new object.

Define the Class name for the new Object; it should start with a capital letter.

 

 Click on the newly created Object to view it.

Expand to view the current object structure.

Optionally, Click the pencil to edit the Object properties, the name, and the description.

Click on the plus icon to add a property to the Request Object.

 

Click the [+] button to add a new property.

The Create Property Dialog

 

The property name should be a noncapital word.

The Description is for documentation purposes.

To search for a Type, you can start typing its name in the Type field and select it from the list that appears. Alternatively, click the Type field to open a new Type creation dialog. You can also click on the three dots button to open a more detailed type search dialog.

 

Import JSON: You can paste a JSON object to create a new object. This useful option lets you define the JSON structure without using the Create Custom option. Additionally, it can be easier for some users to type out the JSON structure directly.

 

We will first use Import JSON  to define the Person Object (as an example).

 

 

  • When the Import JSON dialog is displayed, fill in the required data here.

 

  •  Now, we have the Request object defined as a Person. 

There are limitations when importing JSON; only basic data types such as strings, floats, boolean, integer, and long can be used.

Importing JSON Schema is not supported.

Building a Complex Object 

Click on Select at the right of the request object, then Select the Create Custom option.

Building a custom object.

The following dialog allows a selection of an existing Object or the creation of a new one.

Click on the Type text box to access the ‘Create Custom Object’ button. Click on it to show the ‘Create Custom Object’ dialog.

Define a name for the object. The name should start with a capital letter.

Save the new custom object
Save the Request Object using the created Family Create

Once the object is defined, we may populate it while editing the request object.

To modify the Object name and description, click the pencil icon on the right.

To expand the Request Object for editing, click on the left-side arrow marked in yellow.

Click on the [+] to create a new property.

Create Property

Property names should start with a lowercase character.

Property Type

There are three options here:

  • Start typing and select an existing type.
  • Click on the Type field to open the Type/Object creation dialog.
Click on the Type field to allow selection or creation.

When Create Custom Object is selected, type the new Object’s name, starting with a Capital letter. Then click on ‘Save Custom Object’.

Create a new Object.

Once a new Property Type has been defined, you can start defining new properties (fields) inside the newly defined Type/Object.

The new Object has no fields initially. Use the [+] button to add properties to the new Object, including nested objects and Lists/Maps.

 

 

Lists and Maps

Lists and Maps are often required when implementing consumed or exposed API endpoints. They can be nested: a List of Lists or Maps containing Lists. Nesting is supported to any required depth.

Note:
Type safety is a core principle in Wizzdi Cloud, ensuring that data structures, including Lists and Maps, enforce consistency of element types

Lists

If the endpoint you’re using requires an array of properties, follow these steps:

  • Click on the  icon.
  • Select the button.
  • In the Create Property menu, choose List as the type. Start typing List and select the option below.
Selecting the List type
  • Once the List is selected, the following dialog appears:
Select the inner type of a list
  • Click on the Type field (marked in yellow) to perform one of the following options:
    1. Start typing the name for the inner type.
    2. Click on the three dots button to open an expanded dialog for searching for a type.
    3. Select Create Custom Object to create a new Object.
  • For option 3, see the subsequent steps:
    • Create a new Object (Custom Type)
Create a new Custom Type (Object) for the List.
  • Once the inner Custom Type (Object) is created, the List inner type changes:

 

The List inner type changed to <FamilyMember>

Maps

A map is a data structure constructed from a list of entries containing a key and a value. The key is used to retrieve the value efficiently.

Key and Value can be Objects, including Lists or Maps. Contained Maps or Lists are similarly defined.

Note: Although rare, there are instances where such a data structure is used in API endpoints.

To create a property of a Map type, proceed as follows:

  • Start typing map in the Create Property dialog and select the Map type from the list below.
Create a property of Map type.
  • The map is shown with the generic designation of <K, V>, where K stands for key and V stands for value.

  • Select the data type by typing, using the three dots menu, or creating a new type by clicking in the type text box. You can also use List or Map as nested types.
A String as a Key and a List of AppUser as a value.
  • In the above image, the final type of the Map is displayed in 1.
  • The type of the Key is displayed in 2.
  • The type of the Value is displayed in 3.
  • The value’s inner type (a List) is displayed in 4.

When selecting the Type as a List or a Map, a text box for the List type and two text boxes for a Map will open.

In the image above, 2 and 3 were opened when Map was selected. Then, when the map value’s type was changed to List, 4 was opened to define the list’s type.

Authentication

When defining consumed API, we must define how API access is authenticated. We have two options:

  • Basic Authentication: This method requires sending a username and password with each API request. The credentials are encoded and passed in the HTTP request’s header. It’s simple but less secure and is often used for less complex or internal systems.
  • Token-Based Authentication: This method uses a token for access instead of credentials. Users authenticate once to receive a token, which is then used for subsequent requests. It’s more secure and scalable, suitable for modern web and mobile applications.

Note: when dealing with consumed (external) API, the authentication definitions should match the external API (consumed) definitions.

Authentication Setup for consumed API

Basic Authentication 

This is the default setup. There is nothing to set. Add authentication parameters following the external/consumed API documentation when defining each secured endpoint. These parameters are automatically defined if an OpenAPI document is available for import.

Token Based Authentication

In token-based authentication, the login endpoint (sign-in) retrieves a token. It is defined as any other endpoint (see login example above) and returns a token. The path and parameters of this endpoint are usually documented in the external service documentation.

The retrieved token is usually automatically sent with any subsequent endpoint call. The consumed API interface provides a way to define this behavior following the consumed API definitions.

To set the common location where the token will be sent in every subsequent call to the API’s endpoints:

In the above dialog, every endpoint call is amended under the hood, with the token obtained in the login endpoint using a header parameter named authenticationKey.

Integrating Applications in Wizzdi Cloud using Consumed APIs.

Leveraging Service-Oriented Architecture for Enhanced System Interconnectivity

Overview:

Service-Oriented Architecture (SOA) emphasizes building easily reusable and interchangeable software components. With the rise of microservices and distributed architectures, SOA’s principles have gained significant traction. In this context, Wizzdi Cloud offers a unique advantage by allowing one app to interact with another seamlessly.

1. Consumed APIs in an SOA Ecosystem:

  • OpenAPI for Inter-App Communication: Consumed APIs are not restricted to external services like Gmail or SendGrid. When working within the Wizzdi Cloud ecosystem, one app can directly import the OpenAPI of another Wizzdi Cloud app. This paves the way for fluid data exchange and service usage between different apps, fostering a cohesive network of interconnected applications.
  • Standardization with OpenAPI: By leveraging the OpenAPI specification, Wizzdi Cloud ensures that the communication between apps adheres to a recognized and consistent format. This standardization reduces integration overhead and potential discrepancies, allowing for a smoother interoperability experience.
  • Multiple Options for Reusability:
    1. Adding Dependencies:
      • ***************************
    2. Integration without SOA:
      • Wizzdi Cloud allows users to add dependencies to their apps. This means that users can incorporate additional functionalities or components into their applications. These components can be self-developed or sourced from the Wizzdi or other Market Places.
      • When components are added this way, the original backend of the app is merged with the backend of the external elements. This creates a unified, singular backend system.
      • As a result of this merging, the database created is a collective of entities (or pieces of data) from all the incorporated components. This implies a more integrated data structure.
      • These components’ services (or functionalities) communicate internally in this approach. There isn’t a need for external calls or connections; everything is managed within the unified system.
    3. Integration with SOA:
      • SOA, or Service-Oriented Architecture, is a design principle where services (functionalities) are made available to other parts of an organization through APIs (Application Programming Interfaces).
      • In the context of Wizzdi Cloud, when using an SOA approach, each service or component becomes a separate instance in the Wizzdi Customer’s Cluster. This means each service operates independently and is like its own mini-application. You have the option to deploy the apps either on-premise or on a different cloud service.
      • The integration or communication between these services happens purely through their respective APIs. Instead of having a single, merged backend, each service communicates externally with other services.

    Summary:

    • Without SOA: Consider blending ingredients to make a single smoothie. You can’t distinguish the individual components; they are fully integrated. This is how Wizzdi Cloud allows apps and their dependencies to merge.
    • With SOA: Imagine a tray of different cups with a distinct beverage. You must sip from each cup separately if you want a taste of two or more. They remain distinct; it’s an external process if you want them to interact. This represents the separate instances communicating through APIs in Wizzdi’s SOA approach.

    These two approaches would depend on the project’s specific needs and design preferences. Some may prefer the seamless integration of the non-SOA method, while others might find the modular and independent nature of the SOA approach more suitable.

2. Benefits of SOA Integration in Wizzdi Cloud:

  • Reusable Components: Embracing SOA principles means you can design an app component once and then deploy and utilize it across multiple applications. This not only reduces redundant effort but also ensures consistency across projects.***********
  • Scalability & Flexibility: As your system grows, you can easily add or modify new services without disrupting the entire application ecosystem.
  • Optimized Maintenance & Upgrades: With distinct apps handling specific services, updating or patching one service doesn’t necessitate taking down the entire system. This modular approach streamlines maintenance tasks and minimizes downtime.

3. OpenAPI Publishing in Wizzdi Cloud:

Every app built on Wizzdi Cloud automatically publishes its exposed APIs via an OpenAPI document. This self-documenting feature means that any other app, within or outside the Wizzdi Cloud environment, can access and understand the functionalities. It acts as an open invitation, encouraging other systems to leverage the services provided by the app.

In summary, Wizzdi Cloud’s support for SOA principles and its inherent capabilities around Consumed APIs position it as a robust platform for creating intricate, interconnected software ecosystems. Whether you’re aiming for a vast web of interlinked applications or want two apps to share resources, Wizzdi Cloud provides the tools and frameworks to make it happen effortlessly.


Exposed API

Overview

Exposed API is the collection of the REST endpoints the created backend exposes. These endpoints are usually consumed(used) by client-facing apps on mobile, web, or desktop.

Other backends can also consume exposed Apis. When integrating with other systems, services offered by the backend you build can be utilized by other systems; these systems can be built with Wizzdi Cloud or any other framework or programming language.

Wizzdi Cloud automatically generates API endpoints based on the entities you define within your domain model. This feature simplifies the backend development process, ensuring that every entity you create is instantly accessible and manageable. Additionally, Wizzdi Cloud offers flexibility in adding or importing API endpoints for advanced use cases or specific requirements.

Note: The automatic generation of API endpoints from entities can be turned off.

1. Default API Generation:

  • Entity-Based Automation: As soon as you create entities in the domain model editor, Wizzdi Cloud takes the initiative to generate corresponding API endpoints. These entities’ basic CRUD (Create, Read, Update, Delete) operations are instantly set up without further intervention.
  • Immediate Usability: With automatically generated APIs, your backend is instantly operational. As you evolve your domain model, the system adapts immediately, updating the available API endpoints as necessary.

2. Advanced API Management:

  • Manual Endpoint Addition: There might be scenarios where you require custom API endpoints for specialized operations or to cater to unique functionalities. Wizzdi Cloud’s interface allows for the intuitive addition of individual API endpoints, granting you full control over the specifics.
  • OpenAPI Document Import: To streamline the process further and accommodate extensive API structures, Wizzdi Cloud supports importing OpenAPI documents. This feature is especially beneficial when migrating or integrating extensive systems, as it bypasses the need for manual entry. Upon importing, all the endpoints defined in the OpenAPI document are readily available within Wizzdi Cloud.

Wizzdi Cloud’s approach to managing exposed API endpoints balances automation and customization. Whether building from scratch or integrating existing systems, the platform offers tools to ensure your backend is robust, responsive, and ready for deployment.

Description

Controlling automated API generation

By Default, Wizzdi Cloud generates CRUD API endpoints.  To change this behavior, select Exposed API from the menu.

Select Settings 

Then, switch off the Auto Generation option.

Importing an Open API API specifications

Wizzdi Cloud supports the import of Open API definitions from a URL or a file. In both cases, the definitions can be JSON-based or YAML-based.

Importing Open API specifications is the first step in the Contract First approach. Alternatively, the API endpoints can be manually defined.

Select manage at the bottom right corner of the Exposed Api section, then select the top option.

Import Open API definitions.
Import Open API definitions from URL into the Exposed API.

Below is an example of an OpenAPI URL from another demo App deployed in Wizzdi Cloud Customer’s cluster, where Apps may run.

In such cases, the URL is https://[appname].[workspace].cluster.wizzdi.com/api/v3/api-docs
for example, https://publish16.avishay-s-workspace.cluster.wizzdi.com/api/v3/api-docs.

Paste the URL in the upper text box of the import OpenAPI dialog.

Here is the link

Hit the Save Changes button. After a while, you should see the endpoints in the exposed API view.

To import from a file, click Upload File and browse for a valid OpenAPI file on the local system.

Import can be executed as many times as required. Note that the import of an existing endpoint will not change its signature.
Changing the EndPoint properties can be carried out by the built-in editor provided in Wizzdi Cloud.

One needs to scroll to see all imported endpoints.

Note: We can see the endpoints if we deploy the application now. However, the endpoints are not currently linked to any actual actions. Linking the endpoints to ‘real’ actions requires the following steps:

  •  Infer the required domain model from the endpoint definitions.
  • Create the domain model entities, enums and relation ship.
  • For each endpoint, you must create either a Custom Query, Flow, or both.
  • The imported API defines the request and response objects required in the Custom Queries and Flows.

Managing Exposed EndPoints.

Once the API is imported, endpoints are visible under the corresponding tags in the OpenAPI document.

Endpoints after the import

To enable an endpoint in a web application or API to perform specific actions, it must be integrated with either a Flow or a CustomQuery. A Flow refers to a predefined sequence of operations or tasks the endpoint will trigger and execute. These operations could include data processing, database interaction, calling other services, or another flow. On the other hand, CustomQuery is a user-defined operation, often tailored for complex or specific data retrieval. It usually involves using the Wizzdi Cloud custom query visual tool. By linking an endpoint to a Flow or a CustomQuery, you define the exact functionality that the endpoint will offer, essentially ‘programming’ it to respond to client requests meaningfully.

collapsed endpoint

To edit an endpoint, click on the small open triangle to the right of its available tools:

An empty endpoint (POST method) below:

Expanded, empty endpoint
Adding Request object

In a POST method, the Request Object is essential. It contains a JSON body from the client, which the server uses to retrieve,  create, or update resources.

In the example below, we will build a request object for creating a Family on the server.

Click on the small arrow to the right to expand the view.

Let’s create a FamilyCreate request object:

  • Select the ‘Create Custom’ option ******   from the ‘+Select’ option to the right of the Request icon

 

  • Create a new object called FamilyCreate. 

 

 

  •  Open the new object members editing by clicking on the two small arrows, first #1, then # 2
  • Proceed by clicking on the ‘+’ sign to add a member.
  • Select Object here ->
  • In  the Object Creation dialog, Select the name -> Person
  • The default name for the created Person object is person; let’s use the ‘pencil’ icon to change it to Parent1 as below:
  • Let’s expand person1 using the small arrow to the left of its name and click on the ‘+’ sign to add two properties. A name and a birth date.

Note: Adding these properties to the parent1  field in the request object changes the object Person. Other uses of the Person object are immediately affected.

  • Let’s add a new parent2 field. At this time, the Person object is defined, and we will create a Property of the type Person.
  • Click on the ‘+’ sign at the highest level of the Request object and select Property. 

Note: Please be cautious when selecting which ‘+’ sign you click on. In the image above, the upper ‘+’ adds fields to parent1, whereas the lower ‘+’ adds fields to the request object.

  • Add the name parent2, then in the Type field, start typing Perso… The previously defined Type becomes available, select it.
  • Click on ‘Create Property’ to dismiss the dialog.
  • Once both parents are added, you should see:
  • Let’s add a List of children to the FamilyCreate object:
  • We have added a familyName to the request object. The final object is below:

Custom Queries

Advanced data Queries in Wizzdi Cloud


Overview:

Wizzdi Cloud strives to simplify the backend development process by automating foundational aspects, like creating repositories and generating code for CRUD operations on entities. However, real-world applications often demand more granular control and nuanced data interactions. Recognizing this need, Wizzdi Cloud offers advanced tools such as the custom query builder.

1. Automated Entity Management:

  • Instant Repository & Service Generation: As you sculpt entities within Wizzdi Cloud, the system recognizes these entities and instantaneously crafts the requisite data repositories and accompanying services to facilitate basic CRUD operations.
  • Smart Data Retrieval: Wizzdi Cloud is designed with an innate understanding of entity relationships. For instance, when querying for an entity related to another entity, the system automatically fetches relevant connected data. This feature ensures that data remains contextually rich and relevant. Using the authors and books example, when books are queried, their corresponding author is nested within the retrieved data, providing comprehensive insights without additional requests. This happens only when you retrieve the ‘many’ side of the relation, in this case, the Book. When an Author is retrieved, no book list is populated.

2. Custom Query Builder:

  • Beyond Basic CRUD: While automated CRUD operations suffice for many scenarios, there are times when the default isn’t enough. Whether it’s complex filtering, advanced aggregations, or specific data transformations, there are myriad cases where a more hands-on approach to data access is warranted.
  • Intuitive Interface: The custom query builder is designed with user-friendliness in mind. It provides a visual platform to define specific data retrieval conditions, ensuring you get the exact slice of data you need in your desired format.
  • Integrated Code & Repository Creation: As with entity creation, Wizzdi Cloud takes over the heavy lifting once you design a custom query. It generates the necessary data repository structures and crafts the service code, ensuring that your custom queries are not just designs but instantly actionable components of your backend.

Detailed Description

General

A custom query is usually connected to an API endpoint or is called from a Flow. 

These associations are defined using the user interface, if you are interested, like all other elements created in Wizzdi Cloud, and regardless of the deployment method, a custom query becomes generated code behind the scenes. Some of us, sometimes, may want to look at the code, change it, or enhance it. Otherwise, it is just interesting to know.

When we create a custom query, we use the domain model. Custom Queries provide a way to retrieve data beyond the data retrieval provided by the exposed CRUD APIs.

Like the data retrieval services created by the system, data is efficiently fetched using the system’s database engine.

The process of creating a query is usually along these lines:

  • Define the entities participating in the query; these must be entities from our project and entities from referenced projects, be it from other workspaces or marketplaces.
  • Define the data structure passed to the query; usually, filtering parameters are passed this way. This is called the Request.
  • Define the data structure the query returns; this is called the Response. Besides exceptional cases, most queries return a list of the response object type.
  • Define the conditions narrowing the result set; for example, fetch all Students studying mathematics.
  • Define optional sorting.
  • Define optional grouping. Grouping is an essential concept in queries; for example, calculate the number of students in each class passing minimum average exam result.

 The Custom Query creation interface

Add Query: To add a new custom query, which has name and description fields, the name must conform to Java class names.

Manage: edit a query after it is created.

The main user interface

Root and Connections (joins):  here, we define what are the entities participating in the query.

Root Entity: In query construction, the root entity is the primary Entity from which the query starts. The central table in your query emanates from all paths (joins) to related tables. Select it by right-clicking on a space on the left side of the screen.

Searching for a root entity.

Search for a root entity.
Root created

Root marking on the query diagram

Adding more entities

Why we need to include other entities via cascaded joins from the root entity:

  1. Response Composition: Include related data from different entities in a single query response.
  2. Condition Application: Apply conditions involving fields from multiple entities.
  3. Result Sorting: Use fields from included entities to sort query results.
  4. Data Grouping: Group data by fields from multiple entities in aggregate functions.

Joins are essential when data is normalized across multiple entities, requiring compilation or comparison of information from those entities.

We can use reference fields on the root item to add more entities. (in the image above, we have the Teacher and MainSubject)

Right-click on a reference field (if its type is another entity) and select Join.

You can continue adding more entities from the available reference fields on any entity on the diagram.

Note: When one-to-many relations relate entities, we normally find a field of the one side in the many-side entity. For example, a Child entity may have a Mother field in the underlying database, but there is no Children field in the Mother entity.

However, Wizzdi Cloud adds such a List to the one-side entity. This list is never populated, as it can be infinite in size. However, it is readily used in joins; for example, instead of using the TeacherToMainSubject entity as root, use ‘real’ references to add both Teacher and MainSubject entities to the diagram; we can start with either Teacher or MainSubject like this:

Start from MainSubject and add joins in two hops.

The request

Every query must define a Request object. This object provides the query with the required parameters affecting the result set.

Define a new request by right-clicking on the right side empty area.

Select Request from the right-side top menu, then right-click to define a request object.

The request object includes mandatory fields to control the size of the result set: pageSize and currentPage.

Click the right-facing small arrow to open the Request.

Minimal Request Object

Adding new fields to the request object

Click on the ‘+’ sign to add Property or Object

The request object can include nested objects. If you want to define a new object. Click on the Object button.

Using the respective ‘+’ sign, you can keep adding fields at the correct level; when adding a property, you can use the new types you have defined while creating Objects.

The fields from the Request object are usually used in conditions or the response object.

The Response Objects.

Add response object

Available options when building a response object:

  • Create a property; the property has a name and a data source.
  • Create an Object accommodating a more complex structure in the response.

We can now select the data source for the subjectName property.

While setting the data source for a property.
Data source set

Using functions in conjunction with fields.

Dependencies

Introduction:

Dependency management within Wizzdi Cloud ensures your application integrates seamlessly with other projects and artifacts. This facility allows for the incorporating and reusing of external resources, streamlining development by building upon existing components. Let’s explore this in more detail.

Adding Dependencies:

  • Workspace Dependencies: You can incorporate components from other projects within your current workspace. This is especially helpful if you have multiple interrelated projects and want to leverage functionalities or data structures from one project in another.
  • My Market Place Integration: Beyond your workspace, “My Market Place” is a repository to import external projects and artifacts. Once imported, these become available across all your workspaces, making integrating and reusing established components in various apps easy.

Referencing and Utilization:

  • Domain Model Integration: You can refer to or integrate entities from other domain models with the defined dependencies. This facilitates a modular approach, where specific domain components can be standardized and reused across multiple projects.
  • Custom Queries and APIs: Dependencies aren’t limited to domain models. You can also reference and utilize custom queries and APIs from other projects, ensuring you don’t reinvent the wheel and maintain consistency in data access and manipulation.
  • Business Flow Interactions: Business flows, which define your applications’ logic and operational flow, can also integrate functionalities from dependencies. This is particularly beneficial when standard operational patterns are established and must be replicated across applications.

Wizzdi Cloud’s dependency management is a modular and integrated application development cornerstone. Userd can ensure consistent, efficient, and integrated application functionalities across projects by defining and managing dependencies effectively.

Reusability


In Wizzdi Cloud’s no-code platform, modularity and reusability are core principles. This allows users to efficiently construct applications by leveraging components from multiple projects. Here’s how it works:

  1. Project References: Within a user’s workspace, it’s possible to reference other projects directly from the current project or application. This is achieved through the “dependencies” menu option.
  2. Workspace Reference: You can reference project components from other workspaces you can access. Workspace owners can invite other users to use their projects; access can be read-only, so invitees are blocked from changing them.
  3. Marketplace Workspaces: Wizzdi Marketplace workspaces are available for users of Wizzdi Cloud. The ever-growing repository of solutions can be the starting point for a new project or form most of it. Marketplace apps can either be imported to one of your workspaces, or their elements can be referenced directly from the marketplace. These elements can be
  4. Code access:  Including dependencies in your code is possible from private and public repositories, such as Maven Central. This allows your business logic (flows) to access the methods and public classes defined in the referenced code. But, it is essential to have a basic understanding of Java code and the services that the referenced code offers.

External Entities Integration

This section will provide a concrete example of how to reuse one app within another.

The External App

Here is the domain model for an app called Organization. It describes the organization’s structure, including its employees, branches, and addresses.

Organization App Domain Model
The Address Model can be defined in yet another external project

Here, we have added the Address model to the Organization App.

The dependent App

Here is a very simplified domain model for an e-commerce app seller entity where the Organization entity is set to be the Super Entity of a Seller.

Step By Step

Access the dependencies option from the left-side menu.

 

After clicking, you may encounter a view similar to this:

Click on ‘+ Add Dependency’ to add one,

Click on ‘Search Projects’   and start typing organization; once the Organization-model becomes visible, select it to make it accessible to your project. Once selected, all of the elements in this App are available to the dependent App. The external API the App exposes combines the Referenced App Apis and the Apis from the dependent App.

Using entities from an external App

Right-click on a space in the diagram and select Import->Entity->External 

Then, please search for the desired entity and add it to the diagram

Once visible on the diagram, it can be used in two distinctive strategies: Inheritance and composition.

Inheritance

Select the circle above the Seller entity, drag it to the Organization entity, and then release it on its header.

Once released, the Seller entity includes the inherited fields from the Organization entity.

Two additional fields (not inherited) were added to the Seller entity.

Composition

Here, the Organization entity’s ID circle is dragged onto the Seller name, creating a one-to-many association where the Seller is the many- side.

The composition approach offers several benefits. Firstly, it ensures that unnecessary fields from the Organization are not incorporated into the Seller. This means that the Seller remains streamlined, containing only relevant data. Moreover, the composition method allows the Seller entity to encompass many external entities as fields. This adaptability allows for a more tailored and modular structure, accommodating a wide range of relationships and data sources without compromising the integrity or clarity of the Seller entity.

Components

Introduction:

In Wizzdi Cloud, when initiating a new application, users have a choice between two runtime environments: Spring Boot, a well-known framework, and its extension, FlexiCore Boot. FlexiCore boot has all the features of Spring, it is a Spring Boot with additional features.
Components apply to FlexiCore boot only.

 

Key Features of FlexiCore Boot:

  • Access Control:  Multi-tenancy,refined data and API access control are often needed. FlexiCore Boot offers tools to address these requirements effectively.
  • Modularity in Action: Rather than confining feature modifications to the development stage, FlexiCore Boot supports real-time component integration or removal. It accomplishes this by treating these components as active plugins. This dynamic nature has several benefits:
    • Integration: Enables the smooth addition or removal of components without a complete system reset.
    • Adaptability: As application requirements shift or grow, it’s possible to introduce new functions seamlessly.

Component Types in FlexiCore Boot:

  • Model Component:
    • Purpose: To define the domain model of the application.
    • Features:
      • Structures essential data entities and their interrelationships.
      • Dictates how data will be organized, preserved, and accessed.
      • Serves as the foundational framework for services, APIs, and business logic.
  • Service Component:
    • Purpose: Handles nearly all functions outside of the domain model.
    • Features:
      • Manages both exposed and consumed APIs.
      • Supports custom queries and business flows, shaping the application’s interactions with its data and other systems.
  • Module Component:
    • Purpose: Generates a usable module for integration into the FlexiCore Boot runtime.
    • Features:
      • Modular design for easy runtime integration.
      • Supports specific functionalities or features for modular addition or subtraction.
      • Facilitates scalability by allowing for the addition of new modules as needs change.

Considerations:

While FlexiCore Boot offers dynamic modularity and refined access control, it does come with a consideration. Applications developed using FlexiCore Boot become dependent on the FlexiCore framework. This dependency contrasts with the more universally applicable Spring Boot framework. To ensure flexibility and to cater to varied requirements, Wizzdi Cloud provides support for both runtime environments, allowing users to choose the one that aligns best with their needs and plans.

FlexiCore Boot and Felxicore are open source and available on Github. Binary artifacts are available on Maven Central

Git

Introduction:

Within Wizzdi Cloud, users have tools to oversee the app’s commits, versions, and repositories. While the intricacies of the generated code might remain hidden, the platform ensures that these files are safely stored in repositories. Think of this as a safeguard for your work, akin to an external storage or backup system for your digital creations.

Breaking Down the Terminology:

  1. Commits:
    • Explanation: A commit represents a set of changes or additions to a project’s files. When you commit, you save a version of your files at a particular time.
    • Purpose in Wizzdi Cloud: This allows you to track the modifications made to the app, offering a history of changes and the ability to revert to earlier states if needed.
  2. Versions:
    • Explanation: In software, a version refers to your application’s specific state or iteration.
    • Purpose in Wizzdi Cloud: Versions lets you manage and navigate through different stages of your app’s development, ensuring you can return to a previous version if necessary or progress forward with updates and enhancements.
  3. Repositories:
    • Explanation: A repository (or ‘repo’ for short) is a centralized place where code is stored and managed. It contains all the files and the historical record of changes made to those files.
    • Purpose in Wizzdi Cloud: Repositories store your app’s codebase. They facilitate collaboration, version control, and your app’s intellectual property backup.
  4. Branches
    • Explanation: In software development, a “branch” is a separate line of development that diverges from the main codebase and is often used for developing new features or testing. Each branch represents an independent line of development, allowing developers to work on different features or fixes without interfering with the main or other branches. This concept is crucial in version control systems, where multiple branches can be managed simultaneously.
    • In Wizzdi CloudIn Wizzdi Cloud, the use of the “Generated” and “Master” branches reflects a specific workflow designed to manage and integrate code changes effectively:
      • Generated Branch: This branch contains code automatically generated by the Wizzdi Cloud system. It serves as a repository for the system-generated code, ensuring a clear distinction between what the system produces and what developers manually create or modify. Wizzdi Cloud continuously updates this branch as the system generates new code or updates.
      • Master Branch: The Master branch is where developers actively work on the code. It represents the primary branch of the codebase, typically containing the most stable and up-to-date version of the application code that is manually developed or modified by the developers. Developers use this branch for manual coding, feature development, bug fixes, and other tasks that require human intervention.

      The interaction between these two branches typically involves:

      • Merging from Generated to Master: When Wizzdi Cloud generates new code or updates, these changes are committed to the Generated branch. Developers can merge these changes from the Generated branch into the Master branch. This process allows for integrating the latest system-generated code with the manually developed code, ensuring that the application benefits from automated generation and developer expertise.
      • Separation of Concerns: Keeping the system-generated code in a separate branch (Generated) creates a clear demarcation between what the system produces and what developers create or modify. This separation helps manage the codebase efficiently, making it easier to track changes, resolve conflicts, and maintain a stable codebase.
      • Collaboration and Version Control: Using these branches facilitates collaboration among team members and aids in effective version control. Developers can work on the Master branch without worrying about immediate changes from the system, while system-generated updates can be reviewed and merged systematically.

      This workflow ensures a harmonious integration of automated code generation with human-led development, contributing to an efficient and streamlined development process in Wizzdi Cloud.

Storing Your Code with Repositories:

Even if you aren’t interacting with the code directly, Wizzdi Cloud ensures your work is backed up. It pushes the created files to a repository, safeguarding your intellectual property.

You have several options when choosing where to store this code:

  1. Public GitHub Account:
    • Explanation: GitHub is a popular platform for hosting and managing code repositories. A public account means that the contents of your repository are visible to anyone on the internet.
    • Benefits: Easy accessibility and visibility.
  2. Private GitHub or BitBucket Account:
    • Explanation: This is a version of GitHub/BitBucket where your repositories are hidden from public view and only accessible to those to whom you have granted permission.
    • Benefits: Greater control over who sees your work. It provides more privacy than a public account. Private repositories are now free to use in GitHub. When a repository is created from Wizzdi Cloud, it is private.
  3. Self-Hosted GitLab Account:
    • Explanation: GitLab is another platform for code hosting, similar to GitHub. A self-hosted GitLab means you’re running GitLab on your servers.
    • Benefits: Offers increased control over your repositories. You can ensure privacy and security based on your personal or organizational preferences. However, it must remain accessible online for proper integration with Wizzdi Cloud.

Conclusion:

Managing commits, versions, and repositories in Wizzdi Cloud gives you greater control over your app’s development history. By understanding the terminology and the importance of repositories as backups for your intellectual property, you can make informed decisions on how and where to store your work.

Note: 

In the Wizzdi Cloud workflow, generating, calculating, and committing the code are consolidated into a single action initiated by pressing the “Commit” button. Here’s how it works:

  • One-Step Process: When you press the “Commit” button in the Wizzdi Cloud interface, the system automatically triggers a sequence of actions. First, it generates the necessary code based on the current configuration or parameters set within the system. Then, it immediately compiles this generated code, turning it into an executable format.
  • Seamless Integration: Following the compilation, the system commits the compiled code to the designated repository without requiring additional input or separate action. This step involves saving all the recent changes, ensuring that the latest version of the code is stored and tracked.
  • Optional Deployment on Wizzdi Cloud Customer Cluster: Following the commit, deploying the compiled and committed code on a Wizzdi Cloud customer cluster is an option. This step is optional and depends on whether you use Wizzdi Cloud’s infrastructure for deployment. If you opt for this, the system will handle the deployment process, utilizing Kubernetes to manage and scale the containerized application.

It’s important to note that the Docker build script in the committed code offers the flexibility to deploy the application on any server, not just Wizzdi Cloud. This allows you to deploy your application in various environments, depending on your requirements and preferences.

Description

Accessing Git is carried out from the left-side menu.

 

Setting up a remote repository

We need to define a remote repository for each app we create for the app files.

Click on ‘+ Add Remote‘.

On the first time this is carried out on Wizzdi Cloud, you will be prompted to connect Wizzdi Cloud with a GitHub account. If you do this, click ‘Connect With GitHub‘.

Alternatively, you may select Manual Connection to connect to another remote code hosting provider, such as BitBucket or a private GitLab server.

Connect With GitHub

Make sure you have a GitHub account before you proceed. This account should use the same email to sign up for Wizzdi Cloud.

When signing up for Wizzdi Cloud, you may select your existing GitHub account.

 

Wizzdi Cloud must be authorized to access your GitHub account.

Connect With BitBucket

BitBucket is a popular code hosting service. BitBucket isn’t free for private repositories.

After creating an account on BitBucket, you must use your account username and an App Password to create a repository on Wizzdi Cloud.

Get the username and generate the app password for the Wizzdi cloud.

  • Access the personal setting in BitBucket
  • Get the username. 

 

  • Generate the App Password. 

  • Get the App Password.

The same App password can be used for many Apps in Wizzdi Cloud.

For every remote Git Repository you create in Wizzdi Cloud, you must create a Repository in Bit Bucket.
In Bit Bucket home:

Then

Make sure that the ‘include .gitignore  is set to no.

Once the repository is created, copy the URL, it is used in Wizzdi Cloud to connect to the right repository.

 

Using Bit Bucket username and password in Wizzdi Cloud

Select Manual remote repository definition (click on Setup Remotes)

Manual Connection Steps

  • Check the Manual Connection checkbox.

Fill in the Description and all other required fields, then click Ok. Wizzdi Cloud verifies that the remote repository can accessed.

Note:

When creating a new manually set remote repository on Wizzdi Cloud, you may notice that your credentials from Wizzdi Cloud are auto-filled in the remote repository dialog. Make sure to replace them with the credentials from the corresponding service, such as Bit Bucket.

Committing Apps

Once a remote repository is defined for the App, we need to commit it to the repository. This is required for two main purposes.

  1. Collaboration Between Wizzdi Cloud Users and Java Developers: Committing code to a shared repository facilitates collaboration. It allows Wizzdi Cloud users and Java developers to access, review, and work on the same codebase. This shared access is vital for coordinating development efforts, ensuring consistency, and enabling multiple contributors to work on different aspects of the project without conflict. It should be noted that committing code is not required when team of Wizzdi Cloud users collaborate on the same App, this is carried out by Workspace sharing.
  2. Deployment: Committing code is a crucial step in the deployment process. Whether deploying within the Wizzdi ecosystem or on external servers. The deployment process doesn’t require Wizzdi Cloud users to view or access code; generating and complying code are done ‘under the hood’ and are required to facilitate high-performance apps deployed anywhere.

Committing Steps:

  • Select Commit from the Git menu

  • Fill in the commit message (optional) and leave all other fields ‘as is’.

Whenever the app is committed, a frozen version is created, allowing you to revert to a previous system state at any time.

The commit process takes a few minutes and the progress is presented on the screen.
When successfully committed, the App can be deployed

Flows

What are Flows?

Flows are automated pathways an application follows in response to specific triggers or events. They represent a logical sequence of steps to achieve a particular outcome within an application. Each flow can contain various elements, such as triggers, conditions, activities, and loops, that dictate how the application should respond under certain circumstances.

How Flows Define App Behavior

  1. Triggers: Flows begin with triggers. These triggers can be a schedule (happening at a specified time or interval), a webhook (initiated by an exposed API endpoint front-end or other backend call), or an event (occurring due to user actions or system conditions).
  2. Events: Flows can be designed to respond to or send events, allowing for a sequence of flows to be executed.
  3. Activities: Various activities can be defined within a flow to manipulate data. These can include creating, changing, or committing objects in a database, creating transient objects in the system memory, performing list operations, or handling variables and responding to requests on exposed API endpoints.

Flows in Wizzdi Cloud can be tested against test data. Users can examine the data state at each stage of the flow.

Flows in Wizzdi Cloud

To add a flow to an App, click on flows and then click on ‘+ Add Flow.’

Add new Flow.

Create a Flow

 

A flow name is a single word starting with a capital letter.

Once the flow is created, the screen below is opened:

Note: the yellow flag indicates that you must define the returned Object for this flow.

 

In a flow diagram, lines connecting activities represent the direction and progression of actions within the flow. Each activity represents a discrete step or task in the overall process. When lines link activities, it indicates the sequence in which these tasks are executed and how control passes from one activity to the next.

Here’s how the lines and icons depict the flow of action:

  1. Start Point: The flow typically begins at a start point, represented by a lightning bolt for a trigger. This indicates where the flow initiates.
  2. Directional Lines: Lines that extend from the start point of one activity to another are usually arrows. These arrows show the direction of the workflow. The flow of action follows the direction of these arrows, moving from one activity to the next.
  3. Activity Icons: Each step in the process is represented by an icon or symbol that denotes the type of activity.
  4. Sequential Flow: When an arrow connects one activity directly to another, it indicates that the second activity will commence immediately after the first one is completed. This linear sequence shows a clear start and end point for each activity.
  5. Branching and Decision Points: Some lines may split into two or more paths, signifying a decision point where the flow can branch off based on certain conditions. Each branch will lead to different activities, showing conditional paths of action.
  6. Loops: Loops in the flow diagram allow for repeating a sequence of activities until a specific condition is met.
  7. Convergence Points: Conversely, lines from different activities may converge into a single line, indicating that multiple activities may need to be completed before moving on to the next step in the flow.
  8. End Point: The flow of action concludes at an endpoint, represented by the endEvent icon; this indicates the completion of the process or that the flow has reached a state where no further action is taken. The endEvent must include an Object returned by the flow. This can be, for instance, return the response in a webhook. All lines must converge before the flow ends.

Flow Diagram Tools

Below is a list of diagram tools and activities that may be placed in a flow diagram. Items 1-5 and 16 through 18 are diagram tools.

  1. Go Back: Quit editing
  2. Flow Name.
  3. Edit Flow Details: edit name, description, and package name. Please do not change the package name unless you understand its purpose and you adhere to Java package name rules.
  4. Undo: revert a diagram change.
  5. Redo: revert undo.
  6. Triggers: Select one of the following triggers:
    • Schedule Trigger: triggers a flow at intervals or at a specific time of a selected day of the week.
    • WebHook Trigger: triggers a flow from a custom exposed API endpoint.
    • Event Trigger: triggers the flow from another flow. The other flow sends the event.
    • Other triggers may appear when integrations are added to the app; see below.
  7. Events: These are activities to control the flow.
    • Continue Event: In a loop, ignore the remaining activities and start a new iteration.
    • Break Event: In a loop, leave the loop.
    • End Event: quit the flow and pass the result to the caller.
  8. Object Activities: These are activities dealing with Objects.
    • Create: Creates a new instance of some type.
    • Change: Change the properties of an existing object.
    • Commit: Commit an object to the database, which applies to entities only.
    • Retrieve: Fetch one or more instances from the database.
    • Call Custom Query: Fetch instances using an existing Custom Query.
  9. List Operations:
    • Create List: create a new list of homogenous types.
    • Change List: Apply changes to a list.
    • List operations: perform operations on a list, such as a find.
    • Aggregate List: Aggregation Functions on a list.
  10. Variable Operations:
    • Create a Variable: Create a variable for some object type.
    • Change a Variable: Change a Variable value.
  11. Gateways: A gateway controls the processing flow.
    • Condition gateway: testing a value and processing one of two possible branches.
    • Enum Gateway: Select a different branch for each possible value for an enum variable (a finite list of possible values).
    • Type Gateway: Select a different branch based on the type of an Object.
  12. Code: For the code-inclined, write any code using the built-in editor with Intellisense support. Coding is always optional and is available for people preferring it for some tasks.
    • Define a method: define a Java method.
    • Call a method.
  13. Loops: Create loops. Loops can be nested to any level.
  14. Call External API: Access one of the pre-defined services consumed APIs and those added by you in the APP.
  15. Integrations:  Use any of the current integrations added to the app.
    • Kafka: A high-throughput, scalable streaming and messaging platform.
    • MinIO: Distributed, high-performance object storage system.
    • WebSocket: Protocol for full-duplex communication over TCP.
    • MQTT: Lightweight, publish-subscribe network protocol for devices.
  16. Restore zoom value.
  17. Zoom In.
  18. Zoom Out.

The flow diagram in the image above appears as a default view upon creation. It includes two connected activity icons

    A. Schedule Trigger: A flow starts with a trigger; the default trigger is a schedule trigger.

    B. End Event: A flow must end with an End Event. This is where processing terminates, and a result is returned to the caller.

  • Drag any icon on the diagram canvas to a new location.
  • Click on any icon to edit it.
  • Use the mouse wheel to zoom in or out of the diagram.
  • Use the bottom right tools to fit to the screen, zoom in, and zoom out.
  • Use the top left tools to edit the name and package name of the flow, undo, and redo.
  • When dragging an icon from the left toolbar, position it on an existing line to insert it between two icons.  Move the new icon over the line till the line is lit up, then release the icon.
Line lit while dragging an icon.
The in-between icon is connected.

Available Flow Activities and Icons.

 

 

Triggers

Select the start icon for a flow, that is, the way the flow is started or triggered.

Schedule trigger

Trigger at Intervals

This trigger can run in intervals, say, every 15 minutes.

Trigger at intervals

Available fields:

Name: The trigger name must be a valid variable name, starting with a lowercase letter and containing no spaces.

Description: document this trigger.

Run: Select the scheduling type for

 

Trigger at a specific time of the day.

The ScheduleTrigger can be set to trigger at specific times and repeat daily at a particular time.

Select the days of the week using the ShceduleTrigger type.

Days of the week scheduleTrigger

Available Fields:

Weekdays:  select the days of the week you want the trigger to fire.

When: select the time of the day you want the trigger to fire.

 

Proceed to select the time of the day.

Select the hour and minutes using 0-23 notation.

Webhook Trigger

Integrating a WebHook with a business service establishes a direct connection between a custom REST API endpoint and a Flow.

This flow is triggered when the custom endpoint receives a request. The endpoint can optionally pass a request body, headers, path parameters, and query parameters to the Flow.

The end event of the flow includes the response generated by the Flow. The response should match the response defined in the custom endpoint.

Creating a flow bound to a custom API.

This can be created from the API endpoint or from the flow creation.

Create or select the flow from the API endpoint (recommended)

A custom-exposed endpoint. Request and Response objects are defined.
  1. This is the Tag under which the custom endpoint appears in the exposed endpoints list.
  2. The Request object
  3. The Response object
  4. Select a Query or a Flow. It can be an existing one or a new one.

Select a Flow

Search for a Flow or create one.

Creating a new flow is selected.

Once you provide the flow with a name, click the ‘ Select ‘ button. The flow is now created. You can access it directly from the exposed API editor.

 

Go to the flow from the custom API endpoint.

 

The new flow has a Webhook trigger.

A WebHook trigger triggers the new flow, the required variables for the request body (if it exists), and the parameters the endpoint passes are defined.

The new Flow has the correct Object type on the trigger as defined on the API endpoint.

 

Create the Webhook on a new Flow.

Place a new WebHook trigger on a new flow. The existing trigger should be deleted. Click on it and use the three-dot button to delete it.

 

On the Webhook drop-down menu, select an existing custom API. Then save the Webhook trigger.

An API endpoint can trigger a single flow.

Once the webhook is saved, the required variables are auto-created based on the Endpoint definitions.

Webhook Trigger fields.
  1. The activity name should be a valid Java field name.
  2. Description, use for documenting the activity.
  3. The path to the connected API endpoint (WebHook).
  4. The Object type passed to the flow.
  5. The object’s name passed: use this name when referring to the passed body and its fields.
  6. Mapping for endpoint parameters: Query, Path, and Headers.

Event Trigger

Wizzdi Cloud systems use an event trigger to start a flow when a particular event occurs. This event is represented by an event object, which can either be predefined by the system or defined by the user. Typically, events are triggered by actions like creating or updating an entity. Custom events can also be defined, where some conditions can be tested to check if the flow should be executed.

The same event can trigger multiple flows.

Flows can also be explicitly called from other flows; see below.

Create an Event Trigger

Drag an event trigger from the toolbar and delete any existing trigger.

Select the Object type and assign it a name, then select the condition from the three possible options: CREATE, UPDATE, or CUSTOM.

Event trigger fields
  1. The type of the trigger.
  2. The name of the trigger
  3. The description for this trigger.
  4. The type of object firing this event. In our case, a Teacher object.
  5. the name of the Object Type.
  6. Specify the instance name of the object triggering the flow, which will be referred to in subsequent activities.
  7. Condition: It will only fire on the following conditions: Create, Update, or Custom.
    • Create: This flow is triggered whenever an object of the specified type is created.
    • Update:  This flow is triggered whenever an object of the specified type is updated.
    • Custom: This option allows you to use an expression to filter for a custom condition. When the condition is evaluated as true, the flow processing commences.

When events are fired?

Events are fired based on the runtime selected and some other conditions.

  • If the fireEvent activity is used in one flow to activate another, the object type used in the fireEvent should match the one selected on the event trigger; the event trigger condition should be set to none or evaluated to true.
    • The above works on both runtimes, Spring Boot and Flexicore Boot.
  • Spring Boot:
    • If the object type is an Entity, the flow will be activated when there is no condition.
    • If there is a condition, it should be evaluated as ‘true ‘ in the custom condition.
    • To use Create or Update conditions, the entity must have two fields defined as Creation Date and Update Date, respectively. See the field’s purpose when defining the domain model.
  • Flexicore Boot, Flexicore
    • If the Object type is an entity, the entity is sent to the triggered event.
    • CREATE and UPDATE can be used as conditions; there is no need to set a creation date and update the date on entities in Flexicore derived from Basic. See elsewhere on this document on FlexiCore extensions over Spring Boot.

Sending a custom Object from one Flow to another flow.

  • When an Event Trigger is defined, there is no option to define an object type. Only existing types can be selected.
  • If you need to create a new object type, you must do so from either consumed or exposed APIs.  Search in this document for ‘Adding Request object’.
  • Once you create such an Object on a dummy endpoint, you may delete the endpoint; the definition remains available here and elsewhere. Note: The soon-to-be-released version of Wizzdi Cloud offers a new Object definition inside the flow.

Integrations Triggers.

When Integrations are added to an App, additional triggers may become available from the flow toolbar. For example, Kafka, Websocket and MQTT integrations add triggers.

Triggers and Activities when integrations are added.

 

Events.

 

These are used at the end of the flow (End Event)  inside loops (Break Event, Continue event)

The Continue Event and Break Event are discussed below in the context of Loop.

End Event.

A flow must end with at least one end event. The endEvent defines a response value in a predefined Object type.

When a WebHook triggers the flow, the response type in the endEvent must match the defined response for the associated endpoint.

When an event triggers the Flow, for instance, one fired by another flow, the response has no meaning. A common practice is to change the received object to contain the required data the publisher requires.

Definition

Drag an event icon and place it on the flow; new flows include such activity already.

End Event – example returning Time and Date (with proper timezone)

Expressions

In the End Event above, an expression was used to define the return value for the flow. Such expressions are used in other places in flows.

In Wizzdi Cloud, the management of object fields—whether setting them for new objects, altering them in existing objects, or applying filters for retrieval—is handled through an expression editor. This editor functions in a way that’s analogous to the formula features found in spreadsheet applications like Microsoft Excel and Google Sheets, where expressions are used to perform calculations or manipulate data.

The expression editor in Wizzdi Cloud utilizes the syntax of Spring SpEL (Spring Expression Language), a powerful expression language that supports querying and manipulating an object graph at runtime. Spring SpEL expressions can be used for a wide range of operations in Wizzdi Cloud, from setting default values for object fields to defining the logic for filtering data during retrieval.

When Wizzdi Cloud generates code, the expressions written in Spring SpEL are translated into standard Java code. This conversion process ensures that the high-level, user-friendly expressions are turned into executable code that can run within the Java environment.

The appendix provided in the Wizzdi Cloud documentation likely contains various examples of how Spring SpEL can be used within the platform. These examples serve as a practical guide for users to understand and craft their expressions for different purposes.

The SpEL editor in Wizzdi Cloud has features like Intellisense, an intelligent code completion tool. Intellisense assists users by suggesting functions, methods, and property names as they type, helping to prevent syntax errors and speeding up the expression writing process. This feature is particularly useful for those who may not be familiar with the full syntax and capabilities of Spring SpEL, as it can guide them through the process and improve their efficiency when working with data in Wizzdi Cloud.

Objects.

 

In the context of a flow interface, “objects” can represent different stages or components within a business process or workflow. These objects serve as digital stand-ins for real-world elements of a business operation, such as documents, tasks, products, or services.

Each object in the workflow would have attributes and statuses that reflect its current position or role in the overall business flow. For instance, an object could represent a customer order that moves through various stages like order placement, fulfillment, shipment, and delivery. At each step in the process, different operations might be performed on the object—such as updating its status, modifying its details, or moving it to the next stage in the workflow.

Here’s how the functions in the interface relate to managing the lifecycle of an object within a business flow:

  • Create Object: Initiates a new instance in the workflow. For example, this could be used to start a new customer order.
  • Change Object: Alters the details of an existing object as it progresses through the flow. This might include updating the status of an order from “pending” to “fulfilled.”
  • Commit Object: Makes any changes to the object permanent. This action could be analogous to confirming a step in the business process has been completed, ensuring that the object reflects the latest stage in its lifecycle.
  • Retrieve Object: Looks up and retrieves objects at any point in their lifecycle. This is useful for monitoring progress or auditing the history of an object’s journey through the business flow.
  • Call Custom Query: Executes predefined queries tailored to the business’s needs, which may involve complex data retrieval across different stages of the business flow. For example, a custom query might gather all orders ready for shipment.

In essence, this business flow interface allows for the digital tracking and manipulation of objects that mirror the phases of a process.

Create Object Activity

Create a new instance of an object

explanation

  • Name: Every activity within the flow is assigned a name. This name is used to identify the activity and typically reflects the action or step in the business process it represents. For example, an activity might be named “invoiceGeneration” or “qualityCheck.” Note that names have built-in restrictions, such as no spaces.
  • Description: Alongside the name, each activity has a description. This description offers additional details about the purpose or action of the activity and is displayed as a tooltip when a user hovers over the activity within the flow. This feature aids users in understanding the function of each step without cluttering the visual representation of the flow. Furthermore, there is functionality to embed these descriptions as comments in the source code generated by the Wizzdi Cloud, enhancing code readability and maintenance.
  • Object: This refers to the type of object that the activity creates or manipulates. The object type must be pre-defined within the App and is part of the digital representation of the business process. For example, the object in a sales process flow could be “CustomerOrder” or “PaymentReceipt.”
  • Output Name: once an object is created or modified by an activity, it must have an output name, which serves as a handle or reference to that particular instance for the duration of the flow. This allows the object to be identified and accessed by subsequent activities within the flow. For instance, if an object named “orderDetails” is created, it can be referenced by that name in downstream activities like “orderConfirmation” or “dispatch.”
  • Data Fields: Below the aforementioned components, you would typically find fields or parameters that allow you to specify the data you wish to add to the object instance being created. These could include various attributes of the object, such as dates, status codes, quantities, or any other relevant data points. This information is critical as it populates the object with the necessary details to represent a step in the flow accurately.

 

Change Object Activity

Once objects are instantiated in upstream activities (those activities that have been executed), the Change object Activity can change them.

Drop the Change Object activity on the execution line or an empty diagram area and open it.

Change Object Activity.

Select the Object Type and the Object Instance (Input Variable), and change the object fields.

To change the object fields, you need to select the fields that need changing; you do not have to update all fields.

Note a field called Teacher in the example; it lets you assign to the object instance that is the subject of the change another object of the same Object type.

Select fields for a change.

 

Populated Change Object Activity Dialog

Commit Object

When an object instance is an entity, changes are not written to the underlying database unless committed.

Drag the Commit Object activity to the required position on an execution line, then click on it to select the object you want to commit.

Commit an Entity ( an Entity Object)

Once the required fields are filled, the dialog should be similar to the dialog below.

Commit Object Activity filled.

Retrieve Object(s).

This activity pertains to obtaining data from a database, a common necessity in many software systems, especially when dealing with data-driven responses or processes.

  • Use in Custom APIs: When the APP exposes custom API endpoints for use by other systems or user interface clients, it often needs to retrieve specific entities from its database to compile the data necessary for the API’s response. For example, if the API is designed to provide customer details, the activity would fetch customer entities containing information like names, addresses, and transaction histories.
  • Batch Processing: There are situations where a set of entities needs to be processed as a group. This could involve batch updating records, performing calculations, or generating reports. For instance, a financial system may fetch all transactions for the end-of-day processing to calculate interest or fees.
  • Integration with External APIs: Often, entities from the local database need to be sent to external APIs. This is common in integrations where two different systems communicate with each other, such as sending order details from an e-commerce system to a shipping provider’s API to arrange delivery.

When retrieving entities, if the requirement is straightforward, such as fetching a list of all products in a catalog, the resulting list will contain entities of a single type, all sharing the same structure or schema. In this case, the Retrieve Object is a good fit for the job.

However, there are instances when the needed information is not contained within a single entity type. In such cases, the “Call Custom Query” activity (below) can fetch data from multiple entities that must be combined. Custom Queries are powerful tools that specify complex data retrieval operations, such as joining data from multiple entity types. Custom Queries enable you to define a custom structure for the output list, including fields from various related entities. For example, you might need a list that combines customer information with their respective order histories and payment statuses. Custom Queries would allow you to define and retrieve a complex list tailored to your requirements.

How to use

Drop a Retrieve Object activity on an execution line or a diagram space.

Retrieve object empty Dialog.

Retrieving entities from a database typically requires careful consideration to avoid performance issues. Fetching all entities of a particular type at once is generally inefficient and can lead to resource strain. To mitigate this, filtering mechanisms are employed.

Filtering allows for narrowing down the dataset to only those entities necessary for a particular operation or requirement. It can be based on specific criteria, such as a date range, a status, or any other relevant attribute of the entities.

Paging is a common filtering technique used to manage data retrieval by dividing the results into “pages” of a specified size. This means that a subset of records is fetched instead of retrieving the entire dataset in one go. The size of each “page” or batch can be configured based on the application’s performance considerations and the data processing needs.

Wizzdi Cloud, as mentioned, provides built-in filtering capabilities that can be applied to any entity. These built-in filters are predefined and can be easily applied to retrieval.

For more complex filtering needs that cannot be satisfied by the built-in options, the Custom Query Request Object is utilized, and the required activity is Call Custom Query. This object provides flexible, user-defined filtering criteria, including multiple fields from the entity, complex conditional logic, and the ability to join data across different entity types.

When processing all entities of a certain type is necessary, the paging mechanism is used to loop through the entities in manageable batches. This approach allows the system to process large datasets without overwhelming the memory or processing power by only handling a small subset of records at any given time.

In practice, the user specifies the desired filters once the entity type is selected for retrieval.

The retrieve type option has three possible values: all, first, or any.

  • ALL: the returned object type is a filtered list of the selected object type. For example, a list of teachers. The list is always returned, but it may be empty.
  • First, Any: the returned type is the type selected. For example, a teacher. This instance may be valid or null.
Retrieve object activity when the object type is selected.

Adding filters.

Retrieving entities from a database typically requires careful consideration to avoid performance issues. Fetching all entities of a particular type at once is generally inefficient and can lead to resource strain. To mitigate this, filtering mechanisms are employed.

Filtering allows for narrowing down the dataset to only those entities necessary for a particular operation or requirement. It can be based on specific criteria, such as a date range, a status, or any other relevant attribute of the entities.

Paging is a common filtering technique used to manage data retrieval by dividing the results into “pages” of a specified size. This means that a subset of records is fetched instead of retrieving the entire dataset in one go. The size of each “page” or batch can be configured based on the application’s performance considerations and the data processing needs.

As mentioned, Wizzdi Cloud provides built-in filtering capabilities that can be applied to any entity. These built-in filters are predefined and can be easily applied to retrieval.

When processing all entities of a certain type is necessary, the paging mechanism is used to loop through the entities in manageable batches. This approach allows the system to process large datasets without overwhelming the memory or processing power by only handling a small subset of records at any given time.

In practice, the user specifies the desired filters once the entity type is selected for retrieval. If the operation requires processing all entities, the user creates a loop that fetches and processes each batch of entities sequentially until all entities have been processed. This loop utilizes the paging mechanism to move through the dataset incrementally.

Selecting from available built-in filters.

Details

Select the pageSize filtering field and click on the pencil icon to set the value.   

The expression editor opens, and we set the page size to a constant 10 records.

Current page setting from a variable.

A variable was created for the current page value (see variables below), and the expression references this variable. The image was taken while typing the word current. The expression editor IntelliSense feature suggests the existing variable with its Object Type.

Call Custom Query

When retrieving entities, if the requirement is straightforward, such as fetching a list of all products in a catalog, the resulting list will contain entities of a single type, all sharing the same structure or schema. In this case, the Retrieve Object is a good fit for the job.

However, there are occasions when the needed information is not contained within a single entity type, or filtering must be finer than what the built-in one provides. In such cases, the “Call Custom Query” activity (below) can fetch data from multiple entities that must be combined. Custom Queries are powerful tools that specify complex data retrieval operations, such as joining data from multiple entity types. Custom Queries enable you to define a custom structure for the output list, including fields from various related entities. For example, you might need a list that combines customer information with their respective order histories and payment statuses. Custom Queries would allow you to define and retrieve a complex list tailored to your requirements.

Explanation.

Empty Call Custom Query Activity dialog.

Once the Custom Query is set from the available custom queries, its request object is presented to be set with data from available object instances in the flow.

Consider a flow that starts from an API endpoint. The API endpoint initiates a flow by receiving input parameters for a custom query. Additional data required for the query may be computed or retrieved within the flow. The combination of initial and acquired data is then used to configure the custom query request object, which dictates the filtering criteria for the query.

Custom Query request object fields presented

Set the request object fields with values from variables or objects defined elsewhere in the query.

Set the teacherNameLike field from a variable set in the query.
Set the startDate to now minus ten days

Lists.

Manage lists; here, you can create a list of any Object, change the list by removing, clearing, or adding elements, perform a set of operations on lists such as find, union, and dozen more, and perform aggregations on lists such as count and sum.

Create A List

Drag a Create List Activity on an execution line to connect to activities at both sides.

The empty list activity

Set the Create List fields: set the list type and the name for this list. The activity name and description can be set too.
Note: an activity has a name; this is for you, the user, to identify the activities on the diagram. The output name is the internal name of the list other activities can reference. The generated Java code uses the output name.

Change a List

Drop the change list on an execution line and let it connect to the activities on both sides.

An empty change list activity.
Filled Change List Activity.

The change list activity has three options for the change: add, clear, remove

The Add and Remove command requires two parameters: the instance to add or remove and the list. The Clear change type requires only one.

List Operations Activity.

  1. Intersect: Creates a new list containing only the elements that are present in both of the original lists.
  2. Subtract: Removes all elements in the second list from the first list. The resulting list contains only those elements in the first list but not in the second.
  3. Contains: Checks if the first list contains all elements of the second list and returns a boolean value (true or false).
  4. Equals: Compares two lists to determine if they are the same in content and order of elements, returning a boolean value.
  5. Sort: Orders the elements of a list according to the specified criteria, which can be in ascending or descending order based on one or more attributes.
  6. Map: Transforms each element in a list based on a provided function or expression and can be used to extract specific attributes from a list of objects.
  7. Find/Filter: Searches for elements in a list that match a specified condition and returns a new list with the matching elements. It can also return a single element if the ‘findFirst’ operation is used.
  8. Head: Retrieves the first element of a list if it exists.
  9. Tail: Retrieves the last element of a list if it exists.
  10. Union: Combines two lists into one, including all elements from both, even if duplicates exist.

To use these operations in Wizzdi Cloud, you would typically select the operation type from a dropdown menu, specify the input list(s), and, if necessary, provide additional expressions to dictate how the list should be manipulated. You would use the output name to reference the resulting list in subsequent activities within your workflow.

Explanation and example

Suppose we have an entity called Book.

The book entity

 

The following description is a collection of list operations depicting their purpose and usage.

Retrieve books from the database.

Create a List of books (Book type) by retrieving the first ten books or less.

Create a list of the Book type called currentBooks from the first ten books.

Create an adHocBook

Book Object Created

This is created to populate another list of books

Create a new, empty list of books.

Create an empty list of books.

Add the adHocBook to the moreBooks list.

Add the ‘adHocBook’ to
the ‘moreBooks’ list.

Add the two lists into a third one

Add moreBooks to currentBooks.

The union operation creates a new list out of two existing lists.

Subtract one list from another.

Subtract operation.

The resulting list is identical to currentBooks minus all books in currentBook that are found in moreBooks.

Sort a list. The result forms a new list

Sort operation
Setting a sort field

In many data processing contexts, particularly in databases, data analysis, or programming, there’s often a need to sort datasets based on multiple criteria. This is where sorting by a list of fields becomes relevant. Here’s a detailed explanation:

  1. Multiple Fields Sorting: Instead of sorting by a single attribute (like age or name), sorting by a list of fields means sorting data based on multiple attributes. For example, you might first sort by age and then by name.
  2. Ascending and Descending Order: Each field in the list can be sorted in ascending order (e.g., from smallest to largest, from A to Z) or descending order (e.g., from largest to smallest, from Z to A). This order is specified for each field individually.
  3. Significance of Order in the List: The position of the field in the sorting list determines its priority in the sorting process. The first field in the list is the primary sorting criterion. Only when there are ties in this first criterion does the second field come into play, and so on.
    • For example, consider a dataset sorted based on the list [Age (ascending), Name (descending)]. Here, the primary sorting criterion is age in ascending order. If two records have the same age, their order is determined based on their names, in descending order.

Intersect two lists

Create a list of books that appear in both lists, currentBooks, and moreBooks.

The intersect operation creates a list of objects appearing in two lists.

Create a list by filtering anther list using the find operation.

 

 

Filter a list
Are all objects of moreBooks included in currentBooks list

The Equal operation

Compares two lists and returns either true or false as a result.

Set the two lists

Contains 

return true if all objects in the second list are found in the first list.

The Aggregate List Activity

The aggregate list activity provides the following aggregations over a list of objects.

Count 

Counts the number of items in a list.

Count the items in a list.

Sum a value across a list.

Sum s specified field in each item in a list.

Find the minimum value in a list.

Find the minimum value of a specified field across all list items.

Find the maximum value in a list.

Find the maximum value of a specific field across all list items.

Find the average value in a list.

Find the average value of a specific field across list items.

Variables.

Create or update a variable (A temporary object holding data).

Variables are used throughout the lifetime of a flow to store intermediate data, control loops, and more.

Create a Variable

Drop the created variable activity on an execution line; the empty activity should look like this.

The Empty Create Variable activity

Apart from the standard name and description, this activity requires you to fill in the following fields:

Variable type: Search for the required type of variable. It can be any type, including entities and other objects.

Variable name: The name of the created variable; this is how it will be identified by activities downstream of the flow.

Init expression: The value given to this variable once it is created.

Create a Variable of a String type with init value.
Create a variable of an object type OffsetDateTime

Gateways.

Gateways are for changing the processing path in a flow based on data. The Condition deals with true/false paths. The Enum gateway deals with multiple possible values and corresponding paths for each. The Merge gateway continues processing from multiple paths back into a single path. The Type Gateway allows processing to take different paths based on a descendant type of some parent type.

The Condition Gateway.

The Condition Gateway evaluates an expression and changes the execution path according to the result.

Eventually, all execution paths must merge before the flow endEvent is reached.

Consider the following flow:

Simple flow for depicting conditions.

The condition in this flow check is two variables are equal and take a different execution path based on the result.

 

The condition gateway activity

In the flow, we set variableA to 5 and variableB to 6 (both are int type), so the expression result will be false.

From the Condition Gateway, we have two execution paths; the first is created for a ‘false’ result when you drop the condition gateway on the existing connection line. The second should be dragged from the outlined ‘ear’ to the next activity on the ‘true’ connection line.

How to connect the second connection line for ‘True’

In the flow above, you can see the Condition Gateway with the two execution paths.

The Merge Gateway

When the execution flow splits because of a Gateway, it must be merged before the flow execution is finished at the end event.

The Merge Gateway

The merge gateway has multiple entry points (unlimited) and a single output point. Its definition includes a name (for the activity) and a description.

The merge gateway on the flow

Note the empty ‘ear’ for connecting a new connection line (execution path); a new one will be created once it is used.

Java code.

This is for developers who wish to enhance diagram-based programming with Java programming. Methods creation is supported. A full Java editor is provided, including auto-completion and awareness of project available types and services.

Loops.

Create loops across a list of elements or for a fixed number of times; loops are visual containers hosting other icons (activities), including nested loops.

To create a loop, drag the loop icon on a connection line. Or drag it onto a diagram space and manually connect it to upstream and downstream activities.

Inside the loop

The activities inside the loop represent what one iteration should do; the structure should be similar to any flow structure. The loop has one entry point and one exit point.

The break and continue events are provided to allow exiting the loop or starting a new iteration without finishing the current one.

Loop types

There are two types of loops: a “for loop” and a “loop over collection.”,

  1. For Loop:
    • This is typically used for executing a set of actions a fixed number of times. The for loop might represent a process that needs to repeat certain steps a predetermined number of times. For example, if a task needs to be performed daily for a week, the for loop could iterate seven times.
  2. Loop Over Collection:
    • This loop iterates over a collection of items, such as a list. This could represent a process where each item in a collection must undergo the same actions. For instance, if you have a list of teacher records that each need to be processed similarly, a loop over collection would be used to iterate through these records.
Loops Example

The example above depicts some points:

  • It retrieves an unknown number of Teacher items from the database in a preferred paged manner.
  • It demonstrates how loops can be nested.
  • It uses the two types of loops.

Steps to build.

Step 1

Drag the loop icon on a connection line.

Drag the bottom right corner of the loop to adjust its size. The yellow flag indicates that the Loop is not yet defined.

‘For loop’ type defined.

The loop above is defined as follows:

  • The variable name for the loop is currentPage. We need this loop to control teacher records (entities) fetching.
  • The Init value is 0; we start with page 0.
  • The condition value is set to true. This is because we do not know how many pages will be present. We will exit the loop when the current batch of teacher records is empty. See below.
  • The increment value is 100, which is our choice for a batch size. Too large a batch size will strain our resources, and too small is inefficient.

Step 2

The next step is to drag a Retrieve Object activity inside and to the left side of the loop. It will auto-connect to the loop entry point.

Click on the activity to edit it.

The Object Retrieve activity to get a batch of teachers.

Setting the retrieve Object correctly is critical as we do not want to fetch all Teacher records in one batch.

  • Set the object type to Teacher.
  • Set the output name to teachers. This will be a List of Teacher types per batch.
  • Set the Retrieve Type to all; we will get all teachers available filtered by the Property Mappings.
  • Set the Property Mappings as follows:
    • Click on Add Field and select the currentPage field. The system created this field for the Teacher entity to allow paged access to the Teacher entity.
    • Set the field value to the currentPage variable set on the main loop. Save changes.
    • Click on the Add Field again. Now select the pageSize field and set it to 100.

Note: The currentPage field in the Retrieve Object activity gets its value every loop from the currentPage ‘For Loop’ control variable; we have set the ‘For Loop’ currentPage variable to increment by 100 every loop, hence the setting of 100 for the pageSize field of the Retrieve Object activity.

Step 3 

Connect the Retrieve Object activity’s exit ‘ear’ to the loop’s exit point.

Connection Line inside the loop

Step 4

Drop a Condition Gateway on the line connecting the Retrieve object Activity and the loop exit.

The gateway checks if the last Retrieve Object execution has returned an empty list; this is the condition for exiting the main loop.

Click on the gateway and set it to check if the teachers’ list is empty.

Gateway Setting

Step 5

When the teachers’ list is not empty, we want to process the items individually and increase each teacher’s salary by 20 percent.

We need to drag and drop a new loop inside the main loop; this loop processes each batch if it is not empty.

Drop inner loop

 

Inner loop dropped

The inner loop is now ‘yellow flagged,’ indicating that we must define it properly.

Inner loop (over collection) defined.
  • The inner loop type is Loop Over Collection, and the collection is the currently fetched batch from the database.
  • When such a loop iterates, every item is fetched from the collection into a variable. We need to define this variable’s name so we can reference it inside the loop. The name selected here is ‘teacher’.
  • The type of ‘teacher’ needs no definition as the type of each item is known; it is the type of the collection. So, the type can be inferred by the system implicitly.
  • Lastly, we must type the collection’s name to iterate over, which is the name given to the collection in the retrieve Object activity. That is, ‘teachers’.

Step 6

Drag  a Change Object activity and place it inside the inner loop as follows:

Change Object in the inner loop, yet to be defined.

Set the activity parameters as follows.

Change variable details

Although the type of teacher is known in runtime, we need the Object Type to be set to Teacher so the property mappings correctly reflect a teacher’s fields.

We now must select the field we want to change in the teacher variable.

Click on the ‘+Add Field‘ and select the salary field.

Select the salary field.

Set the salary to a new value. This will be the current value*1.2.

Change Salary to the current value * 1.2.

Step 7

Connect the right ‘ear’ of the Change Object Activity to the inner loop exit.

The inner loop connection line while dragging.

Connection line connected to inner loop exit.

It is important to note that when an object is modified in a Change Object activity, the changes will not be reflected in the database until they are committed. To ensure that the changes are saved, a Commit Object Activity should be added inside the inner loop.

Empty Committed Object activity.

 

The commit object is filled with the Object Type Teacher and the variable ‘teacher’.

The Commit Object activity is straightforward and requires both the variable and the object type.

Step 8

We need to define the actions taken when there are no additional Teacher items and the Gateway Condition evaluates to true.

In such a case, we need the main loop to exit, this is achieved by the Break Event.

The break event.

The two paths from the Condition Gateway must merge before exiting the outer loop. We’ll use a Merge Gateway on the connection line from the inner loop to the outer loop exit.

Merge Gateway added on the end of the ‘false’ path exiting from the Condition Gateway.

Step 9

The ‘true’ path should also end in the same Merge Gateway, so we connect the right ‘ear’ of the Break Event’  to an empty ‘ear’ on the Merge Gateway.

The final example looks like this.

The Break Event is connected to the Merge Event.

External (consumed) apis.

 

Access external service providers from here; these include built-in services (like Google’s) or consumed APIs defined in the Consumed Apis section.

Fire Events.

Fire an event from one flow, potentially notifying another flow. Events are processed synchronously and pass an Object to the receiving Flow.

The same event can trigger multiple flows.

Additional Activities from integrations.

See below a discussion about Integrations. These are software components available on the Wizzdi cloud. Once added to an App, integrations may add additional activities to the left side menu of any App flow. For Example, the WebSocket integration adds these activities:

Docker

Introduction to Docker

Docker is a platform that enables developers to package applications into containers—standardized executable components combining application source code with the operating system (OS) libraries and dependencies required to run that code in any environment. Containers are isolated from each other and bundle their software, libraries, and configuration files; they can communicate through well-defined channels. Docker provides the ability to package and run an application in a loosely isolated environment called a container.

The benefits of Docker include:

  • Portability: Since the container contains all the dependencies, the application can run on any Docker system installed, regardless of the configuration.
  • Consistency: Developers can be assured that the application runs the same way in development, staging, and production environments.
  • Efficiency: Containers can share OS kernels and use less memory than traditional virtual machines.

Docker Deployment on Wizzdi Customer Cluster

When you deploy an application on the Wizzdi customer’s cluster (see deploy), the Docker image is automatically built and deployed “under the hood.” This means that the platform takes care of containerization aspects such as setting up the Docker environment, creating the Docker image, and deploying it within the customer’s cluster. This process abstracts the complexities of container management and allows you to focus on the development of the application itself.

Installing Docker for Deployment Elsewhere

If you wish to deploy the Docker container elsewhere, you need to have Docker installed on the target system. Here’s how you can install Docker on the three major operating systems.

Deploying with Docker Compose

Once Docker (and Docker Compose on Linux) is installed, you can deploy your application by following these steps:

  1. Clone the created code repository to your local machine or selected server. Required files are on the remote repository you have set for the app.
  2. Navigate to the main folder of the code where the docker-compose.yml file is located.
  3. Run docker compose up in the terminal.

This command will start all services defined in your docker-compose.yml file. Docker will download any images required and run the containers as defined in your configuration.

You can now access the running app OpenAPI interface from the same system browser
HTTP://localhost:8080/swagger-ui.html

If you have uploaded static files into Wizzdi Cloud, you can access the user interface on:
HTTP://localhost:8080

Deployments

The user interface lists all previous deployments on the Wizzdi Cloud customer’s cluster. This is for information only, and it shows previous versions and the currently running one, if at all.

Deployments.

For example:

Deploying an App

Deploying a committed App to the customer cluster is carried out as follows:

You can install(deployit from the Overview menu or the Install button on some screens.

Click on Install on any of the two options, and you will be presented with the deployment progress report.

When you update the App and commit again, the Install button becomes Upgrade. A new version will be deployed.

Accessing An App exposed API endpoints from anywhere

Once the App is deployed (wait a few minutes till it becomes alive), it can be accessed from your browser as follows:

From Swagger (Open API interface) :

  • Switch to App Overview and copy the Swagger URL from there

The URL is available if the app is deployed on the Wizzdi customer’s cloud. Copy the URL into the browser.

Swagger User Interface

The Tags and API endpoints list comprises CRUD APIs created by Wizzdi Cloud, custom APIs from the APP, and some default APIs related to AppUsers.

Using the Swagger interface

  • The first step is to sign in; the admin.username and admin.password are defined in the Properties section. See below a discussion on how to set values to both admin.username and admin.password properties..
    • Find the login API

    • Open the login API and click on ‘Try It Out.’

The screen after ‘Try it out’ is clicked.

Type the admin.username and admin.password as defined in properties., then hit execute
    • You now need to copy the Authorization key and paste it into Authorize.
    • Click on the Authorize button:

    • Paste now the copied authorization into the text box and click Authorize.
  • You can now access endpoints in the API. The Authorization key is usually good for 24 hours.
  • Let’s test the API to validate that the key was correctly copied, and we can execute all endpoints.
    • Let’s find existing users.
Search for ‘getAllAppUsers’ API
    • Click on ‘try it out’.
    • Use this body for the POST method:
    • Providing some of the available filters on the endpoint
    • And the result
getAllAppUsers typical result

Unique Identifiers in the returned JSON data

The concept of json-id in JSON response is used to reference specific items within the JSON structure. This is a common practice in data serialization and management, especially in complex JSON objects that contain nested structures or multiple instances of similar objects.

Here’s a brief explanation of the concept:

  1. Unique Identifier: Each json-id is a unique identifier that differentiates each object or item in the JSON structure. This uniqueness is crucial for accurately identifying and referencing specific elements within the JSON data.
  2. Reference and Linking: In complex JSON structures, especially those representing relational data, json-id can create links or references between objects. For instance, an object in one part of the JSON might reference another object using its json-id.
  3. Client Side expansion: The client code must be able to expand such responses correctly. Code samples in some client-side programming languages can be found on Wizzdi.com.

 

 

Accessing static files.

You can create the Web APP to access the exposed API endpoints using your technology of choice. Once the application is ready, you can upload it to the App, and the server will serve it.

Access the App overview: Access it from the left-side menu. Then click on Edit Details.

Upload Static Files

UI

The UI editor in Wizzdi Cloud, currently under development, is designed as a point-and-click interface for generating and building client-side apps. Under the hood,  Google Flutter code is generated.

  1. Point-and-Click Interface: The UI editor aims to provide a user-friendly interface where users can design their app’s interface through simple point-and-click actions. This approach is intended to simplify the UI design process, making it more accessible, especially for those who may not be proficient in coding.
  2. Google Flutter Code Generation: The editor specifically focuses on generating code for Google Flutter, an open-source UI software development kit created by Google. Flutter is known for its ability to build natively compiled mobile, web, and desktop applications from a single codebase. By generating Flutter code, the UI editor will enable the creation of versatile and high-performance applications. Notably, mobile apps are generated for both iOS and Android.
  3. Mobile and Web App Creation: Once operational, the UI editor will allow users to create mobile and web applications. This is particularly significant given Flutter’s cross-platform capabilities, meaning the same application can be deployed on various platforms with minimal adjustments.
  4. Integration with the Server App: The apps created using this UI editor are tailored to interact with the server app built on Wizzdi Cloud. This means that users can design custom front-end interfaces that seamlessly connect and communicate with their back-end server applications, providing a complete solution for app development.

In summary, the upcoming UI editor in Wizzdi Cloud represents a significant advancement in the app development process. By enabling the creation of mobile and web apps through a user-friendly interface and generating Google Flutter code, it promises to streamline the development process, enhance productivity, and facilitate applications’ rapid prototyping and iteration. This tool will be particularly valuable for creating front-end interfaces fully integrated with server applications built on Wizzdi Cloud.

Integrations

Introduction

In Wizzdi Cloud, integrations are extensions used within the Flow User Interface to add specific functions to applications.

Currently, we have four integrations available:

Kafka

Kafka: A distributed event streaming platform used to publish, subscribe to, store, and process streams of records in a fault-tolerant way.

MinIo

Minio: An object storage solution that provides APIs for storing and retrieving data, often used as a private or cloud-based storage service. Minio API is compatible with Amazon S3.

MQTT

MQTT is a lightweight messaging protocol for small sensors and mobile devices optimized for high-latency or unreliable networks.

WebSocket

Websocket: A protocol providing bi-directional, real-time communication channels between a client and a server.

Adding an Integration

To add an integration to your App, follow these steps:

  • Click on Integrations

  • Click on the Add button to add the corresponding integration.

 

Properties

What are Properties?

In Spring and Flexicore Boot, properties are key-value pairs used to customize and configure various aspects of the application. These can include database settings, server configurations, custom variables, and more.

For example, the admin username and password properties define how the deployed App (the backend) can be accessed for administration, such as creating new app users.

The values of properties are in effect only when the App is deployed.

Business flows and code can access properties to control how the App behaves.

Accessing the Properties

Access the App properties from the left menu, then click ‘Manage.’

Sensitive Properties

Some properties are critical for system operation (when deployed) and never change if deployed on Wizzdi Cloud.

You may change these properties if you are sure about the change.

Managing Properties

Properties can be added from the ‘Add Property‘ button.

Add new property

The create property dialog

Select an existing property or create a new one

 

Create a new property.

You can select an existing property, for example, admin.username, or create a new one; if you click ‘Create New Property, ‘you will see:

New property dialog

Select the required type for the property. Property types are limited to Java Basic Types.

Search for type

Setting property name

Set the property name, which is often in a dot notation. The first part may be the property group, while the second can be the specific property name.

Setting Property Value

If an existing property is selected or when a new one is created, you can set the value now or edit it from the properties list at any time.

setting a property value

Editing Properties from the properties list

Click on Edit to change a property value

Setting username and password

Users must sign in to access the OpenAPI and use static files using API endpoints. The initial credentials of the deployed system are set in properties.

  • Check if you can find the admin.username and the admin.password properties in the list of properties, use the search box.
  • If not, add each property.
Add username
Add password

Once a property is added, you can edit its value.

Edit the password property value

Security

SSO (Single Sign On)

The app you build in Wizzdi Cloud may allow the deployed app’s users to sign up using their account for other services such as Google or Apple.

Supported OAuth 2.0 providers

  • Google
  • Apple
  • Facebook
  • LinkedIn
  • Github
  • Custom

 

Set OAuth 2.0 support in the Google Cloud Console

The following section depicts SSO settings for Google accounts. Other SSO providers are not detailed here. More information is available in their respective guides.

Setting up a client on Google OAuth 2.0 when the service is a server (where a secret is required) involves several steps. Here’s a general outline of the process for Google OAuth 2.0 using Google tools.

Note: The following is executed outside Wizzdi Cloud.

For a backend created with Wizzdi Cloud to support Google SSO sign-up, the build backend, that is, the App must register with Google services.

  1. Google Cloud Console:
  2. Enable APIs:
    • In your project dashboard, navigate to the “APIs & Services” > “Dashboard” section.
    • Click on “+ ENABLE APIS AND SERVICES” to enable the necessary APIs for your application (e.g., Google Drive API, Google Sheets API, etc.).
  3. Create Credentials:
    • Go to the “Credentials” page.
    • Click on “Create credentials” and select “OAuth client ID”.
  4. Configure OAuth consent screen:
    • Before creating credentials, you need to configure the OAuth consent screen.
    • Provide the necessary information like the application name, user support email, and developer contact information.
  5. Creating OAuth Client ID:
    • Choose the application type (e.g., Web application, Android, iOS, etc.).
    • Set up the name for the OAuth 2.0 client.
    • Specify the authorized JavaScript origins and redirect URIs for web applications.
  6. Obtain Client ID and Client Secret:
    • Once the OAuth client is created, you will receive a client ID and client secret. These will be used in the App.
    • These are important and should be kept secure and confidential.

For the specific URLs to set up OAuth clients on other platforms like Facebook, GitHub, Apple, and LinkedIn, you can refer to their respective developer documentation:

Setting up an SSO provider in your app

Create SSO provider

Select SSO Provider

Select SSO provider

Select one of the available providers.

Google Selected

You may repeat the process and support multiple providers on your backend.

Fill in the OAuth2.0 fields:

Open the provider for edit:

Fill in the data obtained from the provider management console in the Client ID and Secret fields.

Scopes

In OAuth 2.0, scopes are permissions that define the access level your application has to a user’s data. By specifying scopes, you request authorization to interact with specific types of user information, such as emails or calendars. These scopes are provided as comma-separated values during the authentication process, dictating what data your application can retrieve or actions it can perform on behalf of the user.

Add comma-separated Scope values. In Google OAuth 2.0, these can be any of the scopes here.

For example, if you want to use the user’s email in the App to send emails to the user through SendGrid-consumed API support, you will add email to Google SSO scopes.

For other SSO  providers, use the respective documentation to get the scope list they support.

Use the values obtained from the Auth 2.0 provider for Client ID and Client Secret, and add comma-separated scopes to the Scopes field.

SSO In Deployment

SSO providers’ usage at deployment.

Regardless of where the App is deployed, the client-side user interface should provide the required access buttons for each OAuth 2.0 provider. When building the client user interface without using Wizzdi Cloud User Interface builder, The URL associated with such a button should be constructed as follows:

https://[server URL] oauth2/authorization/[provider name].

where the provider names are Google, Apple, GitHub, LinkedIn, or Facebook. A single one should be selected.

If the App was deployed on Wizdi Customer’s cloud, the URL for Google will be:
https://[app-name].[workspace-name].cluster.wizzdi.com/oauth2/authorization/google

When deploying on Wizzdi Cloud customers’ cloud, you can copy the Swagger URL from the App overview if it was deployed and replace the suffix as follows:

 

Replace swagger-ui.html with  oauth2/authorization/google 

Once this URL is activated, the process is pretty automatic; if this is the first time this provider is used, the user is prompted to approve access to Wizzdi Cloud, and subsequent accesses are transparent.

Note that switching among providers, for example, between Google and Apple, is equivalent to having two different users. Likewise, Do not use any of your emails for standard email password sign-up if this email is associated with any SSO provider.

Permissions

 

Wizzdi Cloud supports defining role configurations inside permission configurations on all three current runtimes (Spring, Flexicore, Flexiocore Boot). This provides Role-based access control to API endpoints.

In addition, the FlexiCore and Flexicore Boot runtimes have a robust security framework emphasizing multi-tenancy and role-based access control (RBAC) for API endpoints and data objects. This security framework is crucial for applications that require stringent data isolation and access control mechanisms, especially in environments serving multiple user groups or tenants. Here’s an expanded view of how this is implemented and managed:

Tenant and Role-Based Access Control

  • Tenant Support: Multi-tenancy is a software architecture principle in which a single instance of the software serves multiple customers or tenants. FlexiCore achieves this through predefined database objects that segregate data by the tenant. This ensures that data is isolated between tenants and that access controls can be enforced at the tenant level.
  • Role-Based Access Control (RBAC): RBAC is a method of restricting system access to authorized users. In FlexiCore, roles are defined to define permissions or access rights. These roles are then assigned to users within a tenant, determining what actions they can perform and what data they can access within the system.

Predefined Database Objects

  • At the initialization of a backend built by Wizzdi Cloud and using any of the two FlexiCore runtimes, a set of predefined database objects related to security (like roles, permissions, and tenant information) are optionally created if so defined in Wizzdi Cloud while developing the App. These objects serve as the foundational elements of the security model, ensuring that the application starts with a basic level of access control and data isolation. For Spring runtime, defined roles and access to API endpoints affect the generated code.

API Endpoints for Security Management:

  • FlexiCore provides multiple API endpoints dedicated to managing these security-related database objects. Administrators can dynamically modify and expand the roles, permissions, and tenant configurations when the app is deployed through these endpoints as the application evolves. This allows for a flexible and responsive security model that can adapt to new requirements or changes in the operational environment.

Web-Based User Interface for Security Objects.

  • When deploying a FelxiCore-based backend, an optional user interface can be added, providing an easy-to-use security objects management console. This user interface makes use of the security-related API endpoints.

Adding and managing permissions

Accessing permissions

The Wizzdi Cloud user interface’s Permissions menu option is the entry point for configuring and managing these foundational security objects.

 

 

The Permission Configuration fields.

Permission Configuration

In the context of Wizzdi Cloud, permission configuration is a critical aspect that dictates access to various components, such as API endpoints and data. This configuration process differs between Spring and FlexiCore runtimes.

In Spring Boot runtime:

  • Permission Configurations are more integrated with the codebase itself. The configurations directly influence the code that is created and executed.
  • There is no API at runtime to manage Roles and permissions.
  • This implies that changes in permission configurations necessitate modifications in Wizzdi Cloud, committing and deploying the App again.

In FlexiCore, both runtimes:

  • Permission configurations define access at two levels: operations (API endpoints) and data.
  • Once the server starts running, any missing configured permissions are instantiated within the database, making them active and enforceable.
  • FlexiCore also provides  API endpoints specifically for managing these permissions. This API allows permissions to be created, modified, or deleted, allowing for dynamic control over access to data and operations.

 Permission Configuration  options

  • Tenant Configurations (Flexicore runtimes Only) create predefined and missing Tenants when the App is deployed.
  • Role Configurations create predefined and missing Roles when the App is deployed.
    Roles are always defined per tenant and present in the database.
    With Spring Boot runtime, as there is no multi-tenancy support, roles are app-wide and present in the generated code, not in the database.
  • Permissions on API endpoints: Access control for each endpoint is delineated by the tenant or role specifications, encompassing three primary modes: Execute Without Security, Anonymous Execution, and Secured Access. The latter, serving as the default mode, permits all authenticated users endpoint access, barring the existence of explicit Permission Configuration.
    Within a Spring framework, such configurations may specify one or multiple roles authorized for endpoint access, denying access to users not associated with these roles.
    In Flexicore runtimes, access control mechanisms are augmented by providing default Tenant behavior and dynamic management through a security API at runtime. This default Tenant behavior introduces tenant-specific access control policies, which are subject to being overridden by role-based permissions.
    In Flexicore run times, as with all other permissions configurations, API access is stored in the database and can be modified on a deployed App through the provided APIs or permission management app.
  • Permissions on Data-Model (Flexicore runtimes only): Access definition for Tenants and Roles to all instances of an Entity; this can be defined in conjunctions with all API endpoints relevant for the entity or just some, for example, cannot create but can view.
  • Exposed Flexicore APIs provide finer granularity at run time when access permissions on all instances are not granular enough.
    Wizzdi’s permission web app can also manage access control to data instances at any granularity.

Note: Flexicore runtimes are based on the Spring Boot framework and provide access to all Spring libraries and services.

 

You may define multiple Permission Configurations. The final behavior at runtime is a combination of all configurations. In most cases, a single configuration is sufficient.

Once the permission configuration is created, the following view is available.

Tenant Configurations (Flexicore Runtimes only)

To create and manage Tenant Configurations, click on Tenants.

The above dialog also appears when managing the existing Permission Configuration.

Create Tenant configuration.

To create a Tenant Configuration, add a name. The tenant is created when the App runs on the server.

Europe Tenant

The view of Tenant Configurations is similar to this one:

Tenant Configurations view

Role Configurations (all runtimes)

 

When using Flexicore runtimes, roles and permissions are configured per tenant, allowing tenant administrators to define roles.

Role Configurations are created within Tenant Configurations. This setup defines the permissions and access levels assignable to users within a tenant’s domain on Wizzdi Cloud.

When FlexiCore runtimes are utilized, role management extends to the server level through API endpoints. This enables the creation or adjustment of roles directly on the application’s target server. The roles available at any given time are predefined through Role Configurations within the Tenant Configurations and those created or modified using the API endpoints. This design allows for managing roles based on immediate needs or changes.

When running a Spring runtime, Tenants are unsupported, and Roles are App-wide.

Create a Role Configuration

Role Configurations, empty view.

Filled Role Configuration.

Create Role Configuration.

Access Rules priority

In systems where permission configurations might conflict, the hierarchy prioritizes permissions assigned to a Role over those set at the Tenant level, allowing role-specific permissions to override tenant-wide defaults.

FlexiCore-runtime-based applications utilize Security API endpoints that allow for precise permission control at the AppUser level. This means permissions or denials assigned to an individual user will override those assigned to the Roles and Tenants with which this user is associated.

This hierarchical approach to permission control ensures that when conflicts arise, the system resolves them by prioritizing user-specific permissions over role-based permissions and role-based permissions over tenant-wide settings.

FlexiCore-based runtimes using the standard API are the only runtimes that can have AppUsers permissions applied at runtime.

Operation Permissions Configuration.

This section applies to pure Spring runtime, Flexicore runtime, and Flexicore Boot runtime.

Permission Configurations for Operations (API endpoints).

Create a Permission Configuration for API endpoints (operations).

Create a Permission Configuration for Operation.

When creating a permission configuration, we define two components. The permission target includes a list of tenants and roles associated with one or more operations.

When a tenant is associated with permission, it defines the default behavior for the included operations for that tenant on a running system.  Tenant administrators may want different system behavior for their users. Some may wish a loose system, while others prefer restricted access by default. When the access is limited at the tenant level, associating with roles is required to open it for some of the tenants‘ users.

It should be noted that this flexibility of changes on a running system is available only with Flexicore runtimes. Changing the permissions on a pure Spring runtime requires changing the App in Wizzdi Cloud and redeploying the App.

Selected Targets in a Permission Configuration.

In the above image, the targets selected are one Role from a Tenant and one Tenant, the America Tenant.

The permission pertains to all users of the Europe Tenant (marked in blue) and only to the Administrator Role (marked in yellow) in the America Tenant.

Select API endpoints for permission configuration.

In the above image, two endpoints have been selected when selecting an endpoint. Either allow or deny may be chosen.

Security On Exposed APIs

 

Available in all runtimes.

The exposed API endpoints have additional settings defining their behavior and the permissions related to them.

Accessing the security settings on an Exposed API endpoint.
Select The Target, Role, or Tenant.

When setting security directly on the Endpoint, The following options are available:

  • Execute without Security: At runtime, the user must be signed in to access the endpoint, and no other security restrictions are applied.
  • Anonymous Execution: Anyone can execute this endpoint at runtime. For example, a sign-in/sign-up endpoint must be accessible to all.
  • Restricted execution: when none of the above two options is selected, the following section applies.

 

Select Security Options on an API endpoint.

When configuring the access to an endpoint, we first need to select Tenants or Roles. 

Then click on the ‘+’ sign to add a Tenant Permission Configuration or a Roles Permission Configuration.

Creating or selecting a Permission Configuration.

When Adding a Role/Tenant Configuration, you can select an existing Permission configuration or create a new one.

Selecting the Tenant.

Selecting a Tenant Configuration for the endpoint.

Adding a Role Permission Configuration or Tenant Permission Configuration may be repeated. A summary of all such configurations created so far is available.

Tenants/Roles Permission Configurations summary.

Permissions on Data

Important Note:

Support for data access control in Wizddi Cloud is available for FlexiCore and FlexiCore Boot runtimes only. Furthermore, all entities must directly or indirectly extend the Flexicore-defined entity SecuredBasic.

 

As in this domain model, Book and Author both extend the SecuredBasic entity.

Entities extend SecuredBasic.

 

Model-Level Permissions

  • Design Phase on Wizzdi Cloud: Model-level permissions can be established during the application’s design phase. These permissions define access controls for entities within the application’s model, setting broad access rights for Roles or Tenants to all records of a particular entity.
  • Runtime: Model-level permissions can be modified and created at runtime using the provided API.

Instance-Level Permissions

  • Runtime only: Instance-level permissions are specific to the runtime environment and are applied to individual data records within the application. These permissions allow for granular control over access to particular data instances.
  • Instances Groups: The run time instance-level access control includes the concept of Instance Group, where a heterogenous collection of instances can be subject to permissions as a whole.
  • Supported by API endpoints: Instance-level permission management is available only at runtime using the provided API endpoints and only for Flexicore and Flexicore Boot.

Model-level permissions, the details.

Data permissions, no permissions yet.

Click on Create Data Permissions.

Create a model-level data permission.

In the above dialog, you must set the Target, a list of Roles and/or Tenants, the Subject, the entities for this permission, and the operation. The API endpoint you want to associate the permission with.

The Data Permission filled.

Multiple targets, Entities, and Operations can be included in a single Data Permission Configuration.

Multiple Targets, Entities, and Operations in one Permission Configuration

In the above screenshot, targets, Tenants, and Roles are marked yellow, Entities from the data model are marked blue, and operations and API endpoints are marked green.

When Add Permissions is clicked, a list of permissions generated from the above is displayed.

Partial view of permissions created.

Applying Data Model Security From Domain Model Editor.

Note: When an app is developed using Wizzdi Cloud, the structure and properties of its entities (such as data models or object types) are predefined. However, the actual data instances (or records) corresponding to these entities are generated only when the app is deployed and used in a live environment. Consequently, security measures related to the entities can be implemented during the app’s design phase within Wizzdi Cloud.

In addition to these design-time security configurations, Flexicore runtimes also support applying dynamic access control measures at runtime through its system APIs. These APIs can be used to apply both Entity-level and instance-level access rules.

 

When an Entity is selected in a domain model diagram, and the runtime is one of Flexicore’s runtimes, the ‘Manage Security‘ button is available.

Manage the Security of an Entity.

 

When managing an Entity’s security, Derived Security or direct Security settings can be selected. In derived security, the Entity’s security becomes the same as that of a related Entity; see below.

Entity Security Settings (direct)

The Entity Security setting is defined for this Entity, for example, if a Role can operate on all Entity instances. Finer-grained access control on specific instances or a group of instances (Permission Groups) is available only at runtime.

To add an Entity Security permission, click the ‘+’ sign after you select Tenants or Roles.

When ‘Tenants‘ is selected, the entity permission created defines the default behavior in this tenant.

Data-model permissions

You have the option to create a new Permission Configuration or to use an existing one.

Select an Existing Permission Configuration or Create a new one.

 

Define the default Tenant-wide permission on an Entity.

 

Derived Security

Derived security means that the access permissions assigned to a particular entity automatically affect the access permissions of other entities linked to it through a derived security relationship. This relationship is defined based on the data model’s structure, where entities are associated through a one-to-many relationship.

 

How Derived Security Works

  • Defining Access Rights on a Primary Entity: When access rights are granted or denied to an entity (the primary entity), these permissions are considered when determining access to other entities associated with the primary entity in the context of derived security.
  • Associated Entities’ Access Rights: Entities with the primary entity associated with derived security inherit the access rights from that primary entity. If an entity is configured to derive its security from another entity, any access rights defined for the primary entity will similarly affect the derived entity. Data model security can be configured on Wizzdi Cloud and managed through the provided APIs.
  • Influence on Associated instances: Entity instances of an Entity defined with a derived security get access rights from the associated instances of the Primary Entity defined in the derived security. Instance-level access control can only be managed through the provided API endpoints in runtime. A web app for managing access rights is available.

Example Scenario: Entity Association

Consider a scenario with three entities: Project, Task, and User. If the Task entity is associated with the Project entity in such a way that its access rights are derived from the Project, and a user has restricted access to a specific Project, then by the principle of derived security, the user will also have restricted access to the Tasks associated with that Project. Similarly, if a User entity’s access to projects is defined through derived security, the user’s permissions on the Project entity would affect their access to related entities.

Configuration and Implementation

  • Data-Model Configuration: In the data model, entities must be explicitly configured to utilize derived security, specifying which fields or relationships govern the derived permissions. This setup involves identifying the paths through which security settings are inherited.
  • Runtime Behavior: At runtime, the application evaluates the derived security configurations to dynamically apply the appropriate access permissions across entities based on the established relationships and inherited rights. This evaluation ensures that the access control logic remains consistent with the data model’s structure and the intended security policies.

Registration

Users registering to your backend may be associated with a default Role. To set the default role, select one of the predefined Role Configurations.

Admin User

Define the user having full rights on permissions in the system. When using Spring runtime, this user can access all the exposed endpoints.

Permissions Web App

In Flexicore Runtime, in addition to having open access to all exposed endpoints, this user can manage permissions, tenants, roles, and users via the available web app.

Below are some screenshots of the Web App. Solution providers can use the Web App or create a user interface based on the exposed API.

 

Tenants management.

 

Roles management.

 

Users management. Tenant and Role associations are displayed.
Permissions management for both operations and data.

 

An instance-group management.

The above screenshot depicts a single instance-group management. An instance group groups multiple instances so that permissions to the entire group can be easily managed.

Not shown here is the Operation-Group management, which allows concise permission management on multiple operations.

The above screenshots are not full and are presented here just to help you understand the permissions management web app.

 

 

Workspaces

In Wizzdi Cloud, “Workspaces” are a key organizational feature. Think of a Workspace like a virtual room or office space on the cloud where you can gather different applications that serve a common purpose or are used by a specific team. This arrangement helps keep related apps together, making them easier to manage and access.

The concept of Workspaces is also very beneficial for teamwork and collaboration. You can invite others, such as team members, clients, or stakeholders, to work together within a Workspace. Each person you invite can access the apps within that Workspace.

One important aspect of this system is controlling who gets to see or do what within the Workspace. This is managed through “access rights” or permissions. For instance, you might allow team members to edit and update Apps while clients can only view the information. This ensures that sensitive data or functionalities are only accessible to those who need them, maintaining security and efficiency in collaboration.

In summary, Workspaces in Wizzdi Cloud help organize your applications, foster collaboration among different users, and provide a controlled environment where access rights ensure security and proper management of resource

The first workspace

The first workspace is created when you sign up for Wizzdi Cloud. Once you are signed in, you can see this workspace here:

The first workspace

Every new app you create is placed in the current workspace; if you have not created new workspaces, they will be in the first workspace created for you.

Create a new workspace.

Create a new workspace and search for an existing workspace.
Create a new workspace.

Click on ‘+ New Workspace’ to create a new workspace. Add a name and description.

Select a different workspace.

Select a different workspace.

You can switch to a different workspace by clicking on it, and the small checkmark on the right designates the current workspace.

Manage a workspace.

To manage A workspace, click on the ‘settings’ button next to it.

Manage a workspace

 

Access edit details

 

Edit details

In edit details, you can change the name and description of the workspace.

Manage workspace users

When inside the workspace settings, click ‘users’ to see a list of the workspace users. You can use the search area to search for a user by name.

The workspace users’ list

Adding a user to a workspace

Adding users is carried out by inviting them.

Click ‘Invite user’ to open the invitation dialog.

Invite a user to a workspace.

While inviting the user, click on the ‘+’ sign at the left of a user group to add the user to that group.

The invited user receives an email in the following format:

Invitation email.

If the user has never signed in to Wizzdi Cloud, he or she can do it once the invitation is accepted, using the same email used to invite them.

Once logged in, they should see the following dialog inside Wizzdi Cloud.

Invitation inside Wizzdi Cloud

Once the invitee accepts the invitation, the workspace is listed inside the invitee’s own workspaces list.

New workspace inside the invitee list

User groups

While managing a workspace, you can manage user groups. By default, each Workspace has three built-in groups.

Viewers, administrators, editors.

Reusability in Wizzdi Cloud

Reusability in Wizzdi Cloud focuses on maximizing the efficiency and utility of applications (Apps) within its ecosystem. This concept is implemented through several key features:

  1. Inter-app Dependencies within the Same Workspace:
    • In Wizzdi Cloud, Apps within the same workspace can be designed to depend on each other. This means an App can utilize functionalities or data from another App within the same environment. This interconnectivity enhances reusability by allowing developers to build modular applications where common functionalities are reused rather than duplicated across multiple Apps.
  2. Publishing Apps to Marketplaces:
    • Wizzdi Cloud allows developers to publish their Apps to marketplaces. This feature opens up opportunities for wider usage and collaboration. Other users can be invited to these marketplaces to discover their apps, use them, or extend their functionalities. This fosters a community of sharing and collaboration and encourages the development of versatile and robust applications.
  3. Cloning Apps to Personal Workspaces:
    • When an App is available in a marketplace, other users can clone it to their workspaces. This cloning process allows users to take a pre-existing App and adapt or modify it according to their specific needs. This ability to customize and build upon existing Apps significantly reduces development time and effort, promoting a more efficient development process.
  4. Using the Wizzdi Public Marketplace
    • The Wizzdi public marketplace functions similarly, enabling users to access a wide range of Apps developed by others. This marketplace acts as a central hub where users can find Apps that suit their needs, contributing to the culture of reusability and collaboration.
  5. Adding Code Dependencies and Service Calls:
    • Wizzdi Cloud supports the integration of code dependencies from repositories like Maven. This allows developers to easily incorporate existing libraries and frameworks into their Apps, leveraging a vast ecosystem of pre-built code. Furthermore, business flows within Wizzdi can include Call Method Activities, which enable Apps to call services or methods from these referenced libraries.

In summary, reusability in Wizzdi Cloud is achieved through inter-app dependencies within a shared workspace, the ability to publish and clone Apps via marketplaces, and the integration of external code dependencies and service calls. This approach streamlines the app development process and fosters a collaborative environment where resources and expertise are shared across the Wizzdi community.

Reusing Apps in A Workspace

Introduction

When constructing multiple applications within a single workspace, it’s possible to establish interdependencies among them. This hierarchical dependency allows any given application (the dependent) to access and utilize the objects and services of another application (the depend-on).

This setup enables the dependent application to extend and reference entities from the depend-on application and employ its workflows and custom queries. Such an arrangement fosters a modular and integrated system where each application enhances the capabilities of others.

Upon deployment, the dependent application makes its APIs and those of the depend-on application available. This unified exposure of APIs ensures seamless integration and interaction between the different applications within the workspace, enhancing overall functionality and user experience.

An Example

In the same workspace, a Territories App defines a few entities such as Address, City, Country, Street, and State, and an Organization app that we want to be dependent on Territories.

Neither app does much beyond the basic CRUD operation, exposing these API endpoints.

The Territories Domain Model

Territories domain model

Note a ParentEntity has been defined, and all other entities extend it to have the id, name, description,creationDate, and updateDate.

Once the Territories app is committed successfully, it can be referenced in other Apps from the same workspace.

In the Organizations  App, access the dependencies menu.

Dependencies
Select the desired project and version

Once the depend-on (referenced) project is added to project dependencies, it can be used in the project tools.

In the images below, we reuse entities from the Territories App.

Import an external entity from a referenced project.
Search for the ParentEntity defined in Territories.
ParentEntity Imported.

The Organization and Branch entities were created and extended by the ParentEntity and interlinked to reflect the required domain model.

In the image below, entities circumvented by a green rectangle were created in the Organization App, whereas those circumvented by blue rectangles are imported from a referenced project, Territories.

 

My Marketplaces

As noted, dependencies can be created among Apps in the same Workspace. To access Apps among multiple workspaces, you need to publish the App you need to reference to a marketplace and then clone it from there.

Marketplace can be looked at as a special kind of a Workspace.

Manging Marketplaces.

To manage your marketplaces, access them from here:

Manage my marketplaces.

Marketplaces are a special type of workspace; thus, invitations and permissions can be managed from the standard Workspaces management in the Wizzdi cloud.

Once an App is published to a marketplace, invitees to that marketplace can clone the app and add it as a dependency to an existing or new App.

Publishing to a Marketplace

Publish to marketplace from App overview.
Start the publishing process.

To publish an App.

  • Click on Overview.
  • Click on publish to a Marketplace.
  • Select a MarketPlace.
  • Select a version to publish; it must be a committed version, not the last one. And it must not have already been published in the same marketplace.
  • You can publish the same App to multiple marketplaces.

Once the app is published to a MarketPlace, it can be viewed in the Marketplace and imported to a personal workspace of choice.

The published App in the marketplace.

 

Marketplace

This is the single public marketplace provided by the Wizzdi software system containing full projects, samples, and projects you can build upon. Cloning from the Marketplace is identical to cloning from any of your Marketplaces.

Repositories

Binary code repositories are essential tools in software development. They serve as storage and management systems for binary files, including compiled software versions, libraries, and dependencies. Maven Central is one of the most well-known public repositories, primarily serving the Java community. It hosts a vast array of Java libraries and components, allowing developers to integrate and manage dependencies in their Java projects easily.

However, in many scenarios, particularly in corporate environments, there’s a need for private repositories. These private repositories store proprietary code, customized libraries, or binaries not meant for public release. They offer several advantages:

  1. Security and Control: Private repositories ensure that sensitive code is not exposed to the public, reducing the risk of security breaches. Companies have full control over who can access and contribute to these repositories.
  2. Customization: Organizations can host specialized libraries or binaries tailored to their specific requirements, which may not be relevant or available in public repositories.
  3. Integration with Internal Systems: Private repositories can be integrated with internal development, build, and deployment tools, creating a seamless workflow.
  4. Compliance and Governance: In industries with strict compliance requirements, private repositories help maintain the necessary standards by controlling the versions and origins of the software components used.

Setting up a private repository can be achieved using various tools and products. JFrog, for instance, offers a range of solutions in this space. Some of their products, like Artifactory, can be used to set up private repositories. These free and paid versions cater to different scales and requirements.

Artifactory is a universal repository manager that supports various package formats, not limited to Java. It can manage NPM for Node.js, NuGet for .NET, Docker images, and many more, making it a versatile choice for multi-technology environments.

The process of setting up a private repository typically involves:

  • Installation and Configuration: Installing the repository management software on a server or in the cloud and configuring it according to the organization’s requirements.
  • User Management: Setting up user accounts and access controls to manage who can access the repository.
  • Integration: Integrating the repository with tools such as continuous integration/continuous deployment (CI/CD) pipelines, source control systems, and build tools.
  • Maintenance: Regularly update the repository to ensure it runs smoothly and securely.

In summary, while public repositories like Maven Central are invaluable for open-source components, private repositories are crucial for managing proprietary, sensitive, or custom software components. Tools like JFrog Artifactory offer flexible solutions to set up and manage these repositories, ensuring security, compliance, and efficiency in software development processes.

Add a repository

Manage repositories

 Repository Details.

Edit new repository

Name: The repository name

Description: A description of the repository.

URL: the URL for the repository on the public Internet.

Username: the defined username on the repository.

Password: the password to access the repository.

Keys: Search for the private keys needed to access the repository in case the repository is accessed with private keys.

Manage Keys

Keys for your repositories are managed on the keys tab.

keys management

Add keys

Add a new key

If you’re not using the contract first approach, then this step is the very first and mandatory one. Once your domain model is ready, you can commit and deploy your app. After deployment, the back end of your app will include the exposed API endpoints that allow you to manage the entities in the domain model.If you’re not using the contract first approach, then this step is the very first and mandatory one. Once your domain model is ready, you can commit and deploy your app. After deployment, the back end of your app will include the exposed API endpoints that allow you to manage the entities in the domain model.If you’re not using the contract first approach, then this step is the very first and mandatory one. Once your domain model is ready, you can commit and deploy your app. After deployment, the back end of your app will include the exposed API endpoints that allow you to manage the entities in the domain model.If you’re not using the contract first approach, then this step is the very first and mandatory one. Once your domain model is ready, you can commit and deploy your app. After deployment, the back end of your app will include the exposed API endpoints that allow you to manage the entities in the domain model.