🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Expose REST Service
This page was created by Wikiadmin on 2026-07-29. Last edited by Wikiadmin on 2026-07-29.

You can expose a ViewModel from an MDriven Turnkey application as a REST endpoint for clients that need to read data, submit data, or invoke ViewModel actions.

Before you begin

This page covers exposing a running Turnkey application to other clients. To call an external REST service from MDriven, see Documentation:Rest Services In MDriven.

A REST request identifies:

  • the ViewModel to run;
  • the root object for that ViewModel; and
  • optional values to place in ViewModel variables.

The endpoint returns the ViewModel content as JSON unless you configure an override.

Expose a ViewModel

  1. Open the ViewModel in MDriven Designer.
  2. Select the root of the ViewModel.
  3. Set the RestAllowed tagged value to true.
  4. Upload or deploy the updated application so that Turnkey runs the changed ViewModel.
  5. Call the endpoint with the ViewModel name and a complete root-object reference.

For example, a ViewModel named CarDetails, rooted in a car object, can be called with a GET request after it has RestAllowed enabled.

Turnkey checks RestAllowed before it looks up the root object. It then checks the ViewModel access groups. A caller must be allowed by those access groups before the request proceeds.

Choose an endpoint format

Turnkey accepts both query-string and path-based endpoint formats.

Format Example Notes
Legacy TurnkeyRest format <host>/TurnkeyRest/Get?command=CarDetails&id=<rootobjref> Use command for the ViewModel name and id for the root-object reference.
Path-based REST format <host>/Rest/CarDetails/Get/<rootobjref> The same path format is available for all supported verbs.

Supported verbs are Get, Post, Put, Patch, and Delete. For example:

<host>/TurnkeyRest/Put?command=CarDetails&id=<rootobjref>
<host>/Rest/CarDetails/Patch/<rootobjref>
<host>/Rest/CarDetails/Delete/<rootobjref>

Use a complete object reference

The id value is an object reference. Always send a complete identifier, such as a GUID or an identifier in the form xx|yyyy.

Do not use a shortcut identifier without its class identifier. Such shortcuts can resolve incorrectly and cause request failures or unexpected results.

Send input values to the ViewModel

Declare a String variable on the ViewModel for each input value you want to receive. Turnkey matches incoming parameter names to these variables.

For example, if the ViewModel declares MyVar:String and MyOtherVar:String, call:

<host>/Rest/CarDetails/Get/<rootobjref>?MyVar=hello&MyOtherVar=world

Turnkey sets MyVar to hello and MyOtherVar to world. URL-encoded parameters and multipart form-encoded parameters are supported.

Request verb Incoming values are matched against Result
Get ViewModel variable names Matching variable values are set.
Post ViewModel variable names, attributes, and values Matching values are set before root-level actions run.

Control behavior with root-level actions

After Turnkey finds the ViewModel and root object and sets additional parameters, it executes actions placed at the root level of the ViewModel. Actions run from top to bottom in their displayed ViewModel order.

Use these actions to implement the endpoint behavior.

  • For Get, use actions to retrieve or calculate additional information before the JSON response is produced.
  • For Post, use actions to process submitted data. Changed values are saved to the database.

Branch by HTTP verb

Turnkey assigns the received HTTP verb to a variable named vRestVerb, when that variable exists in the ViewModel. Use it in an action's Disable or ReadOnly expression to choose which action is available for a request.

For example, make an action read-only except for PUT requests:

vRestVerb&lt;&gt;'Put'

This lets one RestAllowed ViewModel distinguish between Get, Post, Put, Patch, and Delete requests.

Process JSON submitted in a POST request

A JSON string is not automatically converted into modeled objects. To create or update an object tree from JSON, receive the JSON string in the ViewModel and use selfVM.JSonToObjects in an action.

selfVM.JSonToObjects(«&lt;Type&gt;», JSonDataInStringFormat)

JSonToObjects creates objects from the specified root class and matches JSON names to attributes and associations. It can create an object tree by following association names; the resulting graph is unclosed.

For a worked approach to importing JSON or XML into modeled objects, see Documentation:Rest Services In MDriven.

Receive raw string or binary request content

Form fields are normally matched to ViewModel columns. If a request does not send form data, Turnkey can place the raw request body in a designated ViewModel column:

Declare this column Type requirement Received value
STRINGCONTENT String The complete raw string content of a non-form request.
BYTEARRAYCONTENT A blob type The complete byte stream of a non-form request.

Use STRINGCONTENT when the client sends raw JSON or other text content. Use BYTEARRAYCONTENT when the client sends binary content.

Read request headers

Declare a ViewModel variable named vRequestHeaders to receive all request headers as a JSON string. You can then retrieve an individual header with JsonGetProp.

For example, this expression reads the Host request header:

vRequestHeaders.JsonGetProp('Host')

Control the response body and status code

By default, GET and POST return the ViewModel content as JSON. You can replace that response or set an HTTP status through specially named ViewModel members.

Member name Type Effect
RawJSon String attribute on the root Its value is returned instead of the complete ViewModel JSON.
vReturnMessage String variable Its value is returned as the response content instead of the default ViewModel JSON.
vReturnStatusCode String variable Sets the HTTP status associated with vReturnMessage.

Set vReturnStatusCode to a named value from the .NET System.Net.HttpStatusCode enumeration. For example:

vReturnStatusCode:='NotFound'
vReturnMessage:='The requested car was not found'

You can also use values such as 'Created'. If vReturnStatusCode is absent or does not contain a valid enumeration value, the response status is 200 Ok.

When MDriven calls another REST service through its REST operators, use variables named vReturnStatusCode:String and vReturnMessage:String to receive the status and reason content from that external call. See Documentation:Rest Services In MDriven for the REST operators.

If processing fails, Turnkey returns a string in the form error: <message>.

Test and troubleshoot requests

  1. Start with a GET request that only supplies the ViewModel name and a complete root-object reference.
  2. Confirm that the ViewModel has RestAllowed set and that the caller is permitted by its access groups.
  3. Add one String ViewModel variable and pass one query parameter.
  4. Add root-level actions only after the basic endpoint returns the expected JSON.
  5. Test the final request in an HTTP client. When request formatting is unclear, use postman-echo.com to inspect what the client sends.

For a walkthrough that demonstrates enabling RestAllowed and requesting a ViewModel, watch the REST services in MDriven video.

See also

Example REST responses

Example REST responses

REST requests identify a ViewModel by name and operate on its root object. For example, a ViewModel named CarDetails can be requested with the documented route format:

GET <host>/Rest/CarDetails/Get/<rootobjref>

The ViewModel must be allowed for REST exposure through its RestAllowed tagged value. After the ViewModel and root object are found, Turnkey checks access groups before continuing.

By default, Get and Post return the ViewModel content as JSON. The exact response content follows the ViewModel that is executed. A root-level string attribute named exactly RawJSon can override the default ViewModel JSON response.

Return a custom body and status

A REST-allowed ViewModel can declare these variables:

vReturnMessage:String
vReturnStatusCode:String

When vReturnMessage is found, its value is returned as the response content instead of the default ViewModel JSON. Set vReturnStatusCode to a defined HTTP status-code name, such as Created or NotFound.

For example, a root-level action may set:

vReturnStatusCode:='Created'
vReturnMessage:='{ "result": "created" }'

This returns the content of vReturnMessage with the selected status code. If vReturnStatusCode is not a recognized HTTP status-code value, the documented behavior is 200 OK. If an error occurs, the documented error response is error: <message>.

Receive request values

To receive extra request parameters, declare ViewModel variables of type String. For example, a ViewModel that declares MyVar:String and MyOtherVar:String can receive values in a request such as:

GET <host>/Rest/CarDetails/Get/<rootobjref>?MyVar=hello&MyOtherVar=world

For Get, parameter names are matched to ViewModel variables and their values are set. For Post, parameter names are matched to ViewModel variables, attributes, and values. Root-level ViewModel actions then execute in the order in which they appear in the ViewModel. Post saves changed values to the database.

If a request does not use form data, string content can be received in a column named STRINGCONTENT, if that column exists. Binary content can similarly be received through a blob column named BYTEARRAYCONTENT. JSON supplied as a string can be applied to modeled objects with selfVM.JSonToObjects.

Use complete object references

The root-object reference must be complete. The documented guidance is to send a GUID or an identifier in the form xx|yyyy. Do not use a shortcut identifier without a class identifier, because it can cause problems.

The alternate route format is also supported for all verbs:

<host>/Rest/CarDetails/Get/<rootobjref>

In addition to Get and Post, the documentation lists Put, Patch, and Delete. A ViewModel variable named vRestVerb receives the verb used, so action disable/read-only expressions can make decisions based on that verb.

See also

Design the ViewModel for the REST response

Design the ViewModel for the REST response

GET and POST return the ViewModel content as JSON by default. Design the ViewModel to contain the attributes and related data that the REST client needs.

For a REST endpoint, enable Eco.RestAllowed on the ViewModel. The REST documentation describes the endpoint as operating on the named ViewModel; the ViewModel's exposed columns determine the data returned in the default JSON response.

A column can map directly to a modeled attribute, for example self.title, or use a computed expression. When a column uses a computed expression, the response returns the computed value rather than the raw stored value. Use direct mappings when a client requires the underlying attribute value.

Use clear, client-appropriate column names and expose only the data needed for the endpoint. Changes to exposed columns or their expressions can change the response received by clients.

Override the default response

GET and POST normally return the complete ViewModel content as JSON. To return different content, use one of the documented response overrides:

  • Add a String attribute named exactly RawJSon on the root. Its value is returned instead of the complete ViewModel JSON.
  • Declare vReturnMessage:String. Its value is returned as the response content instead of the default ViewModel JSON.
  • Optionally declare vReturnStatusCode:String with vReturnMessage to provide a status code. The documented value must be a valid .NET HttpStatusCode name; otherwise, the response defaults to 200 OK.

Scope of the documented REST mechanism

The supplied documentation describes REST exposure through a ViewModel with Eco.RestAllowed enabled. It does not document an OData endpoint or an unrestricted direct-model query API as an alternative.