WinBatch® Technical Support Forum

All Things WinBatch => WinBatch => Topic started by: kdmoyers on July 08, 2025, 04:51:13 AM

Title: Examples of RESTful calls?
Post by: kdmoyers on July 08, 2025, 04:51:13 AM
I was sure I'd find some examples of consuming a REST api in the tech database, but I'm coming up empty. What should I be searching for?
Title: Re: Examples of RESTful calls?
Post by: spl on July 08, 2025, 08:41:57 AM
Restful calls usually return json.  I know I have posted several examples. Whether or not they got to Tech DB would be up to Tony. But for fun try below and check return
cUrl = "https://query1.finance.yahoo.com/v7/finance/quote?symbols=IBM,GOOG,AAPL"
request = Createobject("WinHttp.WinHttpRequest.5.1")
request.Open("GET", cUrl, @False )
request.Send()
json = request.ResponseText
ObjectClose(request)

Title: Re: Examples of RESTful calls?
Post by: td on July 08, 2025, 08:44:59 AM
I am not sure how to answer that one. There are several examples, but they tend to be associated with specific tasks. I know Stan has posted examples over the years. Many REST API providers have examples in Curl. Curl translations to WIL are generally straightforward.

REST API usage typically involves a combination of POST and GET HTTP verbs, utilizing JSON as the data format. HTTP headers are almost always required as well. 

I imagine you already know HTTP and HTML basics, but this longish tutorial is a good way to brush up.

https://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+Tutorials+HTTP~and~WinInet~-~An~Opus.txt (https://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+Tutorials+HTTP~and~WinInet~-~An~Opus.txt)

Here is a dummy example that may be of some use:
objHttp=ObjectCreate("Msxml2.XMLHTTP.6.0") ;WinHttp.WinHttpRequest.5.1") ; MSFT keeps Msxml2 in better shape.

URL = "https://your.api.url.here/maybe some more required here"
objHttp.open("POST",URL,"False")
objHttp.SetRequestHeader("Authorization", "Bobs-Auth-Key some long 64bit number or something here" )    ; Put your key here!
objHttp.SetRequestHeader("User-Agent", "MyApp/1.1.1") ; Put your "app" name here!
objHttp.SetRequestHeader("Content-Length", "71")   ; Set the data length in bytes here
objHttp.SetRequestHeader("Accept", "application/json")
objHttp.SetRequestHeader("Content-Type", "application/json")   
Body = `{"whatever":["some json key":some json value}`
objHttp.Send(body)
while objHttp.readyState != 4
   objHttp.WaitForResponse(10)
endwhile
Terminate(objHttp.Status != 200,"REST API", "You didn't do it correctly or the server is down")

strJson=objHttp.responseText
; You can use the JSON extender to extract the returned results.

This forum likely has a few better examples, if you can find them.
Title: Re: Examples of RESTful calls?
Post by: spl on July 08, 2025, 08:57:51 AM
and for more fun, here is an older script (probably pre-dates Json Extender, when ScriptControl object could be used to parse Json). Uses CLR instead of COM.
;Based on Tony's code to obtain Yahoo finance for multiple stocks; returns Json
IntControl(73,1,0,0,0)
Gosub udfs
symbols =  "IBM,GOOG,AAPL"
strUrl = "https://query1.finance.yahoo.com/v7/finance/quote?symbols=%symbols%"
ObjectClrOption('useany', 'System')
objWebUtil = ObjectClrNew('System.Net.WebUtility')

objUri = ObjectClrNew('System.Uri', strUrl)
objSvcManager = ObjectClrNew('System.Net.ServicePointManager')
protocols = ObjectClrType("System.Net.SecurityProtocolType",3072|768) 
objSvcManager.SecurityProtocol = protocols
objSvcPoint = objSvcManager.FindServicePoint(objUri)

objWebRequest = ObjectClrNew('System.Net.WebRequest')
objWebRequest = objWebRequest.Create(objUri)
objWebRequest.Timeout = objWebRequest.Timeout * 5
objResponse = objWebRequest.GetResponse()
objResponseStream = objResponse.GetResponseStream
Encoding = ObjectClrNew( 'System.Text.Encoding' )
objStreamReader = ObjectClrNew("System.IO.StreamReader", objResponseStream, Encoding.UTF8)

;convert json to comma-delimited file

strOut = 'c:\temp\Output.Json'
if FileExist(strOut) then FileDelete(strOut)
jdata = StrReplace(objStreamReader.ReadToEnd(),",",",":@LF)

Message("",Jlen(jdata))

output = GetJSON1(jdata)
hdr = "Key":@TAB:"Subkey":@TAB:"Value":@LF
output = hdr:StrReplace(output,",",@TAB)  ;change to Tab-delimited
FilePut(strOut, StrReplace (output, @LF, @CRLF))
if FileExist(strOut) then Display(2,'Json Data', strOut)
if FileExist(strOut) then Run('notepad.exe', strOut)
Exit


;=========================================================================================
:WBERRORHANDLER
Terminate(@TRUE,"Error Encountered",err())

:udfs
#DefineFunction err()
wberroradditionalinfo = wberrorarray[6]
lasterr = wberrorarray[0]
handlerline = wberrorarray[1]
textstring = wberrorarray[5]
linenumber = wberrorarray[8]
errmsg = "Error: ":lasterr:@LF:textstring:@LF:"Line (":linenumber:")":@LF:wberroradditionalinfo
Return(errmsg)
#EndFunction


#DefineFunction GetJSON(jdata)
If jdata == "" Then Return ""
objJSC = CreateObject ("MSScriptControl.ScriptControl")
objJSC.Language = "JScript"
;objJSC.AddCode(: `function json2txt(obj,path){var txt='';for(var key in obj){if(obj.hasOwnProperty(key)){if('object'==typeof(obj[key])){txt+=json2txt(obj[key],path+(path?'|':'')+key);}else{txt+=path+'|'+key+','+obj[key]+'\n';}}}return txt;}`)
code = $"
function json2txt(obj)
{
  var txt = '';
  var recurse = function(_obj) {
    if ('object' != typeof(_obj)) {
      txt += ',' + _obj + '\n';
    }
    else {
      for (var key in _obj) {
        if (_obj.hasOwnProperty(key)) {
          txt += key;
          recurse(_obj[key]);
        }
      }
    }
  };
  recurse(obj);
  return txt;
}
$"
objJSC.AddCode(:code)
Return objJSC.Eval(: `json2txt(` : jdata : `,'')`)
; JS code from Patrick Fisher at "http://stackoverflow.com/questions/10221229/list-all-keys-and-values-of-json" ; 2012-04-19T03:48:24.
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction Keys(jdata)
If jdata == "" Then Return ""
objJSC = CreateObject ("MSScriptControl.ScriptControl")
objJSC.Language = "JScript"
objJSC.AddCode(: `function getKeys(obj,path){ var keys = new Array(); for (var i in obj) { keys.push(i); } return keys; }`)
Return objJSC.Eval(: `getKeys(` : jdata : `,'')`)
#EndFunction

#DefineFunction JSONDecode(jdata)
   objJSC = CreateObject ("MSScriptControl.ScriptControl")
   objJSC.Language = "JScript"
   data = objJSC.Eval(: `(` : jdata : `)` )
   Return(data)
#EndFunction


#DefineFunction Jlen(jdata)
   objJSC = CreateObject ("MSScriptControl.ScriptControl")
   objJSC.Language = "JScript"
   code = $"
   function Keylen(jsonObj) {
   var keys = '';
   for (var n in jsonObj) {
   keys += n + '|' ; }
   return keys;
   }
   $"
   objJSC.AddCode(:code)
   Return objJSC.Eval(: `Keylen(` : jdata : `,'')`)
#EndFunction

#DefineFunction UnixDate(d,ms)
   If ms Then d="00":d
   Ymd = TimeAdd('1970:01:01:00:00:00', d)
   Ymd = TimeFormat(Ymd,"MM/dd/yyyy")
   Return(Ymd)
#EndFunction

#DefineFunction GetJSON1(jdata)
If jdata == "" Then Return ""
objJSC = CreateObject ("MSScriptControl.ScriptControl")
objJSC.Language = "JScript"
code = $"
function json2txt(obj,path){
   var txt='';
   for(var key in obj){
      if(obj.hasOwnProperty(key)){
         if('object'==typeof(obj[key])){
         txt += json2txt(obj[key],path+(path?''::'')+key);}
         else{txt+=path+','+key+','+obj[key]+'\n';}
      }
   }
   return txt;
}
$"
objJSC.AddCode(:code)
Return objJSC.Eval(: `json2txt(` : jdata : `,'')`)
; JS code from Patrick Fisher at "http://stackoverflow.com/questions/10221229/list-all-keys-and-values-of-json" ; 2012-04-19T03:48:24.
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------
Return
Title: Re: Examples of RESTful calls?
Post by: spl on July 08, 2025, 10:53:46 AM
As PS has Invoke-RestMethod as a cmdlet, here is the simplest STD_Out script I could put together in 2-3 minutes to illustrate.

OT: but if you think about it, I have posted multiple Std_out scripts all with the same scenario

Now if the single UDF could be called from a data source holding fields for Description of Process; the argument; the list of replace; and the outcome... easy to create a dropdown list for conversions involving
db sources
csv
excel
json
xml
yaml

into a single script. {I've thought about it}
;Rest Query for IP Address
;Stan Littlefield 7/8/2025
;==========================================================
Gosub udfs

args = $"
$IPAddress = (curl -uri "http:://ifconfig.me/ip").Content
$LocationInfo = Invoke-RestMethod -Method Get -Uri "http:://ip-api.com/json/$IPAddress"
$LocationInfo
$"
cmd="Powershell"
msg='IP Address

BoxOpen("Running...",cmd:" ":args:@LF:"PLEASE WAIT...MAY TAKE SOME TIME")
TimeDelay(2)
vals = Get_stdout():@LF:"Script Completed"
Message(msg,vals) 

;If FileExist(xml) Then Run("notepad.exe",xml)
Exit
;==========================================================
:udfs
#DefineSubroutine Get_stdout()
ObjectClrOption("useany","System")
objInfo = ObjectClrNew("System.Diagnostics.ProcessStartInfo")
Output=""
timeOut = ObjectType("I2",5000)
objInfo.FileName = cmd
objInfo.RedirectStandardError = ObjectType("BOOL",@TRUE)
objInfo.RedirectStandardOutput = ObjectType("BOOL",@TRUE)
objInfo.UseShellExecute = ObjectType("BOOL",@FALSE)
objInfo.CreateNoWindow = ObjectType("BOOL",@TRUE)
objInfo.Arguments = args
oProcess = ObjectClrNew("System.Diagnostics.Process")
oProcess.StartInfo = objInfo
BoxShut()
oProcess.Start()
oProcess.WaitForExit(timeout)
STDOUT = oProcess.StandardOutput.ReadToEnd()
STDERR = oProcess.StandardError.ReadToEnd()
Output = Output:STDOUT:@CRLF
If STDERR<>""
   Output = Output:"STDERR:":STDERR:@CRLF
Endif
oProcess = 0
objInfo = 0

Return (Output)
#EndSubroutine
Return
;==========================================================
Title: Re: Examples of RESTful calls?
Post by: spl on July 08, 2025, 11:16:41 AM
Finally, here is a real fun one... try this in your browser, then write WB code to translate the json

https://api.funtranslations.com/translate/morse.json?text=hello
Title: Re: Examples of RESTful calls?
Post by: td on July 08, 2025, 02:40:54 PM
I must be missing something again. It seems trivial to extract the values.
Title: Re: Examples of RESTful calls?
Post by: td on July 08, 2025, 02:41:48 PM
For Example,
AddExtender('ilcjs44i.dll', 0, 'ilcjs64i.dll')
Mesage = 'Faliure to launch'
Data = $"{
    "success":: {
        "total":: 1
    },
    "contents":: {
        "translated":: ".... . .-.. .-.. --- ",
        "text":: "hello",
        "translation":: "morse"
    }
}$"

if jsValid(Data)

   h = jsParse(Data)
   nTotal = jsValueGet(h,'success.total')
   if ntotal

      hCon = jsValueGet(h,'contents')
      Text = jsValueGet(hCon,'text') 
      Lang = jsValueGet(hCon,'translation')
      Translation = jsValueGet(hCon,'translated')
      Mes = 'Morris code for "':text:'" is "':Translation:'"'
   endif
   Pause('Translation', Mes)   
endif

jsConClose()
exit
Title: Re: Examples of RESTful calls?
Post by: spl on July 09, 2025, 02:26:04 AM
Quote from: td on July 08, 2025, 02:40:54 PMI must be missing something again. It seems trivial to extract the values.

It is with the Extender [shout out]. I was thinking more of getting the json with a Rest request, then parsing w/out prior knowledge of the node names. But I think Kirby has enough to work with.
cUrl = "https://api.funtranslations.com/translate/morse.json?text=hello"
request = Createobject("WinHttp.WinHttpRequest.5.1")
request.Open("GET", cUrl, @False )
request.Send()
json = request.ResponseText
ObjectClose(request)
Message("Response",json)

;then add you json Extender parsing
Title: Re: Examples of RESTful calls?
Post by: kdmoyers on July 09, 2025, 09:14:04 AM
So much goodness!!! thanks guys!!
-K
Title: Re: Examples of RESTful calls?
Post by: spl on July 09, 2025, 12:09:57 PM
Quote from: kdmoyers on July 09, 2025, 09:14:04 AMSo much goodness!!! thanks guys!!
-K

You are most welcome. Below is a free/useful source to practice with, and an excellent workout for the Json Extender.
https://mixedanalytics.com/blog/list-actually-free-open-no-auth-needed-apis/