Para um de nossos clientes, precisei integrar com o endpoint AFAS imageconnector/imageconnector/{imageId}?format={format}.
Esse endpoint retorna uma mensagem JSON com a imagem como uma propriedade de string codificada em base64, além do mimetype da imagem.
/// Image Object
Class Mycustomer.Model.AfasGet.Image Extends (%SerialObject, %XML.Adaptor, %JSON.Adaptor)
{
/// file data (base64 encoded)
Property Filedata As %String(%JSONFIELDNAME = "filedata");
/// MimeType e.g. "image/jpeg"
Property MimeType As %String(%JSONFIELDNAME = "mimetype");
}
Na classe Message, tentamos lidar com isso da seguinte forma:
Property Image As Mycustomer.Model.AfasGet.Image;
/// AFAS GetImage response
/// get /imageconnector/{imageId}?format={format}
Method LoadFromResponse(httpResponse As %Net.HttpResponse, caller As %String = "") As %Status
{
Set sc = $$$OK
If $$$LOWER($Piece(httpResponse.ContentType,";",1))="application/json",httpResponse.StatusCode = "200" {
set ..Image = ##class(Mycustomer.Model.AfasGet.Image).%New()
set ..status = ..Image.%JSONImport(httpResponse.Data)
}
Return sc
}
Tudo isso funcionava bem até que, em algum momento, o tamanho do filedata se tornou maior que o $$$MaxStringLength (3.641.144), caso em que uma exceção MAXSTRING era levantada.
O próximo passo lógico foi alterar o tipo da propriedade filedata para %Stream.GlobalCharacter:
/// Image Object
Class Mycustomer.Model.AfasGet.Image Extends (%SerialObject, %XML.Adaptor, %JSON.Adaptor)
{
/// file data (base64 encoded)
Property Filedata As %Stream.GlobalCharacter(%JSONFIELDNAME = "filedata");
/// MimeType e.g. "image/jpeg"
Property MimeType As %String(%JSONFIELDNAME = "mimetype");
}
Mas isso não funcionou, %JSONImport() ainda gerava um erro MAXSTRING
Tentei então com Python, mas como não sou um especialista em Python, eventualmente desisti dessa abordagem.
Graças à resposta de Steven Hobbs https://community.intersystems.com/user/steven-hobbs em https://community.intersystems.com/post/maxstring-trying-read-string-jso..., aprendi então que é possível e direto recuperar propriedades de string JSON para um stream usando image.%Get("filedata", , "stream")):
Method LoadFromResponse(httpResponse As %Net.HttpResponse, caller As %String = "") As %Status
{
Set sc = $$$OK
If $$$LOWER($Piece(httpResponse.ContentType,";",1))="application/json",httpResponse.StatusCode = "200" {
set ..Image = ##class(Mycustomer.Model.AfasGet.Image).%New()
set image = {}.%FromJSON(httpResponse.Data)
set ..Image.MimeType = image.mimetype
set ..Image.Filedata = ##class(%Stream.GlobalCharacter).%New()
do ..Image.Filedata.CopyFrom(image.%Get("filedata", , "stream"))
}
Return sc
}
Ainda estou perplexo sobre como eu poderia instruir a classe %JSON.Adaptor e usar a lógica interna para mapear para um stream.
Se houver alguém por aí que saiba como fazer isso, por favor, me avise!