Artículo
· 5 dic, 2023 Lectura de 3 min

Recuperando ficheros en Base64 desde una llamada POST sin error <MAXSTRING>

¡Bienvenidos a todos! 

En este breve artículo quería presentar un ejemplo de uso que seguramente a muchos de los que trabajéis con IRIS como backend de vuestras aplicaciones web os hayáis encontrado en más de una ocasión y sería el de la necesidad de enviar desde el frontend un archivo a vuestro servidor.

Por lo general la forma más sencilla que he encontrado para realizar esta tarea es la de transformar el fichero desde el frontend al formato de Base64 y realizar una llamada POST a nuestro servidor adjuntando el Base64 obtenido a un mensaje JSON en el que indico en un parámetro el nombre del archivo y en otro el fichero en si. Algo similar a esto:

{
    "fileData": "JVBERi0xLjQKJdPr6eEKMSAwIG...",
    "fileName": "example.pdf"
}

Desde mi instancia de IRIS tendré una aplicación web configurada que será gestionada desde una clase que extiende de %CSP.REST y que dispondrá de un método de clase encargado de manejar estas llamadas POST. El código será algo similar a esto:

ClassMethod SaveFile() As %Status
{
    Try {
        Do ##class(%REST.Impl).%SetContentType("application/json")
        If '##class(%REST.Impl).%CheckAccepts("application/json") Do ##class(%REST.Impl).%ReportRESTError(..#HTTP406NOTACCEPTABLE,$$$ERROR($$$RESTBadAccepts)) Quit
        // Reading the body of the http call with the file data
        set dynamicBody = {}.%FromJSON(%request.Content)

        set dynamicStream = dynamicBody.%Get("fileData",,"stream<base64")
        
        set stream=##class(%Stream.FileBinary).%New()
        set sc=stream.LinkToFile("/shared/durable/"_dynamicBody.fileName)
        set sc=stream.CopyFromAndSave(dynamicStream)
       
    } Catch (ex) {
        Do ##class(%REST.Impl).%SetStatusCode("400")
        Do ##class(%REST.Impl).%WriteResponse(ex.DisplayString())
        return {"errormessage": "Client error"}
    }
    Quit $$$OK
}

Expliquemos en detalle que está haciendo este método:

  1. Recuperamos el contenido enviado en el body del mensaje y lo transformamos a un %Library.DynamicAbstractObject que podremos leer como un objeto.
    set dynamicBody = {}.%FromJSON(%request.Content)
     
  2. En este paso es donde ocurre la magia, transformamos nuestro Base64 en un tipo %Stream que podremos obtener mediante el método %Get de la clase %Library.DynamicObject.
  3. set dynamicStream = dynamicBody.%Get("fileData",,"stream<base64")
    Como veis le estamos pasando como parámetro de entrada el tipo de transformación que queremos realizar, en nuestro ejemplo de Base64 a Stream (stream<base64). ¿Cual es la ventaja de utilizar esta instrucción? Pues que no vamos a estar limitados por el valor MAXSTRING, es decir, en el caso de que nuestro fichero en Base64 sea muy grande nunca vamos a recibir una excepción porque hayamos superado el límite máximo de la longitud permitida para un String.
  4. Finalmente creamos en nuestro servidor el fichero que va a contener los datos enviados en Base64 con el nombre definido en la llamada recibida y escribimos en él nuestro objeto de tipo %Stream.
    set stream=##class(%Stream.FileBinary).%New()
    set sc=stream.LinkToFile("/shared/durable/"_dynamicBody.fileName)
    set sc=stream.CopyFromAndSave(dynamicStream)

Como podéis ver, es extremadamente fácil de gestionar ficheros en Base64 desde nuestro servidor. Si tenéis cualquier pregunta no dudéis en escribirla en la sección de comentarios, estaré encantado de contestarlas.

Comentarios (0)1
Inicie sesión o regístrese para continuar