|
1 | 1 | # Mendix Concepts for Newcomers |
2 | 2 |
|
3 | | -A brief introduction to Mendix platform concepts -- entities, microflows, pages, modules, and more -- for developers who are new to Mendix and want to understand the building blocks before working with mxcli. |
| 3 | +This page explains the core Mendix concepts you'll encounter when using mxcli. If you're familiar with web frameworks, relational databases, or backend development, most of these will map to things you already know. |
| 4 | + |
| 5 | +## The Big Picture |
| 6 | + |
| 7 | +A **Mendix application** is a model-driven app. Instead of writing code in files, developers build applications visually in **Studio Pro** (the Mendix IDE). The entire application model -- data structures, logic, UI, security -- is stored in a single binary file called an **MPR** (Mendix Project Resource). |
| 8 | + |
| 9 | +mxcli lets you read and modify that MPR file using text commands, without opening Studio Pro. |
| 10 | + |
| 11 | +## Modules |
| 12 | + |
| 13 | +A **module** is the top-level organizational unit, like a package in Go or a namespace in C#. Each module has its own: |
| 14 | + |
| 15 | +- Domain model (data structures) |
| 16 | +- Microflows and nanoflows (logic) |
| 17 | +- Pages (UI) |
| 18 | +- Enumerations (constant sets) |
| 19 | +- Security settings |
| 20 | + |
| 21 | +A typical project has a few custom modules (`Sales`, `Admin`, `Integration`) plus system modules provided by the platform (`System`, `Administration`). |
| 22 | + |
| 23 | +```sql |
| 24 | +SHOW MODULES; |
| 25 | +``` |
| 26 | + |
| 27 | +## Domain Model |
| 28 | + |
| 29 | +The **domain model** is the data layer of a module. If you know relational databases, the mapping is straightforward: |
| 30 | + |
| 31 | +| Mendix Concept | Relational Equivalent | MDL Syntax | |
| 32 | +|----------------|----------------------|------------| |
| 33 | +| Entity | Table | `CREATE ENTITY` | |
| 34 | +| Attribute | Column | Inside entity definition | |
| 35 | +| Association | Foreign key / Join table | `CREATE ASSOCIATION` | |
| 36 | +| Generalization | Table inheritance | `EXTENDS` | |
| 37 | +| Enumeration | Enum / Check constraint | `CREATE ENUMERATION` | |
| 38 | + |
| 39 | +### Entities |
| 40 | + |
| 41 | +An **entity** defines a data type. There are several kinds: |
| 42 | + |
| 43 | +- **Persistent** -- stored in the database (the default and most common) |
| 44 | +- **Non-persistent** -- exists only in memory during a user session, useful for form state or temporary calculations |
| 45 | +- **View** -- backed by an OQL query, like a database view |
| 46 | + |
| 47 | +```sql |
| 48 | +CREATE PERSISTENT ENTITY Sales.Customer ( |
| 49 | + Name: String(200) NOT NULL, |
| 50 | + Email: String(200), |
| 51 | + IsActive: Boolean DEFAULT true |
| 52 | +); |
| 53 | +``` |
| 54 | + |
| 55 | +### Associations |
| 56 | + |
| 57 | +An **association** is a relationship between two entities. Think of it as a foreign key. |
| 58 | + |
| 59 | +- **Reference** -- many-to-one or one-to-one (a foreign key column on the "from" entity) |
| 60 | +- **ReferenceSet** -- many-to-many (a join table under the hood) |
| 61 | + |
| 62 | +```sql |
| 63 | +CREATE ASSOCIATION Sales.Order_Customer |
| 64 | + FROM Sales.Order TO Sales.Customer |
| 65 | + TYPE Reference; |
| 66 | +``` |
| 67 | + |
| 68 | +### Generalization |
| 69 | + |
| 70 | +Entities can inherit from other entities using **generalization** (the `EXTENDS` keyword). The child entity gets all parent attributes. This is commonly used with system entities like `System.Image` (for file uploads) or `System.User` (for user accounts). |
| 71 | + |
| 72 | +```sql |
| 73 | +CREATE PERSISTENT ENTITY Sales.ProductImage EXTENDS System.Image ( |
| 74 | + Caption: String(200) |
| 75 | +); |
| 76 | +``` |
| 77 | + |
| 78 | +## Microflows and Nanoflows |
| 79 | + |
| 80 | +**Microflows** are the server-side logic of a Mendix app. They're visual flowcharts in Studio Pro, but in MDL they read like imperative code with activities: |
| 81 | + |
| 82 | +- **Retrieve** data from the database |
| 83 | +- **Create**, **Change**, **Commit**, **Delete** objects |
| 84 | +- **Call** other microflows or external services |
| 85 | +- **If/Else** branching, **Loop** iteration |
| 86 | +- **Show Page**, **Log Message**, **Validation Feedback** |
| 87 | + |
| 88 | +```sql |
| 89 | +CREATE MICROFLOW Sales.CreateOrder( |
| 90 | + DECLARE $Customer: Sales.Customer |
| 91 | +) |
| 92 | +RETURN Boolean |
| 93 | +BEGIN |
| 94 | + CREATE $Order: Sales.Order ( |
| 95 | + OrderDate = [%CurrentDateTime%], |
| 96 | + Status = 'Draft' |
| 97 | + ); |
| 98 | + CHANGE $Order ( |
| 99 | + Sales.Order_Customer = $Customer |
| 100 | + ); |
| 101 | + COMMIT $Order; |
| 102 | + RETURN true; |
| 103 | +END; |
| 104 | +``` |
| 105 | + |
| 106 | +**Nanoflows** are the client-side equivalent. They run in the browser (or native mobile app) and are useful for offline-capable logic and low-latency UI interactions. They have the same syntax but fewer available activities (no database transactions, no direct service calls). |
| 107 | + |
| 108 | +## Pages |
| 109 | + |
| 110 | +**Pages** define the user interface. A page has: |
| 111 | + |
| 112 | +- A **layout** -- the outer frame (header, sidebar, footer) shared across pages |
| 113 | +- **Widgets** -- the UI components inside the page |
| 114 | + |
| 115 | +Widgets are nested in a tree. Common widget types: |
| 116 | + |
| 117 | +| Widget | Purpose | Analogy | |
| 118 | +|--------|---------|---------| |
| 119 | +| DataView | Displays one object | A form | |
| 120 | +| DataGrid | Displays a list as a table | An HTML table with sorting/search | |
| 121 | +| ListView | Displays a list with custom layout | A repeating template | |
| 122 | +| TextBox | Text input bound to an attribute | An `<input>` field | |
| 123 | +| Button | Triggers an action | A `<button>` | |
| 124 | +| Container | Groups other widgets | A `<div>` | |
| 125 | +| LayoutGrid | Responsive column layout | CSS grid / Bootstrap row | |
| 126 | + |
| 127 | +```sql |
| 128 | +CREATE PAGE Sales.CustomerOverview |
| 129 | + LAYOUT Atlas_Core.Atlas_Default |
| 130 | + TITLE 'Customers' |
| 131 | +( |
| 132 | + DATAGRID SOURCE DATABASE Sales.Customer ( |
| 133 | + COLUMN Name, |
| 134 | + COLUMN Email, |
| 135 | + COLUMN IsActive |
| 136 | + ) |
| 137 | +); |
| 138 | +``` |
| 139 | + |
| 140 | +### Snippets |
| 141 | + |
| 142 | +A **snippet** is a reusable page fragment. You define it once and embed it in multiple pages using a SnippetCall. Think of it as a component or partial template. |
| 143 | + |
| 144 | +## Security |
| 145 | + |
| 146 | +Mendix uses a role-based access control model: |
| 147 | + |
| 148 | +1. **Module roles** are defined per module (e.g., `Sales.Admin`, `Sales.User`) |
| 149 | +2. **User roles** are defined at the project level and aggregate module roles |
| 150 | +3. **Access rules** control what each module role can do with entities (CREATE, READ, WRITE, DELETE) and which microflows/pages they can access |
| 151 | + |
| 152 | +```sql |
| 153 | +CREATE MODULE ROLE Sales.Manager; |
| 154 | + |
| 155 | +GRANT CREATE, READ, WRITE ON Sales.Customer TO Sales.Manager; |
| 156 | +GRANT EXECUTE ON MICROFLOW Sales.CreateOrder TO Sales.Manager; |
| 157 | +GRANT VIEW ON PAGE Sales.CustomerOverview TO Sales.Manager; |
| 158 | +``` |
| 159 | + |
| 160 | +## Navigation |
| 161 | + |
| 162 | +**Navigation profiles** define how users move through the app. There are profiles for responsive web, tablet, phone, and native mobile. Each profile has: |
| 163 | + |
| 164 | +- A **home page** (the landing page after login) |
| 165 | +- A **menu** with items that link to pages or microflows |
| 166 | + |
| 167 | +## Workflows |
| 168 | + |
| 169 | +**Workflows** model long-running processes with human tasks. Think of them as state machines for approval flows, onboarding processes, or multi-step procedures. A workflow has: |
| 170 | + |
| 171 | +- **User tasks** -- steps that require human action |
| 172 | +- **Decisions** -- branching based on conditions |
| 173 | +- **Parallel splits** -- concurrent paths |
| 174 | + |
| 175 | +Workflows complement microflows: microflows handle immediate logic, workflows handle processes that span hours or days. |
| 176 | + |
| 177 | +## How It All Fits Together |
| 178 | + |
| 179 | +``` |
| 180 | +Project |
| 181 | +├── Module: Sales |
| 182 | +│ ├── Domain Model |
| 183 | +│ │ ├── Entity: Customer (Name, Email, IsActive) |
| 184 | +│ │ ├── Entity: Order (OrderDate, Status) |
| 185 | +│ │ └── Association: Order_Customer |
| 186 | +│ ├── Microflows |
| 187 | +│ │ ├── CreateOrder |
| 188 | +│ │ └── ApproveOrder |
| 189 | +│ ├── Pages |
| 190 | +│ │ ├── CustomerOverview |
| 191 | +│ │ └── OrderEdit |
| 192 | +│ ├── Enumerations |
| 193 | +│ │ └── OrderStatus (Draft, Active, Closed) |
| 194 | +│ └── Security |
| 195 | +│ ├── Module Role: Manager |
| 196 | +│ └── Module Role: Viewer |
| 197 | +├── Module: Administration |
| 198 | +│ └── ... |
| 199 | +└── Navigation |
| 200 | + └── Responsive profile → Home: Sales.CustomerOverview |
| 201 | +``` |
| 202 | + |
| 203 | +In mxcli, you can explore this structure with: |
| 204 | + |
| 205 | +```sql |
| 206 | +SHOW STRUCTURE DEPTH 2; |
| 207 | +``` |
| 208 | + |
| 209 | +## What's Next |
| 210 | + |
| 211 | +- [Part I: Tutorial](../tutorial/setup.md) -- hands-on walkthrough |
| 212 | +- [Part II: The MDL Language](../language/basics.md) -- complete language guide |
| 213 | +- [Glossary](../appendixes/glossary.md) -- alphabetical reference of all terms |
0 commit comments