Question how to get JSON-response back to web-service/client
Hello everyone!
I have manually created a REST-service that receives incoming HTTP-GET calls together with an URL-map. As shown below:
XData UrlMap [ XMLNamespace = "https://www.intersystems.com/urlmap" ]
{
<Routes>
<Route Url="/testGet" Method="GET" Call="Handler" />
</Routes>
}
ClassMethod Handler(req As %Stream.Object) As %Status
{
set Class = ##class(Ens.Request).%New()
set status = ##class(Ens.Director).CreateBusinessService("TestService", .instance)
set status = instance.OnProcessInput(Class, .response)
if $ISOBJECT(response)
{
write response.%ToJSON()
}Quit $$$OK
}
Through the code above I am utilizing a service that I have created as well, as shown here:
Method OnProcessInput(pInput As Ens.Request, Output pOutput As %RegisteredObject) As %Status
{
$$$LOGINFO("inside service")
set req = ##class(Ens.Request).%New()
set tsc = ..SendRequestSync(..TargetConfigName, req, .tResponse)
set pOutput = tResponse
Quit tsc
}
With this code I send a request to another Operation that I have created:
Method PostMessage(pRequest As Ens.Request, Output pResponse As %RegisteredObject) As %Status
{
set pResponse = {"responseText":"Hello world!"}
return pResponse
Quit $$$OK
}
Now, my real question is how can I get the pResponse which is {"responseText":"Hello world!"} to get returned back to my webservice and printed out in Postman? I have tried the principle that is followed here: Creating a RESTful Service using Ensemble | InterSystems Developer , and that worked perfectly fine. But I cannot make it work if I take it a step further and try to retrieve the response from the Operation. In Postman I receive a 200 OK, but in the service this error is logged:
ERROR <Ens>ErrException: <METHOD DOES NOT EXIST>zqueueRequestSync+39 ^Ens.Host.1 *%OpenId,%Library.DynamicObject -- logged as '-'
number - @''
Thanks Beforehand for all the help!
Comments
Here you can see an example:
ClassMethod ImportRawMatches() As%DynamicObject
{
Try {
Do##class(%REST.Impl).%SetContentType("application/json")
If '##class(%REST.Impl).%CheckAccepts("application/json") Do##class(%REST.Impl).%ReportRESTError(..#HTTP406NOTACCEPTABLE,$$$ERROR($$$RESTBadAccepts)) Quitset newRequest = ##class(QUINIELA.Message.OperationRequest).%New()
set newRequest.Operation = "Import"set status = ##class(Ens.Director).CreateBusinessService("QUINIELA.BS.FromWSBS", .instance)
set response = ##class(QUINIELA.Message.ImportResponse).%New()
set response.Status = "In Process"set response.Operation = "Import"set status = instance.SendRequestAsync("QUINIELA.BP.ImportBPL", newRequest, .response)
if$ISOBJECT(response) {
Do##class(%REST.Impl).%SetStatusCode("200")
return response.%JSONExport()
}
} Catch (ex) {
Do##class(%REST.Impl).%SetStatusCode("400")
return ex.DisplayString()
}
The key is this row:
return response.%JSONExport()Hello Luis and thank you so much for your answer!
I tried to change to: return response.%JSONExport() instead of: write response.%ToJSON()
But I still get the error in the service. I can't see what is wrong.
Try extending your response from %JSON.Adaptor
I will try it! Thank you so much for the help! :)
Basically %JSONExport() API method only works if you're class definition extends with %JSON.Adaptor. class You can even use the below to write your JSON response in UI
do##Class(%REST.Impl).%WriteResponse(response)I don't typically use Ensemble for my REST services, but I do see a couple of things.
First, in the documentation you linked to, pOutput is a %DynamicObject, not a %RegisteredObject. %RegisteredObject does not have a %ToJSON() method.
Second, in your PostMessage method, the line "return pResponse" shouldn't be there.