skip to main content

Flutter Developers Contest

Backend setup guide

This guide is intended for developers participating in the Flutter Dev Contest 2023 Edition.

The guide contains step-by-step instructions to build, deploy and test the backend of the app to be submitted, including a ready-to-use Livebase engine model as a starting point, and a compatible dataset for testing.

Ready to start? It should take less than an hour. Feel free to contact us at support@livebase.com if you need help.

Banner

1. Get on board the Livebase platform #

Since the backend application has to be developed on the Livebase platform, you’ll have to first create an account and setup the modeling environment on a Cloudlet. The next steps will guide you through the account activation process.

1.1 Create a free evaluation account #

Go to the Request a free evaluation account

page on our website (under the Dev Resources menu). The form shown on the right will appear in your browser. Fill in the form and press the Send request button.

Request free developer account

Shortly after, you will receive a confirmation email similar to the one shown beside. The email will include as attachments the terms and conditions for using the Livebase platform.

Click on the link to navigate to the account activation page.

Confirmation message

On the account activation page, fill in the form and press the Activate account button.

Request free developer account

If the account activation is successful, the message shown beside will be displayed.

Account activation completed

1.2 Install the Dashboard #

Select your operating system, then click on the corresponding download link and follow the installation procedure:

1.3 Log into the Dashboard #

Launch the Dashboard and then log in using your credentials.

Dashboard login

The Dashboard is a desktop client connected to the Livebase Cloud Services, providing a user interface to control and operate all other components of the Livebase platform. This light-weight control panel allows developers to create and manage their Cloudlets across their entire lifecycle (creation, start/stop and deletion).

Once logged in, the Dashboard appears as shown:

  • the Engine models tab (on the left) contains a versioned repository named Library, that you can use to archive, retrieve and reuse your engine models.

  • the Cloudlets tab (on the right) allows you to manage all your Cloudlets. The tab contains a control panel for each Cloudlet.

Dashboard Livebase

2. Use Livebase to create the backend of your Flutter app #

2.1 Create a Cloudlet #

Cloudlets are headless server components providing advanced (business-level) transactional data services via a secure GraphQL API. Cloudlets are generated and deployed by Livebase starting from high-level conceptual models (engine models) without coding.

To create your first Cloudlet, click on the + New cloudlet button at the bottom right of the Cloudlets tab. The creation process will take about five minutes. A panel will then appear in the Cloudlets section of the Dashboard, allowing you to manage the Cloudlet you’ve just created.

Create Cloudlet

A Cloudlet panel is divided into three sections:

  • the top section displays the name and the URL address of the Cloudlet;

  • the middle section displays three icons that provide information and access to the key components of the Cloudlet, namely the list of its members (i.e. the users allowed to invoke the Cloudlet API), the engine and the database.

  • the bottom section displays the status of the Cloudlet (e.g. Running or Stopped). At the moment, you cannot start your Cloudlet because it has no engine yet, and therefore the Cloudlet status is Cannot start (missing engine). By clicking on the icon, a drop-down menu appears, giving you access to the Cloudlet settings and commands.

New Cloudlet

Rename the Cloudlet as Meetings-Registry by double-clicking on its name. You can also click on the menu icon and select the Rename command.

Rename Cloudlet

2.2 Jump-start the Cloudlet configuration with an engine model provided by us #

Press the + New engine model button in the bottom right corner of the Engine models tab. A new (empty) engine model will appear in the Library.

Create new engine

Open the newly created engine model by clicking on its icon: the Designer (the modeling environment of the Livebase platform) will pop up in a dedicated window, showing an empty canvas.

At this point, you would be normally required to draw you engine model. For the sake of this contest, however, you can download a preconfigured
engine model (Meetings_Registry.xml) and import it into the Designer using the Import XML... command under the File menu.

Import engine model

Save your engine model (now version number 2.0.0) and close the Designer.

Save engine model

Rename the engine model as Meetings_Registry by double-clicking on its name.

Rename engine model

It’s now time to turn the engine model you’ve just stored in the Library into an actual engine installed into the Cloudlet. This can be easily be archived by dragging the engine model icon from the Library onto the Cloudlet panel; the header of the Cloudlet panel will light up (as shown in the image beside) to notify that you’re allowed to drop the icon.

Import engine

The Cloudlet panel with the engine installed will look as shown in the image beside.

The Cloudlet is now ready to start although a database is still missing (as shown by the status line at the bottom of the Cloudlet panel); in fact, an empty database is created automatically the first time a Cloudlet is started.

Before starting the Cloudlet, however, please go through the following section to take a closer look at the engine you’ve just installed.

engine imported

2.3 Take a closer look at the engine just installed on your Cloudlet #

Understanding the basics of the engine you’ve just installed on your Cloudlet is essential to properly invoke its GraphQL API.

Click on the icon inside the Cloudlet panel. The Designer will pop up and show the model of the engine installed on the Cloudlet.

open engine from Cloudlet

The engine consists of a single diagram drawn on three types of layers named schemas. Each schema defines a different aspect of the GraphQL engine, like a thematic layer for a geographical map.

  • On the left are two tabs: Schemas and Classes; the former collects the model views, while the latter lists the classes;
  • On the right is the canvas, with a tab for each diagram and a special tab for notes.

The Designer

2.4 Upload some test data to your Cloudlet #

Close the Designer and return on the Dashboard.
With an engine installed, your Cloudlet is now ready to start; in fact, an empty database with a engine-compatible structure is created automatically when the Cloudlet is started for the first time.

In order to let you perform some significant queries on the Cloudlet GraphQL API, however, we have prepared a dump of an already populated database, that you can easily upload.

Download Meetings_registry_data.sql and drag it onto the Cloudlet panel. Once the header lights up, drop the file inside the Cloudlet panel area.

Drag and drop database

The database uploaded is automatically checked to detect any compatibility issues with engine installed. This process will take a few seconds.

Importing database

Once the upload is complete, your Cloudlet will look as shown in the image beside.

Imported database

2.5 Create an end user for the Cloudlet #

In order to test the GraphQL API of your Cloudlet you need to authenticate as a valid end user.

Beside configuring the Cloudlet to connect an existing Single-Sign-On (SSO) Keyclock instance, you can also create local end user accounts, conventionally named Members of the Cloudlet, as shown in the image beside.

To create a new member for your Cloudlet, open the Members of the Cloudlet dialog by clicking on the icon in the Cloudlet panel, then click on the Create Member button.

Create a new member of the Cloudlet

Each member has a unique username and a password (credentials) that can be used to authenticate on the Cloudlet’s GraphQL API.

Fill in the member creation form, select Administrator from the profile dropdown menu and tick the Admin checkbox. Finally, press the OK button to confirm.

Create new member

2.6 Start the Cloudlet and test its GraphQL API #

From the Dashboard, click the Start button on the Cloudlet panel.

Start Cloudlet

Please wait about five minutes while the Cloudlet is built and deployed. The Cloudlet panel will show a log of the operations performed during the process.

Building Cloudlet

At the end of the build/deploy process, the Cloudlet will be in the Running state, as highlighted in the status line in the bottom left corner of the panel.

Cloudlet running

To connect the Cloudlet API programmatically (from your own client application or from a generic GraphQL console), you need to know its endpoints.

Click the GraphQL icon at the top right corner of the Cloudlet panel to open a list of all its API endpoints (just one in your case).

Access endpoints

GraphiQL is a widely used open-source console for GraphQL APIs. By clicking on the URL at the top of the Cloudlet panel you can launch an instance of GraphiQL already connected to the Cloudlet, ready to execute GraphQL queries.

Authenticate using the credentials of the member created previously, and you’re all set to test the sample GraphQL queries described in the following sections.

Open GraphiQL

To execute any of the sample queries described below, copy the GraphQL code into the left panel of the GraphiQL console as shown in the image beside, then press the play button.

GraphiQL client

This simple query retrieves a list of all customers.

Copy the GraphQL query on the right and paste it into the GraphiQL console and press the play button at the top of the console.


query ALL_CUSTOMERS {
  Customer___getPage {
    items {
      name
    }
  }
}

This query retrieves a list of all projects. For each project, it retrieves name, customer and the list of all the meeting held for that project. For each these meetings it also retrieves the date and the list of the employees who attended.

Copy the GraphQL query on the right and paste it into the GraphiQL console and press the play button at the top of the console.


query ALL_PROJECTS_AND_THEIR_MEETINGS {
  Project___getPage {
    items {
      name
      meetings_ {
        items {
          date
          employees_attending_ {items {full_name}}
        }
      }
    }
  }
}

3. Update the backend to support additional requirements #

Let’s now refine the Cloudlet engine in order to meet the additional requirements specified in last section of the app requirements page.

Stop the Cloudlet and open the Designer by clicking on the engine icon on the Cloudlet panel.

Stop the Cloudlet

3.1 Calculate the total meeting effort spent on all the projects of a given customer #

In this section we modify the model of the Cloudlet’s engine in order to satisfy the following additional requirement:

When showing the details of a customer, the app must calculate and show the cumulated meeting effort (man/hours) spent by the company for all the projects commissioned by that customer.

With Livebase, the requirement can be easily satisfied by adding a derived attribute to the Customer class in the engine model, and by configuring such derived attribute with a query expression that sums the efforts of all the meetings held for projects commissioned by a customer.

By doing so, whenever requested to retrieve a customer from the database, the Cloudlet’s GraphQL API will transparently calculate the value of the new derived attribute and will return it as if it had actually read it from the database.

Customer class

The Livebase Designer allows you to define the query expression of a derived attribute either manually or interactively. The latter one is definitely faster and more intuitive: just drag the /effort attribute (which is also derived, by the way) from the Meeting class, and drop it onto the Customer class.

As soon as you release the /effort attribute on the Meeting class, a contextual dropdown menu appears; select the Link here option.

Query expression editor

In the Query expression path selector that appears immediately after, you can choose the right path for the query expression of the new derived attribute, which in this case is clearly the third one: Customer.projects_.meetings_.effort.

Query expression editor

In the Query expression editor that will then pop up, select the SUM - Sum aggregation function from the dropdown menu as shown beside, then press the OK button to confirm.

Rename the newly created attribute as total_meeting_effort. Since this is a derived attribute, Livebase automatically adds the / prefix to its name.

Query expression editor

By selecting /total_meeting_effort on the Customer class, you can double-check the path of its query. The source attribute (/effort on the Meeting class) is circled in red.

total_meeting_effort

3.2 Prevent archiving contacts still involved in active projects #

In this section we modify the model of the Cloudlet’s engine in order to satisfy the following additional requirement:

When modifying a contact, the app must show a warning and refuse to save the changes if the contact has been marked as archived while it’s still referred as primary contact by one or more active projects (i.e. the contact can be saved as archived only if all projects referring to it as their primary contact are not active).

In order to support this requirement, you can modify the engine model in two steps:

  1. on the Database schema, add to the Contact class a new derived attribute named has_active_projects, whose expression evaluates true if a contact is involved in one or more active projects;

  2. on the Application schema, add to the Contact class a Class warnings that prevents saving or updating a contact if both its attributes is_archived and has_active_projects evaluate true.

Each of the two above-mentioned steps are detailed hereunder.

Contact class

Drag the is_active attribute from the Project class and drop it onto the Contact class, then select the Link here option from the contextual dropdown menu.

Query expression editor

In the Query expression path selector that appears immediately after, select the right path, which in this case is the first one: Contact.projects_managed_.is_active.

Query expression editor

In the Query expression editor that will then pop up, select the OR - Logical OR aggregation function from the dropdown menu as shown beside, then press the OK button to confirm.

Rename the newly created attribute as has_active_projects. Since this a derived attribute, Livebase automatically adds the / prefix to its name.

Query expression editor

By selecting /has_active_projects on the Contact class, you can double-check the path of its query. The source attribute (is_active on the Project class) is circled in red.

has_active_projects

Select Application in the Schemas tab on the left side of the Designer. The diagram will now appear with all the active modeling elements colored in yellow, as shown in the image beside.

has_active_projects

Right-click on the Contact class to open its Class menu and select the Set warnings... option.

Set warning for Contact

The Class warnings manager will appear, allowing you to manage all the warnings defined for this class. Click on the Add button to create a new Class warning.

Class warnings manager empty

In the Class warning editor, shown on the right, type is_archived && has_active_projects as the condition that will raise the warning and tick the Save New and Save Existing checkboxes in the Evaluated on section of the panel.

Set warning for Contact

In the Class warning edito Replace the default message with a more informative one (like the one shown beside), and tick the Block action when message is displayed checkbox.

Finally, rename the Class warning with an explanatory identifier (e.g.“Cannot_archive_contacts_still_working_on_active_projects”) and press the OK button to confirm.

Set message error

If you followed the previous steps correctly, the new Class warning will be listed in the Class warnings manager, as shown in the image beside.

Class warnings manager end result

3.3 Restart the Cloudlet #

Close the Designer and return to the Dashboard, then click on the Start button on the Cloudlet panel.

Restart the Cloudlet

4 Test the updated backend #

4.1 Retrieve the total meeting effort of each customer #

This query retrieves, for each customer, the /total_meeting_effort derived attribute that we have just added to the engine model.


query ALL_CUSTOMERS {
  Customer___getPage {
    items {
      name
      total_meeting_effort
    }
  }
}

4.2 Retrieve all customers and their active contacts #

This query retrieves a list of all customers and their active contacts (i.e. contacts who are primary for at least one active project).


query ALL_CUSTOMERS_AND_THEIR_ACTIVE_CONTACTS {
  Customer___getPage {
    items {
      name
      contacts_(options: {filter: {is_archived___eq: false}}){
        items {
          _id
          full_name
          has_active_projects
        }
      }
    }
  }
}

4.3 Try to archive a contact with active projects #

This mutation checks the enforcement of the last additional requirement. We pick the _id of one of the contacts that is referred to as primary by an active project, and try to mark it as archived. If you followed the steps of this guide correctly up until this point, the mutation should fail, triggering the Class warning we defined in section 3.2 on the Contact class.

mutation ARCHIVE_CONTACT {
  Customer___update(data: {_id: 11304, contacts_:
    {update: {_id: 11309, is_archived: true}}}) {
    contacts_ {
      items {
        _id
        full_name
        is_archived
      }
    }
  }
}