Hidden power of the Mendix Model SDK

Hidden power of the Mendix Model SDK

--

Although the Mendix SDK has existed for many years, you don’t hear about it often. This is most likely because you don’t need it for most of your web and mobile app development, and can sometimes be considered as more of an optional addition to the platform for new users.

Starting to utilise it often scares new users on the platform, because interacting with it can be fairly technical and challenging. After all, Mendix is typically focused on Low-Code users and not the typical High-Coders who are used to solving problems programmatically.

Simply crossing the first hurdle - setting up your project development environment, unlocks a world of benefits which are ready and waiting to be applied. So come with me and unlock the hidden power of the Mendix Model SDK in your apps today.

What are these benefits? Lets’s have a look at some common examples:

· Automating all kinds of manual tasks

· Automating batch and mass changes in your Mendix model

· Exporting documentation from your meta-model, for example text in the description and documentation of your model

· Extracting model information to another framework

· Extracting model information to analyse meta data, listing and ranking apps in your organisation

· Importing legacy code into your Mendix app

You can read up on some other typical use-cases here.

In this blog I want to explain and share one such use case that has helped me personally: preventing many hours of manual actions on a large Mendix model, an app with a long development history and thus also slower reaction time in Studio Pro.

Automatically changing hundreds of pages in Mendix

One of our multi-tenant Mendix apps has around 8300 microflows and 1500 pages, some of these are quite old: this project has existed since Mendix v2 and during the years constantly migrated, now in Studio Pro 8.18 (the LTS at this time). Although the project has been migrated and updated, there were still hundreds of pages based on old-style table layouts. Technical debt on parts of our Mendix model that haven’t changed for years. All the newer and changed parts are built in pages with layouts, without the old ugly tables :)

So, why did we make the effort of automating this and not manually changing all those pages and rebuilding them to the new layout style? There are a few reasons we chose this approach:

1. Why not? Literally every step is the same, copy and pasting attributes of entities on a standard and predictable place in the page. This is perfectly automate-able, with less errors and also with a more standardised output. Of course there are some exceptions- edge cases and situations you will need to address. But isn’t that the same as in so many other aspects of software development?

2. Manually changing every page is very repetitive (and kinda boring 🤷). You don’t want to bore your Mendix Makers with such drudgery and spend precious development time on this.

3. Lead time: writing a SDK script was estimated as quicker than manually updating all the outdated pages. Although we faced some issues with starting up and had to adjust for the learning curve, still it was simple math - a few hours spent automating was faster than refactoring manually. Because this app is so enormous, even opening a single page in Studio Pro can take a couple of seconds. Imaging the time involved in manually stepping through this process as a human.

4. Opportunity: experimenting with the SDK and solving a real world problem gave us a chance to learn. A use-case worth the time spent on researching the SDK API for an automated solutions. Not every use-case is suitable and sometimes you definitely need a human person making decisions.

5. Fun and educational: doing this was a lot of fun! You need to solve some puzzles, crack your brain on a few challenges, all while learning a lot of new things. Even experienced developers will learn a lot on the backend architecture of Mendix and thus improve their architectural knowledge.

There are many more reasons, but let’s continue on this specific case. In the example below you see a simple data view on a page with a table layout. Some columns for every attribute and corresponding label, repeating with a new row for every attribute.

Figure 1 Before the migration — old-style table layout

To migrate the attributes to the a new layout page, you simply need to copy and paste the attributes on a page using a layout, placing it on the right layout grid. The result is almost the same page, only without the ugly tables and aligning the styling on the page can be handled better in the layout, instead of the page.

Figure 2 After the migration — new-style layout

This was an easy one, but you can imagine more complex pages with multiple (nested) data views and more attributes will take more time.

Our approach to automating this with a Script

For this specific case we wrote a script and basically ran the script asynchronously to test out on a small set of modules and committing the result of converted pages to a new branch. After running, validating, testing and improving the script in a couple iterations, we were confident enough to run it on the complete project. This resulted in 150+ converted pages with the first script, on the first subset of modules. Some pages were not migrated correctly and solving all edge scenarios would take significant time, so a handful of pages were excluded from the automatic conversion and fixed manually. After finishing the conversion, we merged the branch to the main line and testing, deployed this to production.

Just to explain how we set up the code, an example below. Of course this is not all the code, but just a pointer to start.

import { sdkuModules } from '../vendor/mendix-sdk-utils';
import { Parser, ParserResult } from './parser'
import { Converter } from './converter'
import { OnlineWorkingCopy, Revision } from 'mendixplatformsdk';
class Processor {
public async processForms(moduleName: string, exceptions: string[] = []): Promise<void> {
for(let batch = 0; true; batch++) {
if(this.state instanceof Revision) this.state = await this.state.createWorkingCopy();

let module = this.state.model().findModuleByQualifiedName(moduleName);
if(!module) throw '[Processor] Could not find module'

// Parse
console.log(`[Processor] [Forms] Loading forms.`);
let forms = await sdkuModules.pages.forms.FormProcessor.loadAll(module); // helper function to load all pages and snippets.
console.log(`[Processor] [Forms] Processing ${forms.length} form(s).`);
let parserResults = this.parser.parseForms(this.state, forms);

// Convert
let j = Math.min(this.batches[Math.min(batch, this.batches.length - 1)], parserResults.length);
console.log(`[Processor] Processing batch [${0},${j}) of [0,${parserResults.length}).`);
for(let parserResult of parserResults.slice(0, j)) {
this.converter.convert(parserResult);
}
// Commit
try {
console.log(`[Processor] Committing changes.`)
this.state = await this.state.commit(this.commitBranch);
}
catch (error) {
console.log(`[Processor] Error committing batch to API: ${JSON.stringify(error)}.`);
break;
}

// Repeat
if(j == toConvert.length) break;
console.log(`[Processor] Sleeping ${this.batchTimeOut} milliseconds before loading new batch.`)
await new Promise(resolve => setTimeout(resolve, this.batchTimeOut))
}
}

Future work

This use-case taught us so much and resulted in a bootstrap script for all batch jobs similar to this. Because this app has so many pages and microflows, every generic and repetitive conversion we do in the future could potentially be automated for similar minor changes, without major alterations to the existing batch script.

For example, a lot of documentation and help texts are saved in this specific Mendix app. We have also created another script, for extracting all the help texts from the Mendix meta-model and exporting them to our github documentation pages. This way we don’t have to manually copy and have our documentation stored in 1 place, which can be synced to multiple channels.

Hopefully this gives you some inspiration to automate some repetitive tasks in your work with the power of the Mendix Model SDK.

Read more

From the Publisher -

If you enjoyed this article you can find more like it at our Medium page. For great videos and live sessions, you can go to MxLive or our community Youtube page.

For the makers looking to get started, you can sign up for a free account, and get instant access to learning with our Academy.

Interested in getting more involved with our community? You can join us in our Slack community channel or for those who want to be more involved, look into joining one of our Meet ups.

--

--

Samet Kaya
Mendix Community

Data & Integration enthusiast and Delivery Manager @ eMagiz https://www.emagiz.com/ Also Mendix MVP