You can build a custom or native client for an MDriven Turnkey application by discovering its permitted menu, opening a selected ViewModel, consuming its server stream, and rendering the view from limited UI metadata.
MDriven Turnkey exposes metadata that tells a client what it may present: menu groups, global actions, view names, suggested control types, placement, labels, and available actions. It does not expose sensitive implementation details. The server remains responsible for authentication, access control, the data slice, and execution of actions. See Training:Information security for the security model.
What a client needs
A client that renders a Turnkey application needs four kinds of information:
| Information | Endpoint or operation | What the client uses it for |
|---|---|---|
| Main-menu metadata | /MDriven/GlobalActionsMeta
|
Discover menu groups and global actions without hard-coding available views. |
| Opened view identity | /api/open
|
Open a selected main-menu action and obtain the server identity of the ViewModel instance. |
| View state and commands | /api/ServerStream
|
Build and keep current the data hierarchy and available action state for the opened ViewModel. |
| UI definition | /MDriven/ViewMeta?view=...
|
Render the ViewModel using suggested controls, labels, and layout positions. |
Replace https://your-site in the examples with the base URL of your Turnkey application.
Request the global-action metadata:
https://your-site/MDriven/GlobalActionsMeta?targetgroup=
The response is XML containing menugroups and actions. A menu-group entry provides its name and sort key:
<menugroup Name="File" Sortkey="001"/>
An action entry describes an item that your client can show:
<action MenuGroup="Views"
MenuGroupSortKey="004"
DividerGroupTag=""
DividerGroupTagSortKey=""
Name="ShowAllCars"
Presentation="Show All Cars"
BringUpViewModel="AllCars"
ExecuteFrameworkRuntimeAction="None"/>
In this example, display Show All Cars in the Views menu. Selecting it opens the AllCars ViewModel.
Use the metadata rather than a hard-coded menu so that additions and changes in the model can be discovered by the client.
- Group actions by
MenuGroup. - Sort menu groups alphanumerically by
MenuGroupSortKey. - Within a group, sort actions alphanumerically by
DividerGroupTagSortKey. - Insert a divider between items whose
DividerGroupTagvalues differ. - Use
Presentationas the text shown to the user.
An action is either a framework runtime action or navigation:
| Action type | Metadata indicator | Client behavior |
|---|---|---|
| Framework runtime action | ExecuteFrameworkRuntimeAction contains a value such as Save, Undo, Redo, or Refresh.
|
Invoke the corresponding Turnkey operation for the selected action. |
| Navigation action | BringUpViewModel is set, for example AllCars.
|
Open the menu action, then retrieve the resulting ViewModel state and UI definition. |
If the application serves different audiences, include the target-group name in the request:
https://your-site/MDriven/GlobalActionsMeta?targetgroup=TargetGroupName
A target group is a specialized use of the access-group concept. The client should treat this response as the menu it is allowed to offer for that target group. Access control is still enforced on the server; a client must not treat menu metadata as authorization to bypass server rules.
When the user selects a navigation action, open it by identifying both the main menu and the action name:
https://your-site/api/open?VMClassId=MAINMENU;ShowAllCars&ResetServerApp=false
In this example, ShowAllCars is the action name from GlobalActionsMeta. The response has two parts separated by ¤:
943a7840-796e-4370-bd37-d407ffa48aa9¤$null$;AllCars
| Returned part | Meaning | Example |
|---|---|---|
Before ¤
|
The server identity of the opened ViewModel instance. Use it as VMId when reading the server stream.
|
943a7840-796e-4370-bd37-d407ffa48aa9
|
After ¤
|
The ViewModel class identifier. | $null$;AllCars
|
The server checks authentication and any access-group requirements when the action is opened.
Read and maintain the ViewModel state
Use the returned server identity to read the ViewModel's message stream. Start at cursor 0 for a newly opened UI:
https://your-site/api/ServerStream?VMId=943a7840-796e-4370-bd37-d407ffa48aa9&cursor=0
The response is JSON containing server update commands. For example, action commands describe actions available in the current ViewModel state:
{
"VMClassName": "AllCars",
"Action": "CreateCar",
"Enable": true,
"Presentation": "Create Car",
"GroupHeader": "Car",
"CType": "ServerUpdateCommand_Action"
}
Collection-update commands build the data hierarchy defined in the ViewModel Editor in MDriven Designer. For example, an UpdateCollection command with Attribute set to AllCar adds an item to that collection.
Continue from the cursor
The final message in a response is an application-information command:
{
"SuggestCallbackInSecs": 0,
"MNo": 7,
"CType": "ServerUpdateCommand_AppInfo"
}
Use this object to continue the stream:
- Read the final
ServerUpdateCommand_AppInfoobject. - Store its
MNovalue as the next cursor. In the example, the next cursor is7. - Wait the number of seconds in
SuggestCallbackInSecs. - Request
ServerStreamagain using the stored cursor.
When SuggestCallbackInSecs is 0, call back immediately because the server may have more messages to deliver. Apply each received command in message order so that the client's state remains aligned with the server's ViewModel state.
Get the UI definition
The server stream provides state; it does not by itself tell a custom client which widgets and layout to use. Request per-view UI metadata using the view name discovered from the menu metadata:
https://your-site/MDriven/ViewMeta?view=AllCars
The response is XML. It contains suggested control types, control names, labels, layout positions, and spans. For example:
<root RowHeight="20" ColWidth="50">
<control type="grid" owner="AllCars" name="AllCar"
root="vCurrent_AllCars" label="All Car"
labelspan="1" colspan="3" rowspan="5"
x="0" y="0" nesting="AllCar">
<control type="textbox" name="AsString" label="As String" colspan="1" />
</control>
</root>
In this example, render AllCar as a grid at position x="0", y="0". Render its nested AsString value as a text box. Treat control types and positions as UI guidance supplied by the model.
Documentation:ViewMeta documents the per-view metadata endpoint and its purpose. Tagged values set on ViewModel columns in MDriven Designer are also included in the metadata, so you can place client-specific rendering instructions in the model instead of hard-coding them in the client.
Blazor client metadata
For a client-side Blazor implementation, use the Blazor-specific per-view metadata endpoint:
http://<YourSite>/Turnkey/ViewMetaBlazorClient?view=NameOfViewModel
See Documentation:ViewMeta for this endpoint.
End-to-end example
The following sequence opens and renders the Show All Cars action without hard-coding the AllCars view into the client.
- Request
/MDriven/GlobalActionsMeta?targetgroup=. - Find the action whose
NameisShowAllCars; display itsPresentation, Show All Cars, in its configured menu group. - When selected, call
/api/open?VMClassId=MAINMENU;ShowAllCars&ResetServerApp=false. - Extract the ViewModel server identity before
¤from the response. - Request
/api/ServerStream?VMId=returned-id&cursor=0and apply its update commands. - Request
/MDriven/ViewMeta?view=AllCarsand render the returned controls against the streamed state. - Continue reading the server stream from the final
MNo, followingSuggestCallbackInSecs.
Security boundaries
The metadata is intentionally limited to what a client needs to present the application. It describes presentation and available actions; it is not a copy of the application's internal implementation. The ViewModel defines the subset of data available for a use case, and Turnkey performs that reduction and access control on the server. This applies whether the client is the standard Turnkey UI or a custom client.
Do not rely on hiding a menu item as a security control. A client can choose what to display, but the server must remain the authority for authentication, authorization, data filtering, and action execution.
Related implementation guidance
For a broader description of creating your own renderer and integrating a Turnkey application with an existing site, see Documentation:Rendering the MDriven Turnkey application yourself. If you need to add page-level browser metadata such as a Content Security Policy or a robots directive, see Documentation:Turnkey extra meta tags.
