Rest Services In MDriven
mNo edit summary
(Adding page to Category:TOC because it contains a TOC.)
 
(53 intermediate revisions by 8 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.


'''Calling existing REST services'''  
You must set the tagged value '''RestAllowed''' on the ViewModels you want to allow Rest access to.
MDriven supports a couple of EAL operators to manage REST services. All operators reside on the selfVM variable available only in the ViewModel context.
 
=== '''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)''
  ''selfVM.RestGet(targeturl,user,pwd,optionalnestingwithheaders)''
 
Read: [[OCLOperators RestGet]]
  ''selfVM.RestPost(targeturl,user,pwd,optionalnestingwithheadersAndUploadValues)''
  ''selfVM.RestPost(targeturl,user,pwd,optionalnestingwithheadersAndUploadValues)''
 
Read: [[OCLOperators RestPost]]
  ''selfVM.RestDownload(targeturl,user,pwd,optionalnestingwithheaders)''
  ''selfVM.RestDownload(targeturl,user,pwd,optionalnestingwithheaders)''
There is a also a new helper operator on selfVM:
Read: [[OCLOperators RestDownload]]
selfVM.JSonToObjects( «<Type>» ,  JSonDataInStringFormat)
The selfVM.JSonToObjects creates objects of class Type and matches attributes and association from the json data – and it can create object trees (unclosed graphs) by following names on associations. These few additions enables us to consume Rest services that others expose.


And when it comes to '''exposing ourselves to others''' – Turnkey has two new MVC verbs:
'''Note!''' ''optionalnestingwithheaders'' is the '''name''' of the blue ViewModel class in the example below (as an OCL String).
MDrivenRest/Get?command=vmname&id=rootobjref


MDrivenRest/Post?command=vmname&id=rootobjref
==== Example ====
What they do is that they look for ViewModel named as the command-parameter, if one is found 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. If it is, additional parameters sent in the url are matched against ViewModel variables – and given corresponding values. Then any actions present in the root level of the ViewModel are executed. And then the Get verb packs the viewmodel content as json in the response.
[[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 <code>vText</code>.


The Post verb looks in the request values after names that match the ViewModel root – if match is found the corresponding value is applied. Then changes – if any – are committed to db. The last thing for post is that it packs the complete ViewModel as json in the response. If there is an error – a string “error: <message>”  is returned.
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.


You must set RestAllowed on ViewModels you want to allow Rest access to.
=== 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


<html>
See [[Improved routes]] for other URLs.  
<p1>
<em>To make your experience more comfortable, we set the main tags mentioned in the video to the right bar menu of this mini player. Choose the interesting subtitle on the list and immediately get to the exact theme timeplace in the video. Now you can pick any topic to be instructed without watching the whole video.</em>
<style type="text/css">
p1 {
opacity: 0.7;
text-align: justify;
width: 90%
}
</style>
</p1>
</br>
<style>
#video12 {
  position: relative;
  padding-bottom: 10px;
}
#video12::after {
  content: "";
  display: table;
  clear: both;
}
#video12 iframe {
  width: 100%;
  min-width: 200px;
  max-width: 740px;
  height: 500px;
  float: left;
}


@media (max-width: 767px) {
The ViewModel name is supplied as the '''command''' parameter.
  #video12 iframe {
    height: 180px;
  }
}


#video12 div {
The '''id''' parameter is an object reference in one of several available formats. Read more [[The ExternalId explained|here]] about how to create these.
  float: left;
  padding-left: 10px;
overflow-y: auto;
height: 500px;
}
span.time {
    display:block;
  padding: 2px 10px 2px 10px;
    padding-bottom: 0.5em;
    padding-top: 0.5em;
  opacity: 0.7;
}
span.time:hover {
  color: #0000FF;
  cursor: pointer;
}
span.time:focus {
  color: blue;
}
</style>
</br>
<div id="video12">
<iframe width="740" height="500" src="https://www.youtube.com/embed/MKlQD8F1mz8?rel=0&autoplay=0" frameborder="0" allowfullscreen></iframe>
  <div>
    <span class="time" data-video="MKlQD8F1mz8" data-start="5" tabindex="0"> What is REST? </span>
    <span class="time" data-video="MKlQD8F1mz8" data-start="77" tabindex="0"> How does it work with MDriven turnkey? </span>
    <ul>
    <span class="time" data-video="MKlQD8F1mz8" data-start="120" tabindex="0"> calling an existing REST service </span>
    <span class="time" data-video="MKlQD8F1mz8" data-start="186" tabindex="0"> exposing ourself as REST service </span>
    <ul>
    <span class="time" data-video="MKlQD8F1mz8" data-start="239" tabindex="0"> MDriven turnkey app slot </span>
    <span class="time" data-video="MKlQD8F1mz8" data-start="328" tabindex="0"> how to expose information as the Rest service? </span>
    <span class="time" data-video="MKlQD8F1mz8" data-start="445" tabindex="0"> MDriven Rest/get strategy </span>
    </ul>
    <span class="time" data-video="MKlQD8F1mz8" data-start="568" tabindex="0"> how to consume data? </span>
    <ul>
        <span class="time" data-video="MKlQD8F1mz8" data-start="675" tabindex="0"> selfvm </span>
        <span class="time" data-video="MKlQD8F1mz8" data-start="711" tabindex="0"> Rest/Get operator </span>
        <span class="time" data-video="MKlQD8F1mz8" data-start="920" tabindex="0"> hard-coded objects </span>
    </ul>
    <span class="time" data-video="MKlQD8F1mz8" data-start="1331" tabindex="0"> Json to objects operator </span>
    <span class="time" data-video="MKlQD8F1mz8" data-start="1779" tabindex="0"> update data with allow post </span>
    <ul>
    <span class="time" data-video="MKlQD8F1mz8" data-start="1893" tabindex="0"> RestPost operator as a post command </span>
    <span class="time" data-video="MKlQD8F1mz8" data-start="2485" tabindex="0"> operation execution</span>
    <span class="time" data-video="MKlQD8F1mz8" data-start="2553" tabindex="0"> vSomeParam adding new parameters </span>
    </ul>
   
</div>
</div>


<script>
'''Caution''': Always send a complete ID, i.e. a guid or '''xx|yyyy'''. Using a shortcut without a class identifier can cause problems.  
var IMG = document.querySelectorAll('#video12 span'),
    IFRAME = document.querySelector('#video12 iframe');
for (var i = 0; i < IMG.length; i++) {
  IMG[i].onclick = function() {
    IFRAME.src = 'https://www.youtube.com/embed/' + this.dataset.video + '?rel=0&autoplay=1';
    if(this.dataset.end) IFRAME.src = IFRAME.src.replace(/([\s\S]*)/g, '$1&end=' + this.dataset.end);
    if(this.dataset.start) IFRAME.src = IFRAME.src.replace(/([\s\S]*)/g, '$1&start=' + this.dataset.start);
    this.style.backgroundColor='rgba(0,0,0,.2)';
  }
}
</script>
</html>


'''Raw subtitles text'''
Note that the variables set in your ViewModel have to be of the '''String''' type.


Rest services and MDriven turnkey, so Rest
===== The Commands Do This: =====
We check that the tagged value '''RestAllowed''' has been set on the ViewModel, then look up the root object.


is a very powerful simple way to access
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.


web services on the web and retrieving
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 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.


information from really anyone
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 vReturnMessage:String variable as described further down this page
If there is an error, a string “error: <message>”  is returned.


so there's a growing catalog of available
If you need to receive Post data unknown at design time, please read: [[Receive post data not known at design time]].


web services, that deliver rest type
You may [[Use c-sharp code to post to TurnkeyRest|use C# code to post to TurnkeyRest]].


messages just to name a few and you
===== 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.


could get the things from Spotify to get
Use [[Tajson]] or the simpler JsonToObjects. Read more here on XML or JSON support: [[Import xml and JSon with MDriven]]


artists or seek their catalog with
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 class template|Using JSON or XML as a class template.]]


resting interfaces you could call on
=== Video ===


services to upload the word documents to
<html>
<p class="warn">
  <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>
</p>
<br>
<div class="video">
  <div class="video__wrapper">
    <iframe src="https://www.youtube.com/embed/rv31ziYXWME?rel=0&autoplay=0" frameborder="0" allowfullscreen></iframe>
  </div>
  <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="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="191" tabindex="0"> Exposing ourselves as REST service </span>


get the PDF in return, you could up
    <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="450" tabindex="0"> MDriven Rest/Get strategy </span>


request the email sent in your name etc
    <span class="navigation-item" data-video="rv31ziYXWME" data-start="573" tabindex="0"> How to consume data? </span>


so it's a very powerful way to get
    <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="925" tabindex="0"> Hard-coded objects </span>


both information and functionality
    <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>


from other providers, so how does it
    <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="2558" tabindex="0"> vSomeParam adding new parameters </span>


work with MDriven turnkey, well there


actually two kinds of needs one kind
  </div>
</div>


is calling existing rest services and
</html>
 
the other one is to expose our self as
 
rest services, so we're going to look at
 
both today and there's a new article out
 
rest services and  MDriven turnkey
 
so calling an existing rest service
 
there are new ocl operators on the selfVM class
 
so you can call a target URL
 
and get data back and you can post to
 
target URL or you can download and this
 
is the case when you have requested
 
something bigger like a file being
 
produced for you or something
 
there's also a method to convert JSon
 
that you have in a string
 
to objects in your model
 
so that it will be easier to work on, with the data and with the tools
 
you know from MDriven designer and the
 
second thing that we're going to talk
 
about is exposing our selves as rest services
 
and this is actually a functionality of MDriven turnkey
 
so there's an MDrivenRest/get that
 
takes a command which actually is
 
ViewModel name and the root object and there is
 
an MDriven post and we're going to see
 
how these two simple mvc verbs will
 
actually solve, I believe,
 
all problems for us, so let's dive into
 
some example, I have this model from before
 
it resides in my MDriven turnkey 006 app slot
 
and it has a few things like show
 
all cars and once on a car you could
 
click it and view edit one car and then it has the override and I
 
don't want this in this case I'm gonna
 
remove that, I'm going to go off screen
 
so I'm back and this is the default view
 
that was rendered for us
 
given the view model that
 
looked like this, right, so what we can do now
 
is to try an access this information
 
try to expose this same information as the rest service
 
in order to do that, we need to select
 
the head of the view model and set this new property
 
this is initially false, but if we want a
 
view to act as a data source available
 
from a Rest request, we need to set Rest
 
allowed to true like that and once we have done that I'm also
 
gonna add and remove this action just
 
not to confuse we're going to come back to this later
 
so you're setting a comment on this one
 
and it should do judt something to be okay
 
we're gonna leave it like that and so
 
can we turn this information as rest
 
well now we have said it allow, said that
 
it was allow Rest, so we're going to
 
upload that, so that our turnkey site
 
works on this view model and check status
 
and we're done to get this, we could
 
simply try an access our site with the
 
new strategy that was said here MDrivenRest/get
 
like this, like so, but we want to have this view model and this
 
root object,so let's paste in the view
 
model name and the root object reference
 
that shouldn't be there, like this
 
executing that returns our data as a Rest
 
document, so let's check this out
 
registration number F F X Y if I were to
 
change it here to my new car is FPT128
 
that's really cool, because that's
 
almost as ftp and 128 is really
 
important number to me because it's well
 
binary and so I'm quite happy with my
 
registration number on your card that's
 
that's finally one I can remember and
 
save that and as I have saved that and
 
hit this one again, I can see that it updates
 
ok so this is one way to expose ourselves as a rest service
 
let's try and consume ourselves that
 
sounds weird, but what I mean is that we
 
could add a viewmodel, well if I'm not
 
locked by the model dialogue, let's add a
 
new view model and let's call this
 
consume our self, weird and going to root that in car and say that
 
let's add a class action for show
 
meaning that whenever we see a car there
 
should be an action that could take us
 
here, having done that I should see
 
that there is a class action car
 
view consume self and if I would wanted to fix
 
up that action I could do that here
 
calling it something else but
 
this is fine so what I want to do here
 
is I can add the registration number
 
just to see that, we have it and
 
then I could add a column prepared for action which really is
 
generic column with this one checked and
 
try and get by rest, so that's an action
 
that we're gonna call to try and consume
 
to get this information, so basically we
 
would want to do this in here
 
and selfvm is the one that has the new
 
rest operators, rest get and I'm not
 
been a little fast, because rest get
 
If I point at this I see the tooltip stating that
 
the first argument is the target URL
 
then it's a user and the password and
 
then it's the name of a nesting so for
 
now I'm just going to use the target URL
 
as the first param I'm going to leave the
 
other ones blank, so paste in that blank
 
blank the password and the nesting blank
 
and I didn't chose it correctly, so rest get, ok, so but that yes return
 
something that we need to store it somewhere
 
let's add a veriable to do this
 
viewmodel just to show on the root
 
I'm gonna do add variable which means
 
that again one new hear, can call it
 
that it's a string in here I can assign
 
the return value to this like this
 
then I could add a generic column with
 
the expression of the value of the new
 
variable, so we don't get confused going
 
to make this a little bigger like this, so what I want to do is to
 
push this button and I want to get this
 
information in this variable, can I do that
 
well, I'm uploading the model
 
check status and then I close it
 
and then I head back here and no
 
that's not the place, here and I refresh
 
this one, so we got a new action
 
view consume ourselves, right, sounds weird but
 
let's do it, I'm going to press ctrl to
 
get a new tab, fault I did test that again
 
press ctrl ok there's something wrong
 
with my language settings of the
 
control keys and targeted, so this is
 
the registration number and trying
 
get Rest and I get the same information right but as you note
 
this was like hard-coded to one specific card
 
the root ID which would mean that
 
doesn't really matter, what car I took
 
in here, if I took this one 12345 and
 
consume I would still get the ftp car
 
because that was hard-coded in here
 
so instead of doing this I would like to
 
just add the self, as I'm rooted,
 
the views was rooted in a car
 
externalid like that,  in that way
 
it would be new data for each,
 
for the rooted object, let's try that out
 
upload and refreshing it
 
okay, it wasn't done, refreshing it again, it was done
 
try and get by rest and now we see that
 
it is updated, now let's see what happens
 
if I change this, seven,and what should
 
happen when I try and get by rest well let's see what happens
 
it returns the same thing
 
why because I haven't saved yet so this
 
is running in its own and this is a new
 
query against the database and the data
 
that's actually in the database not the
 
data that this session is changing, so if
 
I save this and then press this one I
 
get the "seven" right nothing strange about that
 
and just important to know that the
 
rest operations running their own space
 
ok just to ensure that we could call anyone
 
let's do, let's copy this one and put it
 
below and call it get stuff from spotify by
 
I was on the spotify developer page
 
finding out how to formulate a query and I have it here
 
so and it says query - Metallica and
 
type- artist so that would assign it
 
to the new variable as well that would
 
be fine just testing, uploading and
 
refreshing get stuff from Spotify that
 
we get a bunch of data from from there
 
if we would want to do more advanced
 
stuff with this like here we let's see
 
what is the data want to copy that copy
 
and I'm gonna bring it up in the most
 
versatile tool yet ever invented, the notepad
 
yeah, whatever artists' it says it has a
 
link with artists that goes to here
 
no here is this one
 
well it might not be the most brilliant tool
 
this not bad anyhow, but what I want
 
to do is to be able to read some of the
 
things here like, I want to convert it to
 
objects and these are properties of
 
the artists object, so and how would I go about that
 
well I could use the new operator self
 
selfVM was calling something with
 
Json to objects and it takes a
 
type and a string with Json, the type is
 
actually what kind of root object it
 
should create from the Json and let's see
 
and let's just say that we don't have
 
that yet, but we have this one it's the
 
vNew variable, but we need to have
 
somewhere where to store the date
 
that we get, let's add a new diagram or
 
rather just do it here and a class data
 
from spotify and class artist
 
that has the relation called artist
 
why, because that what it was
 
called in the data, so like that and we
 
want to get this attribute maybe that we
 
need to match it with an attribute here
 
and items we might not care about
 
let's see how does this data
 
it has a name, so going to add that as well,
 
so this is the objector we could create and then
 
it will follow the data and create these as
 
well that's the general ID idea like that data from spotify
 
take the values from there and just to
 
see turn into object call this one
 
and how can we verify that it works
 
add the nesting this one going
 
to be our test all instances right and
 
it's gonna be hooked up to it this one
 
call this one artist and the type will
 
be artist as well and we grab the
 
properties that we have in it href and the name
 
let's see how this will work out for us
 
again upload check that we're done
 
now it's great that the table for the artist
 
and things like that, so no need to call
 
the DBA today, we can manage ourselves
 
opening up this one consume
 
ourelves and get stuff from Spotify and
 
turn into objects and it found and href
 
but it couldn't match to query metallic
 
offset let's do the same question hereitems, images
 
these are only images , so it's all the way down here maybe, no
 
that's another one, okay I'm gonna figure this out I'm going off screen
 
ok now I think I got it, it's the items
 
property that holds all the results so
 
for this to work we would need to
 
actually introduce something in between
 
here called the result set and there is
 
the one that holds to our tests and
 
then there would be an association here
 
called items, this is how this data
 
looks, so upload that instead
 
good thing I didn't involve the DBA
 
because he would rip my head off because
 
I haven't checked thoroughly enough
 
before asking him to do work for me
 
so cancel and refresh this one, get stuff
 
from Spotify turn into objects
 
metallica, metalica with Ozzy Osborne,
 
Lou Reed right so I could choose to save
 
this and then I would have those objects
 
and that would be some kind of reference
 
data for my system to work with or
 
consider to make this class transient
 
and ask for it every time
 
still you can do anything you need with
 
this strongly typed information once you
 
have the reference it from from the Json
 
right that was then turn into objects
 
Json turning to objects operator,Json to
 
objects and is there anything left to
 
show you, yes you will want to allow post
 
to your own data, so what if we try and
 
get by Rest and we want to post back a
 
new registration number or other
 
just want to post back a new
 
registration to update supervine
 
let's add a veriable to have hold the new
 
registration number, vNewRegNum  okay
 
and let's add a cgeneric column that has
 
that expression and let's not call it
 
exact the same thing as the other one
 
because that's not allowed and put it
 
put it here and put it below and I'm
 
gonna make it smaller and below, like that
 
yep that's fine, that's fine
 
so I have a new registration number, now


I actually want to post that back to my
=== 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:


rest post, I want to send back to
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".


myself, so we need an action for that
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


it sort of looks like this one,
=== Read Status Code from RestPost, RestGet, etc ===
Use the vReturnStatusCode:string variable name to get Status from querying others with rest - RestPost, RestGet, etc.


UpdateRegNumViaRestPost ok going to change this one
Use the vReturnMessage:string variable name to get the reasoncode from others with Rest.


to rest post, bring up that view editor
=== 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.


with some expression just to check
== 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 [https://postman-echo.com] to better understand what is sent.


how does it selfVM.RestPost it has
four parameters all strings, target URL
user password and name of nesting ok
what it says after in the end is
adds data in nesting and it also says that
file name underscore something
with upload that something column with
filename from filename underscore something,  so that's
advanced we will leave that for later
but what it says that it needs a
nesting to hold the data that we
gonna post up, so assume that we call
that nesting data to post
published and we send that in and then
we add other nesting and we say it's data to post
and it's of type
well it don't care really because we're
going to add the variable at the generic
column and in this column
we're gonna use variable vNewRegNum
like that and now it's important
that what we're going to post up we're
going to post it to this view model called edit one car
ok, so that's add it one car, but what
what does it expect, well edit
on car has these properties, this is what
what will be exposed as the rest
what we can set by rest registration
number it's called right, so we head back
to the consume and we call this one
registration... no I was wrong, ctrl+z to call this one registration
so what we say here is that and grab
grab do rest post to ourselves, but this could
be anywhere, because we got the full URL
on the command "edit one car" with ID
as ourselves the rooted object
from this view that we are in and use
data to post nesting, to get data
so it will upload a multi-part rest
message with at least this column
registration number and set to the
variable that we have assigned our
variable and after that it will get the
return result and how rest post works in
and MDriven is that it will return the
complete as from get, if everything is ok
so that is enough to try it out
upload model, check status, done refresh
so now we have this registration number and if we will get
to get it we see that it's this one and
we set something else so now our variable has
the value something else and we try to
update the registration number by
calling a post request back to ourselves
seems like nothing happened, going off screen
ok I'm back and I figured the problem out
and actually this when I say data to
post it's important that its existing
as a name here, so it will be found so
self and back is associated to the data post
this this is small screen here
well, this one goes up here come back here
maybe we should do something like this
to better fit on the screen
that was the first error but I did another thing wrong as well in my
URL even if I said that it was the
command rest post, which will be
a post command on I actually had from the
copypaste to get verb on our server
our server thought, that well I'm not
gonna post anything because this is a get
so no data was actually applied, so having fix those things and
of course it's just common sense when
you post you need to go to
the post endpoint and when you get you do it
from the get endpoint and once that is done
and I uploaded the model with
those changes I get refresh the view
I can now enter something else on
the registration number and update via
post and this one is returned with registration numbers
something number something else
so we have shown how we can expose
ourselves as rest services and we have
also shown how we can update via rest
services we have shown how we can
consume others how we can consume the
JSon result from others to create the objects in our model and
what's left well one cool thing that we need to show
is the ability to actually execute
operations because this becomes
important if you want to do delete maybe
some kind of complex operation on
your data before returning, actually it's
quite easy and we saw it already because
I had it in the test sample I guess
on the one that we have enabled rest for
allow rest- edit one car we can have it
actions all actions available on the
root level will actually be executed
they will be executed on gets and they
will be executed on posts, so this is important to remember
we can actually do stuff here, so remember
if I've commented this out before you
comment it back again, so what it says here is that
registration number should equals itself
plus something and here it says some
param and this is another important
aspect that we can send in more
parameters on the command line or on the URLs
parameters, HTML parameters, so what is
this that's actually just a veriable
defined here with some param as string
and that would be nothing I guess if we
don't have a default value, let's set the
default value, something and upload model
and this reloads something else
is registration number
and we got this, we didn't get the default value
let's see if I put that wrong I
can't really remember with default value
is going, think it's going in the other one
uploading the model off-screen, refreshing this
what happened now, unbracket, check
status and that probably wasn't a good place to
have it and see if everything is work
you see localhost I'm in the
wrong place,something else
something else, oh and apparently I shouldn't have had
their asteriskes that so the value is
actually something else, but since the
action executes before it returns from
the get it appends this so this isn't
actually saved, but what if I were to do the same on the post
well I say that the new registration
number should be www and update
I sort of expected that to become
and never mind
so can we change this value to
something else by sending in something
else on that URL
yes, we can consume ourselves and we
have this place here and we can just
send in let's add some more parameters
and they are separated by n and we call
that one well now the short-term memory problem
appears I don't remember
what do we call it, on card call it
vSomeParam, consume, hello,
so I can send data and one that's actually
interesting, didn't update if anyone can
help me find that error, ok and back here
upload and trying it rest,now it's hello
because that's what we sent on that we
sent on on the command line or a day in
the URL alright so this is a short introduction
on how to work with them rest interfaces
both consuming information from others
and exposing information from ourselves
and it's quite powerful and you can do a
lot of things and it's good when
integrating both functionality and
information services into your system
[[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 55 days ago on 03/26/2024. What links here