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:
{
<Routes>
<Route Url="/testGet" Method="GET" Call="Handler" />
</Routes>
}
{
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:
{
$$$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:
{
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!
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)) Quit set 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! write response.%ToJSON()
I tried to change to: return response.%JSONExport() instead of:
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.