Question
Mark O'Reilly · Jan 25, 2021

Simple posting of REST Body to api

Hi:

I've looked on many of these examples and questions how to post the JSON body but all the posts are a little complexly worded for me to follow. 

so i have an EnsLib.REST.Operation

The example in ENSDEMO Directory Request says 

Set tSC=..Adapter.PostURL(tURL,.tHttpResponse,"",pRequest.Body)

What i can't see is how in Demo Rest Directory request it happens to get the value of the message fields into 

/// For JSON content submission
Property Body As %GlobalCharacterStream;

I have also played around with converting objects to JSON ect.  All i want to do is post an example like this to the API

{
  "Employee": 1,
  "UserName": "sample string 1",
  "ModuleName": "sample string 2",
  "CompletionDate": "2021-01-25T16:19:52.6560565+00:00",
  "Source": "sample string 4"
}

I'm just trying with a string atm 

Request class 

Parameter RESPONSECLASSNAME = "LMS.ELearningAPIResponse"; // Property Command As %String [ InitialExpression = "POST" ]; /// ESR Employee Number
Property Employee As %String; /// Username from LMS
Property UserName As %String; /// The name of the course/module from the LMS.
Property ModuleName As %String; /// This is the date the person completed this course/module.
Property CompletionDate As %String; /// The source of the e-Learning result, if left blank, the ADAccount prooviding the message will be used.
Property Source As %String; /// For JSON content submission
Property Body As %GlobalCharacterStream;

 

Operation class so far- connects but results in error believed as the body is incorrect 

Method OnMessage(pRequest As LMS.ELearningAPIRequest, Output pResponse As LMS.ELearningAPIResponse) As %Status
{
set tsc=$$$OK
//Set tCmd=$ZConvert(pRequest.Command,"U")
//If tCmd = "POST" {
//as a guess the URL will be the URL only and the body goes into the body
Set tURL=..Adapter.URL
//need to put the values into pRequestBody
//post the rest URL
//set JsonStore=##class("%ZEN.Auxiliary.altJSONProvider").%WriteJSONFromObject(.JsonStore,pRequest)
Set tSC=..Adapter.PostURL(tURL,.tHttpResponse,"",pRequest.Body) // from the Rest Demo
Set:$$$ISERR(tSC)&&$IsObject(tHttpResponse)&&$IsObject(tHttpResponse.Data)&&tHttpResponse.Data.Size tSC=$$$ERROR($$$EnsErrGeneral,$$$StatusDisplayString(tSC)_":"_tHttpResponse.Data.Read())
//??
Set tSC1=pRequest.NewResponse(.pResponse) Set:$$$ISERR(tSC1) tSC=$$$ADDSC(tSC,tSC1)
//update session ID in response
Set pResponse.SessionId=..%RequestHeader.SessionId
//update request url in rsponse
Set pResponse.RequestURL="Post "_tURL //update the raw response
If $IsObject(tHttpResponse) {
Do pResponse.RawResponse.CopyFrom(tHttpResponse.Data) Do tHttpResponse.Data.Rewind()
Set pResponse.Value=tHttpResponse.Data.Read() ; count
}
//}
 
 
 quit tsc
}

 

Product version: Caché 2016.1
00
2 0 2 82
Log in or sign up to continue

Replies

You were on the right track with %WriteJSONFromObject(), but you'll want to use %WriteJSONStreamFromObject() instead. I don't see what purpose the Body property in your request class serves. You can just create a stream object variable instead.

set myTempStream=##class(%Stream.GlobalCharacter).%New()
set tSC=##class("%ZEN.Auxiliary.altJSONProvider").%WriteJSONStreamFromObject(.myTempStream, pRequest)
if $$$ISERR(tSC) {
    quit tSC
}

...then later:

Set tSC=..Adapter.PostURL(tURL,.tHttpResponse, , myTempStream)

Thank you. I think I had something along these lines and then due to /text html being returned went back on this. 

This is developed on 2016.1 So i can't easily exlude the _id and another property from JSON. It's not may tidy but it works

Set Body = ##class(%ZEN.proxyObject).%New()
  Set Body.Employee = pRequest.Employee
  Set Body.UserName = pRequest.UserName
  Set Body.ModuleName = pRequest.ModuleName
  Set Body.CompletionDate = pRequest.CompletionDate
  Set Body.CompletionDate = pRequest.CompletionDate
  Set Body.Source= pRequest.Source

Looking at it new JSON when we upgrade very soon it could be a lot tidier. 

The main stumbling block was all the responses i read use their own HTTP adapters. As soon as had class extending Ens.BusinessOperation, Ens.Util.JSON and using it's own adapter extending Enslib outbound like below it worked

Method PostURL(pURL As %String, Output pHttpResponse As %Net.HttpResponse, pFormVarNames As %String, pData...) As %Status [ CodeMode = expression ]
{
..SendFormDataArray(.pHttpResponse, "POST", ..GetRequest(), .pFormVarNames, .pData, pURL)
} ClassMethod GetRequest() As %Net.HttpRequest
{
    set request = ##class(%Net.HttpRequest).%New()
    set request.ContentType  = "application/json"
    quit request
}