How could we include JSON objects inside a POST request?‽‽
Hello,
We would like to submit a JSON using Ensemble. Here we have the JSON structure:
{
"app_id": "e47322de-64c8-43c5-a1b7-42aa6409eb48",
"headings": {"en":"Cita Atencion Primaria","es":"Cita Atencion Primaria"},
"subtitle": {"en":"C.P. ISORA","es":"C.P. ISORA"},
"contents": {"en": "Next appointment", "es": "Siguiente cita"},
"data":{
"centro": "C.P. ISORA",
"fecha": "yyyy/mm/dd",
"hora": "hh:mm",
"profesional": "nombre del profesional",
"nomUsuario": "nombre del usuario",
"codcita": "idCita",
"sepuedeborrar": 1
},
"include_player_ids": ["2b3a6be7-5475-4871-b3be-a50eb2ec6034"]
}
We have created a class to hold this structure:
Class EsquemasDatos.NotificacionesPUSH.CrearNotificacionRequest Extends (%SerialObject, %XML.Adaptor)
{
Parameter ELEMENTQUALIFIED = 1;
Parameter NAMESPACE = "https://10.136.4.141:19738/sanidad/scs/test/gestionMensajeriaPush/v01r00/crearNotificacion";
Parameter XMLNAME = "CrearNotificacionRequest";
Parameter XMLSEQUENCE = 1;
Property "app_id" As %String(MAXLEN = "");
Property headings As %RegisteredObject;
Property subtitle As %RegisteredObject;
Property contents As %RegisteredObject;
// Property data As %RegisteredObject;
Property data As %RegisteredObject;
// Property "include_player_ids" As %Collection.ListOfObj;
Property "include_player_ids" As %Collection.ListOfObj;
// Property "include_player_ids" As %String(MAXLEN = "");
In addition we have the following operation:
Method CrearNotificacion(pRequest As Mensajes.Request.NotificacionesPUSH.CrearNotificacion, pResponse As Mensajes.Response.NotificacionesPUSH.CrearNotificacion) As %Library.Status
{
$$$LOGINFO("^data: "_^data)
set body=##class(EsquemasDatos.NotificacionesPUSH.CrearNotificacionRequest).%New()
set body."app_id" = pRequest.idApp
set body.headings = {"en":(pRequest.notificacion.titulo),"es":(pRequest.notificacion.titulo)}
set body.subtitle = {"en":(pRequest.notificacion.subtitulo),"es":(pRequest.notificacion.subtitulo)}
set body.contents = {"en":(pRequest.notificacion.mensaje),"es":(pRequest.notificacion.mensaje)}
set body.data = {"en":(^data)}
set body."include_player_ids" = ["2b3a6be7-5475-4871-b3be-a50eb2ec6034"]
set httpRequest = ##class(%Net.HttpRequest).%New()
set tResponse = ##class(%Net.HttpResponse).%New()
set httpRequest.Server = "onesignal.com"
set httpRequest.ContentType = "application/json"
set httpRequest.Authorization = "Basic "_##class(Util.TablasMaestras).getValorMaestra("NOTIFICACIONESPUSH.PARAMETRIZACIONES","onesignal_apikey")
$$$LOGINFO("httpRequest.Authorization: "_httpRequest.Authorization)
set httpRequest.Https = 1
set httpRequest.SSLConfiguration = "Certificado_SCS"
set status = ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(httpRequest.EntityBody, body,,,,"aeloqtuw")
set tSC = httpRequest.Post("https://onesignal.com/api/v1/notifications")
set tResponse = httpRequest.HttpResponse
if $$$ISERR(tSC){
$$$ThrowOnError(tSC)
}
if (tResponse.Data.AtEnd = 0) {
//$$$LOGINFO("En AñadirDispositivo, tamaño de tResponse: "_tResponse.Data.Size)
set linea = tResponse.Data.Read()
//$$$LOGINFO("Linea: "_linea)
}
set pResponse = ##class(Mensajes.Response.NotificacionesPUSH.AñadirDispositivo).%New()
do pResponse.return.Write(linea)
Quit pResponse
When we see the trace we are surprised, because of the API returns:
{"status":400,"error":"There was a problem in the JSON you submitted: unexpected character at line 10, column 3 [parse.c:619] in '{\r\n\t\"app_id\":\"e47322de-64c8-43c5-a1b7-42aa6409eb48\",\r\n\t\"headings\": {\r\n\t},\r\n\t\"subtitle\": {\r\n\t},\r\n\t\"contents\": {\r\n\t},\r\n\t\"data\": {\r\n\t}"}
As you observe, headings, subtitle, contents and data are empty objects. In addition "include_player_ids" which is declared as a list, is not being included in the POST.
Besides we have tried to declare them as %DynamicObject instead of %RegisteredObject:
Class EsquemasDatos.NotificacionesPUSH.CrearNotificacionRequest Extends (%SerialObject, %XML.Adaptor)
{
Parameter ELEMENTQUALIFIED = 1;
Parameter XMLNAME = "CrearNotificacionRequest";
Parameter XMLSEQUENCE = 1;
Property "app_id" As %String(MAXLEN = "");
Property headings As %DynamicObject;
Property subtitle As %DynamicObject;
Property contents As %DynamicObject;
// Property data As %RegisteredObject;
Property data As %DynamicObject;
// Property "include_player_ids" As %Collection.ListOfObj;
Property "include_player_ids" As %DynamicObject;
// Property "include_player_ids" As %String(MAXLEN = "");
And here is the result being send to us by the API:
{"errors":["contents must be key/value collections by language code"]}
We wonder how could we include JSON objects inside the JSON object being sent to the API?
We have read:
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...
https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GO...
https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GO...
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...
https://cedocs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cl...
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...
https://community.intersystems.com/post/size-limitation-tojson-large-stream
How could we include JSON objects inside a POST request?
EDIT: We store in ^data the following string:
{"centro":"C.P. ISORA","fecha":"yyy/mm/dd","hora":"hh:mm","profesional":"nombre del profesional","nomUsuario":"nombre de usuario","codcita":"idCita","sepuedeborrar":"1"}
Hi Yone,
what version are you using ? From Caché/Ensemble 2016.2 you could create your json directly like :
"app_id": "e47322de-64c8-43c5-a1b7-42aa6409eb48",
"headings": {"en":"Cita Atencion Primaria","es":"Cita Atencion Primaria"},
"subtitle": {"en":"C.P. ISORA","es":"C.P. ISORA"},
"contents": {"en": "Next appointment", "es": "Siguiente cita"},
"data":{
"centro": "C.P. ISORA",
"fecha": "yyyy/mm/dd",
"hora": "hh:mm",
"profesional": "nombre del profesional",
"nomUsuario": "nombre del usuario",
"codcita": "idCita",
"sepuedeborrar": 1
},
"include_player_ids": ["2b3a6be7-5475-4871-b3be-a50eb2ec6034"]
}
Hello, Danny Wijnschenk
We are using 2016.1.2
Hi Yone,
Following link explains how to do the same in 2016.1 :
https://cedocs.intersystems.com/ens20161/csp/docbook/DocBook.UI.Page.cls?KEY=GJSON_tojson
But you risk writing code which will be incompatible with later versions as much of the json syntax of pre 2016.2 is not valid anymore.