A user transitioning from Java to Mendix found that applying traditional object-oriented inheritance patterns led to increased work, suggesting a need for Mendix to better support or provide more efficient alternatives for managing complex object relationships, especially for developers familiar with high-code paradigms.
Last year, I wrote about my personal journey from a high coder to low coder. While I see myself more as a hybrid coder, utilising the strengths of both high-code and low-code solutions to add value to each project I contribute to. There are those who are making the transition from being a pure high coder to a low coder without knowledge of low-code capabilities and find themselves relying on their skills and understanding of high-code solutions that clash with the low-code environment. When you find yourself in this position, or if you are just getting into low-code and want to avoid some common mistakes, this newsletter is perfect for you! I will highlight the most common mistakes high coders make when adopting low-code, focusing on Mendix , of course. However, many concepts are translatable to other low-code platforms. Not having any coding skills at all Give credit to the marketing gurus of the low-code world for spreading this misconception. While it is true that you can achieve some goals with less coding skill compared to high-code, tackling more complex solutions will require a significant amount of software development expertise, unless you want the solution to blow up due to all kinds of “unexpected” issues. This is similar to how the AI marketing machine promises that everyone can now code anything, as AI generates it for you. However, you may realise that while the initial steps might be simple, actually building high-quality apps and integrating it into a complex ecosystem requires a much deeper understanding of the underlying complexities of software development. I would argue that a high-coder who learned the basic principles of software development is far more likely to deliver high-quality, low-code driven software than a pure low-coder without any interest in the underlying technology and “nasty” things such as design patterns. Over-engineering your solutions While Johan Hamstra has written some great articles about using design patterns in low-code software, not all multi-layered high-code patterns translate nicely into low-code. They would increase the complexity and reduce the maintainability of your low-code solution. See Mendix as a solution with many built-in features. Rely on these and only extend where your particular use case requires. Finding a building block that already exists instead of reinventing the wheel will allow you to gain the speed the platform offers. Otherwise, you might as well build your solution with high-code. Falling back to familiar coding using Java actions and JavaScript widgets “Low-code is not able to do xyz so I build it using my own Java action or JavaScript widget.” Is a common phrase I often hear from high-coders. This might be a quick and somewhat unrefined method to achieve your goal. However, it will introduce the same issues that regular high-code projects face, with the added disadvantage that your non-high-code colleagues will not be able to maintain or debug that part of the application. While it is not entirely wrong to use Java actions and build JavaScript widgets, it should never be the go-to solution without first attempting to achieve the same result with pure Mendix low-code. Many solutions may simply be built with the tools that are natively offered by the platform or available from any of the building blocks already offered in the public marketplace. If you do fall back on high-code, ensure that it is well documented and accessible for usage in your Mendix applications by any non-high-coder colleagues. Database-first thinking You often start by creating your domain model when building applications with Mendix. The domain model is more than just a data model. When you normalise your entities as you would for your ERD schema, this becomes your database design. You may encounter issues when implementing your logic. Until recently, every single association, for example, was always an intermediate table in the database, regardless of the type. Yes, even one-to-one and one-to-many associations. This, of course, causes issues if you are not aware of this. Since Mendix 10.21, you may choose a foreign key relationship database design when you are not creating a many-to-many association. In addition to such an obvious issue, you must bear in mind that your model should be designed for application simplicity. Although it is becoming less necessary with the alternatives available, you may need to add attributes to your entities simply to assist the logic in your application or to create the page required by your users. This also means that you might need to denormalise for a perfect balance between database purity and the ability to achieve the logic/page design you require. Other elements to keep in mind are that shorter paths lead to simpler XPaths and, therefore, simpler SQL queries generated. For instance, if you have the following: This is useful for creating simpler XPaths for retrieving data and for XPaths on entity access rules, as well as for building pages when you want to display Tenant-related information on an account page. Do keep in mind that each association represents an extra table in the database. This is just one of many examples in which you might utilise the data model differently than you would if you optimised for purely normalised SQL schemas. Creating giga microflows Although this appears obvious and straightforward to translate from high-coding best practices, it still frequently occurs when adopting low-code Mendix. Huge microflows that take care of so many tasks that it becomes nearly impossible to debug or maintain. Comparable to having one giant function written in high-code. Splitting Improving your microflows (and nanoflows) to maintain code reusability and testability is an important best practice to adhere to. This also ensures that you will encounter fewer merge conflicts when working with similar code adjacent to your colleagues in a larger project. Particularly as the interactive merge feature from Mendix is not as flexible as merging lines of code in text-based high-code files. Giga flows also ensure that you will not be able to unit test the microflows with a small set of scenarios. Breaking apart the specific pieces of logic into sub-flows allows you to Remove the merge-conflict issue; Reuse your microflows; Unit test the individual pieces of logic Understand each microflow's purpose quickly when first opening it; Debug your microflows easier. Ignoring Mendix conventions Coding conventions exist to keep the code clean and understandable for anyone joining your project. Mendix has defined standards that advise on general platform conventions or best practices outlined in the documentation. These standards ensure consistency in naming and module organisation, facilitating easier onboarding of new team members and smooth handover to a support team once development is complete. Furthermore, Mendix partners like @Blue Green Solutions have developed their own extensions to these conventions. When all members of the development team adhere to these conventions, it will be much easier to comprehend the logic. Ensure you learn these conventions and best practices from day one to create readable, consistent, and easy-to-understand Mendix code! Overcustomising the UI Mendix provides many building blocks for your UI. With the Atlas UI modules, you can have a basic UI with minor customisations up and running in a few minutes. Customising the UI through CSS (SASS) and JavaScript means you need to always keep in mind that you follow a few “basic” guidelines: Is there a standard component available? If a standard component is available that may achieve the desired look or functionality, you should use that component. This ensures that both you and your fellow team members are able to maintain the UI. Proper usage of specificity While Mendix has violated this in the past with their components, that does not mean you should as well (unless you really can’t without good reason). Ensure you use proper specificity before resorting to !important statements in your CSS. Once you introduce your own CSS, do this in the theme directory or even better in a separate UI resource module, to create a design system for your company’s design work. JavaScript as a last resort When creating UI/UX, ensure that everyone in your team can update and maintain the code. Much functionality is already achievable through nanoflows and platform widgets. Additionally, you can download JavaScript action modules, such as the Nanoflow Commons or Web Actions modules. In many low-code projects, there are still developers who do not comprehend high-code at all, making the maintenance of high-code extensions challenging. Only customise when needed! When you apply customisations, you introduce the risk that upgrading to newer versions of Atlas or the Mendix platform will require updating your customisations. This delays upgrades and necessitates more testing when you do upgrade. Customising sparingly ensures that upgrades are easier, meaning it is best to limit your customisations to those areas of the application where they add value. Build your own security While it is important to add your own layer of logic to ensure your application meets the needs of the business, it is seldom necessary to construct your own security model within Mendix, as the platform provides an excellent array of tools to guarantee data security. Always base your data security on the entity-level security rules. Limit module roles, and, by extension, project roles, to the bare minimum. That way, as you build your pages, those roles can’t access any data beyond what’s permitted. Please remember that while entity access by default applies to any queries executed from the client, this does not apply when executing microflows. By default, microflows ignore entity access unless you specifically enable it for each microflow you build. This offers flexibility to alter data (for instance, a create flow) without having direct access based on entity access. When you must implement your own security measures, ensure you extend the capabilities provided by Mendix. Avoid creating your own entity access logic or overriding the login handler, to name just two examples. Low-code is easy; you can start without any training Just like any new coding language, framework, or platform, Mendix has its own rules and way of working. And of course, the platform has quirks you learn while using a new platform, as they block you from implementing what you had intended. There are numerous learning paths and how-tos available for mastering many of these topics. They even offer a rapid course designed for experienced coders to get up to speed without the extraneous details of the basic principles of coding. It is advisable to follow these guidelines and gain a solid understanding of the platform. If you invest early in learning the Mendix-specific best practices, you will reap the benefits later (or you must really like refactoring and going through life one YOLO project after another). Reinventing the wheel It is a no-go when developing software solutions, unless the wheel is exceptionally poor. Mendix has many built-in components, and if you cannot find the right one for your problem, you may have it available in the marketplace. Therefore, especially for functionality that is not business-specific, ensure you explore the platform-supported content in the marketplace. If you are a bit more adventurous and your company’s guidelines permit it, you could also consider the community-supported content. Unfortunately, this is not always possible, and the solution may not be suitable for your situation. If you simply need to adapt it, ensure you make the adjustments outside of the downloaded component or, at the very least, document it thoroughly so that you can reapply the changes during upgrades. Ignore performance nuances If you have over-engineered your application, applied database-first thinking, and created a ton of gigamicroflows, you will run into all sorts of trouble on the performance side. As mentioned earlier in this article, it is important to build with the platform instead of against it. Writing optimised XPaths based on an optimised domain model is an excellent method to ensure speedy data retrieval from your database. The best practices recommender certainly has some valuable recommendations to help with that. As a highcoder, it could also be interesting to enable tracing on log nodes like connectionbus_retrieve to see what type of SQL queries Mendix produced based on different XPaths. If that still fails, utilise the Ciphx performance tool or similar tools to debug the performance issues. Remember that an optimised domain model, a relatively standard UI, the use of standard components, and optimised XPaths will significantly contribute to adhering to performance best practices. This will enable your Mendix application to run without the performance issues that many high-coders cite as an argument against low-code. What do you think? What has your experience been? Either as a high-coder that transitioned to a low-coder (hybrid-coder) or a low-coder that experienced high-coder colleagues adopting low-code. Which pitfalls did you fall into? And how did you overcome them? Personally, I believe that both complex low-code and high-code solutions face similar challenges and require a comparable mindset. I would love to see more hybrid coders who possess an understanding of both realms and can effectively combine them for an ideal hybrid solution. Join us June 12th, for the yearly Blue Green Solutions Mendix community summer drinks! https://www.meetup.com/mendix-nl/events/304632874/ #mendixignite #fromhighcodetolowcode #mendix #hybridcoder