Rest Services In MDriven
No edit summary
(Adding page to Category:TOC because it contains a TOC.)
 
(15 intermediate revisions by 5 users not shown)
Line 1: Line 1:
'''REST services''' are services that are executed by connecting to an URL that defines operation and parameters then it returns an answer – not seldom as JSon objects.
'''REST Services''' are services executed by connecting to a URL that defines operation and parameters and returns an answer – not seldom as JSON objects.


You must set the tagged value '''RestAllowed''' on ViewModels you want to allow Rest access to.
You must set the tagged value '''RestAllowed''' on the ViewModels you want to allow Rest access to.


=== '''Calling existing REST services''' ===
=== '''Calling Existing REST Services''' ===
MDriven supports a couple of EAL operators to manage REST services. All operators reside on the [[selfVM]] variable available only in the ViewModel context.
MDriven supports a couple of EAL operators to manage REST services. All operators reside on the [[selfVM]] variable which is available only in the ViewModel context.
  ''selfVM.RestGet(targeturl,user,pwd,optionalnestingwithheaders)''
  ''selfVM.RestGet(targeturl,user,pwd,optionalnestingwithheaders)''
Read: [[OCLOperators RestGet]]
Read: [[OCLOperators RestGet]]
Line 12: Line 12:
Read: [[OCLOperators RestDownload]]
Read: [[OCLOperators RestDownload]]


'''Note!''' ''optionalnestingwithheaders'' is the '''name''' of the blue view model class in the example below (as a OCL String).
'''Note!''' ''optionalnestingwithheaders'' is the '''name''' of the blue ViewModel class in the example below (as an OCL String).


==== Example ====
==== Example ====
[[File:2018-05-29 10h31 45.png|none|thumb|689x689px]]
[[File:2018-05-29 10h31 45.png|none|thumb|689x689px]]
The action '''GetExporttest''' retrieves data by converting another viewmodel to xml - it stores it in the variable vText
The action '''GetExporttest''' retrieves data by converting another ViewModel to XML - it stores it in the variable <code>vText</code>.


Next action invokes RestPost to send that data to an url-address, it also says that it should look at the nesting named 'Xml' - in this nesting we have the STRINGCONTENT (see also [[OCLOperators RestPost]]) which get's it's content from the vText variable - we also add the header Authorization with a bearer token in order to get access from the receiving service.
The next action invokes RestPost to send that data to a URL address; it also says it should look at the nesting named 'Xml'. In this nesting, we have the STRINGCONTENT (see also [[OCLOperators RestPost]]) which gets its content from the vText variable. We also add the header Authorization with a bearer token to get access from the receiving service.


=== Exposing ourselves as a REST service ===
=== Exposing Ourselves as a REST Service ===
And when it comes to '''exposing ourselves to others''' – Turnkey has two MVC verbs, Get and Post, like this;
When it comes to '''exposing ourselves to others''' – Turnkey has two MVC verbs, Get and Post, like this:
  TurnkeyRest/Get?command=vmname&id=rootobjref
  TurnkeyRest/Get?command=vmname&id=rootobjref
   
   
  TurnkeyRest/Post?command=vmname&id=rootobjref
  TurnkeyRest/Post?command=vmname&id=rootobjref  
See [[Improved routes]] for another URLs.  
New(2023-04):
--- if you have a varible vRestVerb it is assigned the verb used
TurnkeyRest/Put?command=vmname&id=rootobjref
TurnkeyRest/Patch?command=vmname&id=rootobjref
TurnkeyRest/Delete?command=vmname&id=rootobjref
use Disable/ReadOnly expression on actions to decide what to run: vRestVerb<>'Put' -- readonly for all but Put
 
See [[Improved routes]] for other URLs.  


The ViewModel name is supplied as the '''command''' parameter.  
The ViewModel name is supplied as the '''command''' parameter.  
Line 31: Line 40:
The '''id''' parameter is an object reference in one of several available formats. Read more [[The ExternalId explained|here]] about how to create these.  
The '''id''' parameter is an object reference in one of several available formats. Read more [[The ExternalId explained|here]] about how to create these.  


'''Caution''': Always send a complete id, i.e. a guid or '''xx|yyyy'''. Using a shortcut without class identifier can cause problems.  
'''Caution''': Always send a complete ID, i.e. a guid or '''xx|yyyy'''. Using a shortcut without a class identifier can cause problems.  


Note that the variables set in your viewmodel has to be of the '''String''' type.  
Note that the variables set in your ViewModel have to be of the '''String''' type.  


===== The commands does this; =====
===== The Commands Do This: =====
We check that the tagged value '''RestAllowed''' has been set on the viewmodel, then we look up the root object.  
We check that the tagged value '''RestAllowed''' has been set on the ViewModel, then look up the root object.  


When the viewmodel and it's root has been found and the [http://wiki.mdriven.net/index.php/Part_9_MDriven_Turnkey,_cloud_tools_and_access_groups accessgroups] are checked to see if access is allowed.
When the ViewModel and its root have been found, we check the [http://wiki.mdriven.net/index.php/Part_9_MDriven_Turnkey,_cloud_tools_and_access_groups accessgroups] to see if access is allowed.


Then additional parameters are set (these can be either URL Encoded or multi-part form encoded. [https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST See HTTP POST] for details).
Then additional parameters are set (these can be either URL Encoded or multi-part form-encoded. [https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST See HTTP POST] for details).
* For Get, the parameter names are looked up against ViewModel variables and variable values are set.  
* For Get, the parameter names are looked up against ViewModel variables, and variable values are set.  
* For Post, the parameter names are looked up against ViewModel variables '''and''' '''attributes''' and values are set.
* For Post, the parameter names are looked up against ViewModel variables, '''and''' '''attributes''' and values are set.
Then any actions present at the root level of the ViewModel are executed, ''in the order presented in the viewmodel'' from top to bottom.
Then any actions present at the root level of the ViewModel are executed - ''in the order presented in the ViewModel'' from top to bottom.
* For Get, use the actions to look up additional information.
* For Get, use the actions to look up additional information.
* For Post, the actions are usually used to process sent JSON data into objects (see below)
* For Post, the actions are usually used to process sent JSON data into objects (see below)
Post saves any changed values to the database.
Post saves any changed values to the database.


Both Get and Post returns the viewmodel content as JSON in the HTTP response. To override this use 1 one these strategies:  
Both Get and Post return the ViewModel content as JSON in the HTTP response. To override this, use one of these strategies:  
# add a string attribute named exactly RawJSon on the root - if found this is returned instead of the complete vm as json.   
# Add a string attribute named exactly RawJSon on the root - if found, this is returned instead of the complete VM as JSON.   
add a vReturnMessage:String variable as described further down on this page
Add a vReturnMessage:String variable as described further down this page
If there is an error a string “error: <message>”  is returned.
If there is an error, a string “error: <message>”  is returned.


If you need to receive post data not known at design time please read [[Receive post data not known at design time]].  
If you need to receive Post data unknown at design time, please read: [[Receive post data not known at design time]].  


You may [[Use c-sharp code to post to TurnkeyRest|use c# code to post to TurnkeyRest]].  
You may [[Use c-sharp code to post to TurnkeyRest|use C# code to post to TurnkeyRest]].  


===== Processing JSON into objects =====
===== Processing JSON into Objects =====
If you want to send data as JSON in a POST you need to apply the JSON string to your systems modelled objects.
If you want to send data as JSON in a POST, you need to apply the JSON string to your system's modeled objects.


Use [[Tajson]] or the simpler JsonToObjects. Read more here on XML or JSON support: [[Import xml and JSon with MDriven]]
Use [[Tajson]] or the simpler JsonToObjects. Read more here on XML or JSON support: [[Import xml and JSon with MDriven]]


The selfVM.JSonToObjects creates objects with the root in a of class and matches attributes and association from the JSON data – and it can create object trees (unclosed graphs) by following names on associations.
The selfVM.JSonToObjects creates objects with the root of a class and matches attributes and associations from the JSON data – it can create object trees (unclosed graphs) by following names on associations.
  selfVM.JSonToObjects( «<Type>» ,  JSonDataInStringFormat)
  selfVM.JSonToObjects( «<Type>» ,  JSonDataInStringFormat)
You can use an existing JSON as a template to create a model section that you can import into, see [[Using JSON or XML as class template|Using JSON or XML as class template.]]
You can use an existing JSON as a template to create a model section you can import into - see: [[Using JSON or XML as class template|Using JSON or XML as a class template.]]


=== Video ===
=== Video ===
Line 70: Line 79:
<html>
<html>
<p class="warn">
<p class="warn">
   <em>To make your experience more comfortable, we set the main tags mentioned in the video to the right bar menu of this mini
   <em>To make your experience smooth, we set the main tags mentioned in the video to the right bar menu of this mini-player. Choose an interesting subtitle on the list and immediately get to the exact theme navigation item place in the video. Now you can pick any topic to be instructed on without watching the whole video.</em>
    player. Choose the interesting subtitle on the list and immediately get to the exact theme navigation-itemplace in the
    video. Now you can pick any topic to be instructed without watching the whole video.</em>
</p>
</p>
<br>
<br>
Line 81: Line 88:
   <div class="video__navigation">
   <div class="video__navigation">
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="10" tabindex="0"> What is REST? </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="10" tabindex="0"> What is REST? </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="82" tabindex="0"> How does it work with MDriven turnkey? </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="82" tabindex="0"> How does it work with MDriven Turnkey? </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="125" tabindex="0"> calling an existing REST service </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="125" tabindex="0"> Calling an existing REST service </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="191" tabindex="0"> exposing ourself as REST service </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="191" tabindex="0"> Exposing ourselves as REST service </span>


     <span class="navigation-item" data-video="rv31ziYXWME" data-start="244" tabindex="0"> MDriven turnkey app slot </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="244" tabindex="0"> MDriven Turnkey app slot </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="333" tabindex="0"> how to expose information as the Rest service? </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="333" tabindex="0"> How to expose information as the Rest service? </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="450" tabindex="0"> MDriven Rest/get strategy </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="450" tabindex="0"> MDriven Rest/Get strategy </span>


     <span class="navigation-item" data-video="rv31ziYXWME" data-start="573" tabindex="0"> how to consume data? </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="573" tabindex="0"> How to consume data? </span>


     <span class="navigation-item" data-video="rv31ziYXWME" data-start="680" tabindex="0"> selfvm </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="680" tabindex="0"> selfvm </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="716" tabindex="0"> Rest/Get operator </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="716" tabindex="0"> Rest/Get operator </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="925" tabindex="0"> hard-coded objects </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="925" tabindex="0"> Hard-coded objects </span>


     <span class="navigation-item" data-video="rv31ziYXWME" data-start="1336" tabindex="0"> Json to objects operator </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="1336" tabindex="0"> Json to objects operator </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="1784" tabindex="0"> update data with allow post </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="1784" tabindex="0"> Update data with allow post </span>


     <span class="navigation-item" data-video="rv31ziYXWME" data-start="1898" tabindex="0"> RestPost operator as a post command </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="1898" tabindex="0"> RestPost operator as a post command </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="2490" tabindex="0"> operation execution</span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="2490" tabindex="0"> Operation execution</span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="2558" tabindex="0"> vSomeParam adding new parameters </span>
     <span class="navigation-item" data-video="rv31ziYXWME" data-start="2558" tabindex="0"> vSomeParam adding new parameters </span>


Line 108: Line 115:
</html>
</html>


=== Return Status codes, and override returned data ===
=== Return Status Codes and Override Returned Data ===
New from 2020-12-09 you can now override return result data and code by declaring variables in your RestAllowed ViewModel:
'''New from 2020-12-09:''' You can now override return result data and code by declaring variables in your RestAllowed ViewModel:


  vReturnMessage:String
  vReturnMessage:String
  vReturnStatusCode:String
  vReturnStatusCode:String
The vReturnMessage (reason code) must be found and will be returned as content instead of the default (to make json of the viewmodel) - the return message will have the status code of vReturnStatusCode
The vReturnMessage (reason code) must be found and will be returned as content instead of the default (to make JSON of the ViewModel). The return message will have the status code "vReturnStatusCode".


If the vReturnStatusCode is found it must have one of the values defined here: https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=net-5.0 otherwise 200 "Ok" is returned. We will parse the string value with this logic:
If the vReturnStatusCode is found, it must have one of the values defined here: https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=net-5.0 Otherwise, 200 "Ok" is returned. We will parse the string value with this logic:
  realstatuscode = (System.Net.HttpStatusCode)System.Net.HttpStatusCode.Parse(typeof(System.Net.HttpStatusCode), (string)(returnstatuscode.AsObject), true);  
  realstatuscode = (System.Net.HttpStatusCode)System.Net.HttpStatusCode.Parse(typeof(System.Net.HttpStatusCode), (string)(returnstatuscode.AsObject), true);  
   
   
Line 122: Line 129:
  vReturnStatusCode:='NotFound' or vReturnStatusCode:='Created' etc
  vReturnStatusCode:='NotFound' or vReturnStatusCode:='Created' etc


=== Read status code from RestPost, RestGet etc ===
=== Read Status Code from RestPost, RestGet, etc ===
Use the vReturnStatusCode:string variable name to get Status from quering others with rest - RestPost, RestGet etc.
Use the vReturnStatusCode:string variable name to get Status from querying others with rest - RestPost, RestGet, etc.


Use the vReturnMessage:string variable name to get the reasoncode from other with rest.
Use the vReturnMessage:string variable name to get the reasoncode from others with Rest.


=== Receive string content ===
=== Receive String Content ===
We assume postback data as FormFields that we match to ViewModelColumns. If someone posts string content (no form data) we now put that data in column named "STRINGCONTENT" if found.
We assume postback data as FormFields that we match to ViewModelColumns. If someone posts string content (no form data), we now put that data in a column named "STRINGCONTENT" if found.


== Debugging ==
== Debugging ==
It may sometimes be time consuming to get all the parameters correct when forming a request. A tips is to use [https://postman-echo.com] to better understand what is actually sent.
It may sometimes be time-consuming to get all the parameters correct when forming a request. A tip is to use postman-echo.com [https://postman-echo.com] to better understand what is sent.


[[Category:Rest]]
[[Category:Rest]]
[[Category:Advanced]]
[[Category:Advanced]]
{{Edited|July|12|2024}}
[[Category:TOC]]

Latest revision as of 14:13, 26 March 2024

REST Services are services executed by connecting to a URL that defines operation and parameters and returns an answer – not seldom as JSON objects.

You must set the tagged value RestAllowed on the ViewModels you want to allow Rest access to.

Calling Existing REST Services

MDriven supports a couple of EAL operators to manage REST services. All operators reside on the selfVM variable which is available only in the ViewModel context.

selfVM.RestGet(targeturl,user,pwd,optionalnestingwithheaders)

Read: OCLOperators RestGet

selfVM.RestPost(targeturl,user,pwd,optionalnestingwithheadersAndUploadValues)

Read: OCLOperators RestPost

selfVM.RestDownload(targeturl,user,pwd,optionalnestingwithheaders)

Read: OCLOperators RestDownload

Note! optionalnestingwithheaders is the name of the blue ViewModel class in the example below (as an OCL String).

Example

2018-05-29 10h31 45.png

The action GetExporttest retrieves data by converting another ViewModel to XML - it stores it in the variable vText.

The next action invokes RestPost to send that data to a URL address; it also says it should look at the nesting named 'Xml'. In this nesting, we have the STRINGCONTENT (see also OCLOperators RestPost) which gets its content from the vText variable. We also add the header Authorization with a bearer token to get access from the receiving service.

Exposing Ourselves as a REST Service

When it comes to exposing ourselves to others – Turnkey has two MVC verbs, Get and Post, like this:

TurnkeyRest/Get?command=vmname&id=rootobjref

TurnkeyRest/Post?command=vmname&id=rootobjref 

New(2023-04):
--- if you have a varible vRestVerb it is assigned the verb used 
TurnkeyRest/Put?command=vmname&id=rootobjref 
TurnkeyRest/Patch?command=vmname&id=rootobjref 
TurnkeyRest/Delete?command=vmname&id=rootobjref 

use Disable/ReadOnly expression on actions to decide what to run: vRestVerb<>'Put' -- readonly for all but Put

See Improved routes for other URLs.

The ViewModel name is supplied as the command parameter.

The id parameter is an object reference in one of several available formats. Read more here about how to create these.

Caution: Always send a complete ID, i.e. a guid or xx|yyyy. Using a shortcut without a class identifier can cause problems.

Note that the variables set in your ViewModel have to be of the String type.

The Commands Do This:

We check that the tagged value RestAllowed has been set on the ViewModel, then look up the root object.

When the ViewModel and its root have been found, we check the accessgroups to see if access is allowed.

Then additional parameters are set (these can be either URL Encoded or multi-part form-encoded. See HTTP POST for details).

  • For Get, the parameter names are looked up against ViewModel variables, and variable values are set.
  • For Post, the parameter names are looked up against ViewModel variables, and attributes and values are set.

Then any actions present at the root level of the ViewModel are executed - in the order presented in the ViewModel from top to bottom.

  • For Get, use the actions to look up additional information.
  • For Post, the actions are usually used to process sent JSON data into objects (see below)

Post saves any changed values to the database.

Both Get and Post return the ViewModel content as JSON in the HTTP response. To override this, use one of these strategies:

  1. Add a string attribute named exactly RawJSon on the root - if found, this is returned instead of the complete VM as JSON.
  2. Add a vReturnMessage:String variable as described further down this page

If there is an error, a string “error: <message>” is returned.

If you need to receive Post data unknown at design time, please read: Receive post data not known at design time.

You may use C# code to post to TurnkeyRest.

Processing JSON into Objects

If you want to send data as JSON in a POST, you need to apply the JSON string to your system's modeled objects.

Use Tajson or the simpler JsonToObjects. Read more here on XML or JSON support: Import xml and JSon with MDriven

The selfVM.JSonToObjects creates objects with the root of a class and matches attributes and associations from the JSON data – it can create object trees (unclosed graphs) by following names on associations.

selfVM.JSonToObjects( «<Type>» ,  JSonDataInStringFormat)

You can use an existing JSON as a template to create a model section you can import into - see: Using JSON or XML as a class template.

Video

To make your experience smooth, we set the main tags mentioned in the video to the right bar menu of this mini-player. Choose an interesting subtitle on the list and immediately get to the exact theme navigation item place in the video. Now you can pick any topic to be instructed on without watching the whole video.


What is REST? How does it work with MDriven Turnkey? Calling an existing REST service Exposing ourselves as REST service MDriven Turnkey app slot How to expose information as the Rest service? MDriven Rest/Get strategy How to consume data? selfvm Rest/Get operator Hard-coded objects Json to objects operator Update data with allow post RestPost operator as a post command Operation execution vSomeParam adding new parameters

Return Status Codes and Override Returned Data

New from 2020-12-09: You can now override return result data and code by declaring variables in your RestAllowed ViewModel:

vReturnMessage:String
vReturnStatusCode:String

The vReturnMessage (reason code) must be found and will be returned as content instead of the default (to make JSON of the ViewModel). The return message will have the status code "vReturnStatusCode".

If the vReturnStatusCode is found, it must have one of the values defined here: https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=net-5.0 Otherwise, 200 "Ok" is returned. We will parse the string value with this logic:

realstatuscode = (System.Net.HttpStatusCode)System.Net.HttpStatusCode.Parse(typeof(System.Net.HttpStatusCode), (string)(returnstatuscode.AsObject), true); 

This means the action code can look like this:  

vReturnStatusCode:='NotFound' or vReturnStatusCode:='Created' etc

Read Status Code from RestPost, RestGet, etc

Use the vReturnStatusCode:string variable name to get Status from querying others with rest - RestPost, RestGet, etc.

Use the vReturnMessage:string variable name to get the reasoncode from others with Rest.

Receive String Content

We assume postback data as FormFields that we match to ViewModelColumns. If someone posts string content (no form data), we now put that data in a column named "STRINGCONTENT" if found.

Debugging

It may sometimes be time-consuming to get all the parameters correct when forming a request. A tip is to use postman-echo.com [1] to better understand what is sent.

This page was edited 44 days ago on 03/26/2024. What links here