Written by

Question Yone Moreno · Oct 23, 2023

What is the recommended way to convert a %Stream.Object to a Ens.Response message?

Hello,
First of all thanks for your help.

We have developed a REST Operation. We wonder how could we face that String do have a character limit.

We just need to convert httpRequest.HttpResponse , which is a stream , because $isobject(response.Data) returns 1; which has a JSON inside it, and we need to convert it to a Ens.Response.

This response is structured as same as the JSON's properties: 

Class Mensajes.Response.Radiologia.CConcertados.BusquedaOrdenesNEGRINResponse Extends Ens.Response
    {

    Property data As list Of EsquemasDatos.CConcertadostoPACS.Radiologia.BusquedaOrdenes;

    ...

  

Class EsquemasDatos.CConcertadostoPACS.Radiologia.BusquedaOrdenes Extends (%SerialObject, %XML.Adaptor)
    {

    Property"ID_SICH"As%String(MAXLEN = "");Property"FECHA_DERIVACION"As%String(MAXLEN = "");Property"MEDICO_PETICIONARIO"As%String(MAXLEN = "");

    ...

We have developed it as:
    

Class Operaciones.REST.Radiologia.CConcertadosOrdenesNEGRINv01r00 Extends EnsLib.REST.Operation
    {

    Parameter INVOCATION = "Queue";

    Method BusquedaOrdenes(pRequest As Mensajes.Request.Radiologia.CConcertados.BusquedaOrdenesNEGRINRequest, pResponse As Mensajes.Response.Radiologia.CConcertados.BusquedaOrdenesNEGRINResponse) As%Library.Status
    {
        //Creamos Request y Response HTTPSet httpRequest=##class(%Net.HttpRequest).%New()
        set tResponse = ##class(%Net.HttpResponse).%New()
        set claseAux = ##class(%ZEN.Auxiliary.jsonProvider).%New()

        set URL        = ..Adapter.URL

        set httpRequest.SSLConfiguration = ..Adapter.SSLConfig
            
        $$$LOGALERT("URL: "_URL)    

        // El body va rellenoset httpRequestBody = ""//Convertimos el OBJETO devuelto por el Proceso en JSONset tSC = claseAux.%WriteJSONStreamFromObject(.pOutput,.pRequest,,,,"aeloqtuw")
        set json = pOutput.Read()
        
        do httpRequest.EntityBody.Write(json)    
        
        while (httpRequest.EntityBody.AtEnd = 0) {
            set httpRequestBody = httpRequest.EntityBody.Read()
        }    
        $$$LOGALERT("httpRequestBody: "_httpRequestBody)
        
        do httpRequest.EntityBody.Rewind()
            
        ;set tSC=httpRequest.Get(URL,0)set tSC=httpRequest.Post(URL,0)

        //Lanzamos excepcion si hubo errorif$$$ISERR(tSC){
                $$$ThrowOnError(tSC)
        }

        //Obtenemos respuestaset tResponse = httpRequest.HttpResponse
        $$$LOGASSERT("httpRequest.HttpResponse.ContentLength: "_httpRequest.HttpResponse.ContentLength)
        $$$LOGALERT("$isobject(tResponse.Data): "_$isobject(tResponse.Data))

        ;set linea = "";set linea = ##class(%GlobalCharacterStream).%New()#dim dynamicobject as%Library.DynamicObjectset dynamicobject = ##class(%Library.DynamicAbstractObject).%FromJSON(tResponse.Data)
        set json = dynamicobject.%ToJSON()
        $$$LOGINFO("json: "_json)
        
        //Leemos respuesta/*
        while (tResponse.Data.AtEnd = 0) {
            ;set linea = linea_$ZCONVERT(tResponse.Data.Read(),"I","UTF8")
            ;do linea.Write($ZCONVERT(tResponse.Data.Read(),"I","UTF8"))
            ;do linea.Write(tResponse.Data.Read())
            set linea = linea_tResponse.Data.Read()
        }
        */;do linea.Rewind();$$$LOGINFO("linea.Read(): "_linea.Read());$$$LOGINFO("$LENGTH(linea): "_$LENGTH(linea));do linea.Rewind();$$$LOGINFO("linea: "_linea)// se transforma el objeto JSON a un objeto local;set tSC= claseAux.%ConvertJSONToObject(linea,"Mensajes.Response.Radiologia.CConcertados.BusquedaOrdenesNEGRINResponse",.pResponse,1)    ;set tSC= claseAux.%ConvertJSONToObject(linea.Read(),"Mensajes.Response.Radiologia.CConcertados.BusquedaOrdenesNEGRINResponse",.pResponse,1)    set tSC= claseAux.%ConvertJSONToObject(json,"Mensajes.Response.Radiologia.CConcertados.BusquedaOrdenesNEGRINResponse",.pResponse,1)    
        
        ;$$$LOGINFO("Texto error: "_$System.Status.GetErrorText(tSC))//Rellenamos response;set pResponse = ##class(Mensajes.Response.CConcertadostoPACS.Radiologia.BusquedaOrdenesNEGRINResponse).%New();set pResponse.data = jsonQuit pResponse
    }

    XData MessageMap
    {
    <MapItems>
      <MapItem MessageType="Mensajes.Request.Radiologia.CConcertados.BusquedaOrdenesNEGRINRequest">
        <Method>BusquedaOrdenes</Method>
      </MapItem>
      </MapItems>
    }

    }

Our worry is that the method "%ConvertJSONToObject" required a %String as first parameter, so it is being limited to the System's limits for Strings.

We wonder how could we just convert the %Stream.Object to structured Ens.Response, even if it is too big.

Could you help us please?

Thanks for your help

We have also read:

https://community.intersystems.com/post/maxlen-usage-strings

https://community.intersystems.com/post/convert-characterstream-json-an…

https://community.intersystems.com/post/maxstring-limit-issue

Comments

Sean Connelly · Oct 23, 2023

Hi Yone,

I would keep it simple, avoid unpacking JSON here and make pResponse a generic Ens.StreamContainer

Something like this should do it...

set tSC=httpRequest.Post(URL,0)
if$$$ISERR(tSC) return tSC  //no need to throw, the director will handle tSCset pResponse=##class(Ens.StreamContainer).%New()
return pResponse.StreamSet(tResponse.Data)
0
Sean Connelly  Oct 23, 2023 to Sean Connelly

Expanding on this a little, your service / process that calls the operation will get back an Ens.StringContainer, if at this point you need access to the JSON then convert the stream to a dynamic object, something like...
 

set obj = ##class(%DynamicAbstractObject).%FromJSON(response.StreamGet())
0
Ashok Kumar T · Oct 23, 2023

Hello Yone,

Why don't you use %Stream.GlobalCharacter stream object to store  Long string instead of %String property. You can extend your class with %JSON.Adaptor and create a JSON object and directly import with your contents like below.

ClassMethod Import()
{
    set json=[{"ID_SICH":"121212","FECHA_DERIVACION":123,"MEDICO_PETICIONARIO":(tResponse.Data)}]
    set obj = ##Class(Mensajes.Response.Radiologia.CConcertados.BusquedaOrdenesNEGRINResponse).%New()
    set stt= o.%JSONImport(json)
    if$$$ISERR(stt) write$SYSTEM.OBJ.DisplayError(stt)
    set stt= obj.%Save()
    if$$$ISERR(stt) write$SYSTEM.OBJ.DisplayError(stt)
}
0