<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Irene Mykhailova</title>
    <description>The latest articles on DEV Community by Irene Mykhailova (@graach).</description>
    <link>https://dev.to/graach</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F508209%2F45902aaa-6fe8-41e5-98f4-22a3b4d163cb.jpeg</url>
      <title>DEV Community: Irene Mykhailova</title>
      <link>https://dev.to/graach</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/graach"/>
    <language>en</language>
    <item>
      <title>Transferring Files via REST to Store in a Property, Part 2</title>
      <dc:creator>Irene Mykhailova</dc:creator>
      <pubDate>Fri, 04 Jun 2021 17:34:12 +0000</pubDate>
      <link>https://dev.to/intersystems/transferring-files-via-rest-to-store-in-a-property-part-2-20lb</link>
      <guid>https://dev.to/intersystems/transferring-files-via-rest-to-store-in-a-property-part-2-20lb</guid>
      <description>&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;In the first installment of this article series, we discussed how to read a “big” chunk of data from the raw body of an HTTP POST method and save it to a database as a stream property of a  class. Now let’s look at how to save such data and metadata in JSON format.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Unfortunately, Advanced REST Client doesn’t let you compose JSON objects with binary data as a value of a key (or maybe I simply haven’t figured out how to do it), so I decided to write a simple client in ObjectScript to send data to the server.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;I created a new class called &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;RestTransfer.Client&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; and added to it parameters &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Server = "localhost"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; and &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Port = 52773&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; to describe my web server. And I created a &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;GetLink&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; class method in which I create a new instance of class &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%Net.HttpRequest&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; and set its properties to the aforementioned parameters. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;To actually send the POST request to a server, I created a class method &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;SendFileDirect&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;, which reads the file I wish to send to the server and writes its contents to my request’s &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;EntityBody&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; property. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;After this, I call method &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Post("/RestTransfer/file")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; and, if it completes successfully, the response will be in the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;HttpResponse&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; property. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;To see the result returned by the server, I call the response’s &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;OutputToDevice&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; method. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Here’s the class method:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Class RestTransfer.Client
{
  Parameter Server = "localhost";
  Parameter Port = 52773;
  Parameter Https = 0;

  ClassMethod GetLink() As %Net.HttpRequest
  {
      set request = ##class(%Net.HttpRequest).%New()       
      set request.Server = ..#Server
      set request.Port = ..#Port
      set request.ContentType = "application/octet-stream" 
      quit request
  }

  ClassMethod SendFileDirect(aFileName) As %Status
  {
    set sc = $$$OK 
    set request = ..GetLink() 
    set s = ##class(%Stream.FileBinary).%New()
    set s.Filename = aFileName
    While 's.AtEnd 
    {
      do request.EntityBody.Write(s.Read(.len, .sc))
      Quit:$System.Status.IsError(sc)
    }
    Quit:$System.Status.IsError(sc)

    set sc = request.Post("/RestTransfer/file")                            
    Quit:$System.Status.IsError(sc)
    set response=request.HttpResponse
    do response.OutputToDevice()
    Quit sc
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;We can call this method to transfer the same files used in the previous article:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; do ##class(RestTransfer.Client).SendFileDirect("D:\Downloads \2020_1012_114732_020.JPG")
 do ##class(RestTransfer.Client).SendFileDirect("D:\Downloads\Archive.xml")
 do ##class(RestTransfer.Client).SendFileDirect("D:\Downloads\arc-setup.exe")&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;We’ll see the responses from the server for each file:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 OK
CACHE-CONTROL: no-cache
CONTENT-LENGTH: 15
CONTENT-TYPE: text/html; charset=utf-8
DATE: Thu, 05 Nov 2020 15:13:23 GMT
EXPIRES: Thu, 29 Oct 1998 17:04:19 GMT
PRAGMA: no-cache
SERVER: Apache
{"Status":"OK"}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;And we’ll have the same data in globals as before:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MCFasaO9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/YW1xZFhjsTvK0psYPtxrq_w7_8BBSAWZGX8zBE3_a3bbO8vASpc3R10JMI_s4bFVza29QoE75u9eZXKp_VEsWySiLAAJS6V8Rif4D_RXjCFKJnZe1epOh5iG_YXoRzaLAqcJs5Lw" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MCFasaO9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/YW1xZFhjsTvK0psYPtxrq_w7_8BBSAWZGX8zBE3_a3bbO8vASpc3R10JMI_s4bFVza29QoE75u9eZXKp_VEsWySiLAAJS6V8Rif4D_RXjCFKJnZe1epOh5iG_YXoRzaLAqcJs5Lw"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uyEHguJT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh4.googleusercontent.com/T-WHUkOwBT8ooj29bWyxkTBgvD4kvZroNqK4el0sDJGxd5EtF0_NWREGgAQw-7nMqZHocwjAV8mea5aJvY5kVM8IImcVUKGBIkE9EeClekaDUaUqJ_s5MeYYIXPw-7TB27sZ7K51" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uyEHguJT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh4.googleusercontent.com/T-WHUkOwBT8ooj29bWyxkTBgvD4kvZroNqK4el0sDJGxd5EtF0_NWREGgAQw-7nMqZHocwjAV8mea5aJvY5kVM8IImcVUKGBIkE9EeClekaDUaUqJ_s5MeYYIXPw-7TB27sZ7K51"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;This means our client works and we can now expand it to send JSON to the server.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Getting to Know JSON&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;JSON is a lightweight format for storing and transporting data where the data is in name/value pairs separated by commas. In this case, the JSON will look something like this:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  "Name": "test.txt",
  "File": "Hello, world!"
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;IRIS has several classes that let you work with JSON. I’m going to use the following:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%JSON.Adaptor &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;provides a way to serialize a JSON enabled object as a JSON document and vice versa.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%Library.DynamicObject &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;provides a way to dynamically assemble data that can be conveniently passed between a web client and a server.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;You can find more about these and other classes that let you work with JSON in the Class Reference section of the documentation and &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GJSON"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Application Development Guides&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;The main advantage of these classes is that they give you an easy way to create JSON from an IRIS object or create an object from JSON. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;I’ll show two approaches of how you can work with JSON to send/receive files, namely one that uses &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%Library.DynamicObject&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; to create an object on the client side and serialize it to a JSON document and &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%JSON.Adaptor&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; to deserialize it back to &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;RestTransfer.FileDesc&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; on the server side, and another where I manually form a string to send to and parse on the server side. To make it more readable, I’ll create two different methods on the server for each approach.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;For now, let’s concentrate on the first one. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Creating JSON with IRIS&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;To start, let’s inherit the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;RestTransfer.FileDesc&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; class from &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%JSON.Adaptor&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. This lets us use instance method &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%JSONImport()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; to deserialize a JSON document directly into an object. Now, this class will look as follows:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Class RestTransfer.FileDesc Extends (%Persistent, %JSON.Adaptor)
{
  Property File As %Stream.GlobalBinary;
  Property Name As %String;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Let’s add a new route to &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;UrlMap&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; in the class broker:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Route Url="/jsons" Method="POST" Call="InsertJSONSmall"/&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;This specifies that, when the service receives a POST command with URL &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;/RestTransfer/jsons&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;, it should call the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;InsertJSONSmall&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; class method. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;This method expects to receive JSON-formatted text with two key-value pairs where the contents of the file will be less than the maximum length of a string. I’ll set the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; and &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;File&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; properties of the object, save it to the database, and return the status and a JSON-formatted message indicating either success or an error. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Here’s the class method.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ClassMethod InsertJSONSmall() As %Status
{
  Set result={}
  Set st=0 

  set f = ##class(RestTransfer.FileDesc).%New()  
  if (f = $$$NULLOREF) {    
   do result.%Set("Message", "Couldn't create an instance of class") 
  } else {  
     set st = f.%JSONImport(%request.Content) 
     If $$$ISOK(st) {
        set st = f.%Save()
        If $$$ISOK(st) {      
           do result.%Set("Status","OK")        
        } else {           
           do result.%Set("Message",$system.Status.GetOneErrorText(st)) 
        }
     } else {         
        do result.%Set("Message",$system.Status.GetOneErrorText(st)) 
     }
  } 
  write result.%ToJSON()
  Quit st
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;What does this method do? It gets the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Content&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; property of the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%request&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; object and, using method &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%JSONImport &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;inherited from the class &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%JSON.Adaptor&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;, converts it to a &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;RestTransfer.FileDesc &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;object.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;If there are problems during conversion, we form a JSON with the error description:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{"Message",$system.Status.GetOneErrorText(st)}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Otherwise we save the object. If it saves without problems, we create a JSON &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;{"Status","OK"}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; message. If not, a JSON message with the error description. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Finally, we write the JSON to a response and return status &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;st&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;On the client side I added a new class method &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;SendFile&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; to send files to the server. The code is very similar to that of &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;SendFileDirect&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; but, instead of writing file contents directly to the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;EntityBody&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; property, I create a new instance of the class &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%Library.DynamicObject&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;, set its property &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; equal to the name of the file, and encode and copy the contents of the file into property &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;File&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;To encode the contents of the file I use the method &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Base64EncodeStream()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; proposed by&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://community.intersystems.com/post/how-use-base64-encrypt-string-exceeds-maximum-length-string-type"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Vitaliy Serdtsev&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Next, using method &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%ToJSON &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;of class &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%Library.DynamicObject&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;, I serialize my object to a JSON document, write it into the body of the request, and call method &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Post("/RestTransfer/jsons")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Here’s the class method:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ClassMethod SendFile(aFileName) As %Status
{
  Set sc = $$$OK
  Set request = ..GetLink() 
  set s = ##class(%Stream.FileBinary).%New()
  set s.Filename = aFileName
  set p = {}
  set p.Name = s.Filename 
  set sc = ..Base64EncodeStream(s, .t)
  Quit:$System.Status.IsError(sc)

  While 't.AtEnd { 
    set p.File = p.File_t.Read(.len, .sc)
    Quit:$System.Status.IsError(sc)
  }  
  do p.%ToJSON(request.EntityBody)
  Quit:$System.Status.IsError(sc)

  set sc = request.Post("/RestTransfer/jsons")                                    
  Quit:$System.Status.IsError(sc)

  Set response=request.HttpResponse
  do response.OutputToDevice()
  Quit sc
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;We call this method and method SendFileDirect to transfer several small files:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; do ##class(RestTransfer.Client).SendFile("D:\Downloads\Outline Template.pdf")      
 do class(RestTransfer.Client).SendFileDirect("D:\Downloads\Outline Template.pdf")    
 do ##class(RestTransfer.Client).SendFile("D:\Downloads\pic3.png")         
 do ##class(RestTransfer.Client).SendFileDirect("D:\Downloads\pic3.png")         
 do ##class(RestTransfer.Client).SendFile("D:\Downloads\Archive (1).xml")      
 do ##class(RestTransfer.Client).SendFileDirect("D:\Downloads\Archive (1).xml")    &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;We’ll get the following results:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FXcQ05-B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/ovVDs02LE9yBjvRI2Yp-Gq-b3k26z_wMWICW7TfnxEYow_GZQ18LnTxNQmYGnowCV04bLgpFsN3ArIdS8PvwoCKjAPZlk0F8zAbsD-2lz22SVR2NwXURkf27R9jDjGqHgIGf9ZD1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FXcQ05-B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/ovVDs02LE9yBjvRI2Yp-Gq-b3k26z_wMWICW7TfnxEYow_GZQ18LnTxNQmYGnowCV04bLgpFsN3ArIdS8PvwoCKjAPZlk0F8zAbsD-2lz22SVR2NwXURkf27R9jDjGqHgIGf9ZD1"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;As you can see, the lengths are the same and, if we save those files to a hard drive, we’ll see that they’re unchanged.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Forming JSON Manually&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Now let’s concentrate on the second approach, which is to form the JSON manually. To do this, let’s add a new route to &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;UrlMap&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; in the class broker:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Route Url="/json" Method="POST" Call="InsertJSON"/&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;This specifies that when the service receives a POST command with URL &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;/RestTransfer/json&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;, it should call the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;InsertJSON&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; class method. In this method, I expect to receive the same JSON, but I don’t impose any limits on the length of the file. Here’s the class method:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ClassMethod InsertJSON() As %Status
{
  Set result={}
  Set st=0 

  set t = ##class(%Stream.TmpBinary).%New()
  While '%request.Content.AtEnd 
  {        
    set len = 32000
    set temp = %request.Content.Read(.len, .sc)
    set:len&amp;lt;32000 temp = $extract(temp,1,*-2)  
    set st = t.Write($ZCONVERT(temp, "I", "RAW"))                                                
  }
  do t.Rewind()

  set f = ##class(RestTransfer.FileDesc).%New()  
  if (f = $$$NULLOREF) 
  {     
    do result.%Set("Message", "Couldn't create an instance of class") 
  } else {
    set str = t.Read()
    set pos = $LOCATE(str,""",")
    set f.Name = $extract(str, 10, pos-1)
    do f.File.Write($extract(str, pos+11, *))
    While 't.AtEnd {       
      do f.File.Write(t.Read(.len, .sc))
    }

    If $$$ISOK(st) 
    {
      set st = f.%Save()
      If $$$ISOK(st) 
      {         
        do result.%Set("Status","OK")         
      } else {                      
        do result.%Set("Message",$system.Status.GetOneErrorText(st)) 
      }
    } else {         
       do result.%Set("Message",$system.Status.GetOneErrorText(st)) 
    }    
  }
  write result.%ToJSON()
  Quit st
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;What does this method do? First, I create a new instance of a temporary stream, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%Stream.TmpBinary&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;, and copy into it the contents of the request. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Because I’m going to work with it as a string, I need to get rid of a trailing quote mark (") and a curly brace (}). To do this, in the last chunk of the stream I leave out the last two characters: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;$extract(temp,1,*-2)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;At the same time, I convert my string using the "RAW" translation table: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;$ZCONVERT(temp, "I", "RAW")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Then I create a new instance of my class &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;RestTransfer.FileDesc&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; and do the same checks as in the other methods. I know the structure of my string, so I extract the name of the file and the file itself and set them to corresponding properties.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;On the client side, I modified my class method &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;SendFile&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; and, before forming the JSON, I check the length of the file. If it’s less than the 2,000,000 bytes (apparent limit for the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%JSONImport&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; method), I call &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Post("/RestTransfer/jsons")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. Otherwise I call &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Post("/RestTransfer/json")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Now the method looks like this:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ClassMethod SendFile(aFileName) As %Status
{
  Set sc = $$$OK
  Set request = ..GetLink()
  set s = ##class(%Stream.FileBinary).%New()
  set s.Filename = aFileName
  if s.Size &amp;gt; 2000000 //3641144 max length of the string in IRIS
  {   
    do request.EntityBody.Write("{""Name"":"""_s.Filename_""", ""File"":""")      
    While 's.AtEnd 
    {       
      set temp = s.Read(.len, .sc)
      do request.EntityBody.Write($ZCONVERT(temp, "O", "RAW"))   
      Quit:$System.Status.IsError(sc)
    }

    do request.EntityBody.Write("""}")  
    set sc = request.Post("/RestTransfer/json")                           
  } else {
    set p = {}
    set p.Name = s.Filename
    set sc = ..Base64EncodeStream(s, .t)
    Quit:$System.Status.IsError(sc)
    While 't.AtEnd {
        set p.File = p.File_t.Read(.len, .sc)
        Quit:$System.Status.IsError(sc)
    } 
    do p.%ToJSON(request.EntityBody)
    Quit:$System.Status.IsError(sc)
    set sc = request.Post("/RestTransfer/jsons")                                      
  }

  Quit:$System.Status.IsError(sc)
  Set response=request.HttpResponse
  do response.OutputToDevice()
  Quit sc
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;To call the second method, I create the string with JSON manually. And to transfer the file itself, on the client side I also convert the contents using the “RAW” translation table: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;($ZCONVERT(temp, "O", "RAW")&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Now we call this method and method &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;SendFileDirect&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; to transfer several files of different sizes:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; do ##class(RestTransfer.Client).SendFile(“D:\Downloads\pic3.png”)         
 do ##class(RestTransfer.Client).SendFileDirect(“D:\Downloads\pic3.png”)         
 do ##class(RestTransfer.Client).SendFile(“D:\Downloads\Archive (1).xml”)      
 do ##class(RestTransfer.Client).SendFileDirect(“D:\Downloads\Archive (1).xml”)    
 do ##class(RestTransfer.Client).SendFile(“D:\Downloads\Imagine Dragons-Thunder.mp3”)         
 do ##class(RestTransfer.Client).SendFileDirect(“D:\Downloads\Imagine Dragons-Thunder.mp3”)
 do ##class(RestTransfer.Client).SendFile(“D:\Downloads\ffmpeg-win-2.2.2.exe”)   
 do ##class(RestTransfer.Client).SendFileDirect(“D:\Downloads\ffmpeg-win-2.2.2.exe”) &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;We’ll get the following results:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VTYSuYbq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/v0_vPO3Wj7CVJJ9YFs9OMQGnsPLe_YD0Tcs2CHdC0lqQ24oCOaZelVbTc24XIlt5Zj0ph5oW-H6sMWM52UA14hquBDpMj3U8vA2qy28NplyqVFGMxFLpWYVBPEiPheR4St9NDa27" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VTYSuYbq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh5.googleusercontent.com/v0_vPO3Wj7CVJJ9YFs9OMQGnsPLe_YD0Tcs2CHdC0lqQ24oCOaZelVbTc24XIlt5Zj0ph5oW-H6sMWM52UA14hquBDpMj3U8vA2qy28NplyqVFGMxFLpWYVBPEiPheR4St9NDa27"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ph5lvYux--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/DMAaCkD-LRBd14w0cgw5jAuIxW-_kNlhVnHfBwmQXIScs1sPe2ELMM0sEcONEvuLc6J5vKmXbUKJBWFCdUzQKMqkzWlPDHZAbSwx7SHf7HlRkhwDGjF-RBjfpRyGesraYH5nPKBA" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ph5lvYux--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/DMAaCkD-LRBd14w0cgw5jAuIxW-_kNlhVnHfBwmQXIScs1sPe2ELMM0sEcONEvuLc6J5vKmXbUKJBWFCdUzQKMqkzWlPDHZAbSwx7SHf7HlRkhwDGjF-RBjfpRyGesraYH5nPKBA"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gandaR5U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/dzB_7NT_QnY-GTRW9ahJHL9p_MdEreIlcmjYtIjahzidLSlhNWmqsJKssXpshyHdtXzI-Vb35hLUbq-UbbvWGz09YLc7aln8rkvcA--1N2xm3ZVlNA5mXMFM202xqwHYoJ_-BKH9" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gandaR5U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/dzB_7NT_QnY-GTRW9ahJHL9p_MdEreIlcmjYtIjahzidLSlhNWmqsJKssXpshyHdtXzI-Vb35hLUbq-UbbvWGz09YLc7aln8rkvcA--1N2xm3ZVlNA5mXMFM202xqwHYoJ_-BKH9"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3Xnkk9Il--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/gkd0avld0fMXwbTEhMFbGrSsGJ0j7JbXnhmZYPmXsUI6iFrHpDw4zXUMNPyDgxEQTAtCgBHIhRoPJyGGK6GBfIQCTi2-gbOmJF08xA8e4UAZaCNGYGTL7IGasXVh5L57BlFMyX7o" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3Xnkk9Il--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/gkd0avld0fMXwbTEhMFbGrSsGJ0j7JbXnhmZYPmXsUI6iFrHpDw4zXUMNPyDgxEQTAtCgBHIhRoPJyGGK6GBfIQCTi2-gbOmJF08xA8e4UAZaCNGYGTL7IGasXVh5L57BlFMyX7o"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;We can see that the lengths are the same so everything works as it’s supposed to.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Wrapping Up&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Again, you can read more about creating REST services in the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://docs.intersystems.com/iris20191/csp/docbook/Doc.View.cls?KEY=GREST"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;documentation&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. The example code for both approaches is on &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://github.com/Gra-ach/RESTFileTransfer"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;GitHub&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; and &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://openexchange.intersystems.com/package/RESTFileTransfer"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;InterSystems Open Exchange&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;As for transferring results of the TWAIN module discussed in the first article of this series, it depends on the size of data you’ll be receiving. If the maximum resolution will be limited and the files will be small, you can use system classes &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%JSON.Adaptor &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;and &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%Library.DynamicObject&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. But to be on the safe side, it’s better to either send a file directly in the body of a POST command or to form the JSON manually. Also it may be a good idea to use range requests and divide big files into several parts, send them separately and consolidate back into one file on the server side.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;In any case, if you have any questions or suggestions, please don’t hesitate to write them in the comments section.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>rest</category>
      <category>iris</category>
      <category>intersystems</category>
    </item>
    <item>
      <title>Transferring Files via REST to Store in a Property, Part 1</title>
      <dc:creator>Irene Mykhailova</dc:creator>
      <pubDate>Fri, 04 Jun 2021 17:33:58 +0000</pubDate>
      <link>https://dev.to/intersystems/transferring-files-via-rest-to-store-in-a-property-part-1-366d</link>
      <guid>https://dev.to/intersystems/transferring-files-via-rest-to-store-in-a-property-part-1-366d</guid>
      <description>&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;A question came up in the InterSystems developer community concerning the possibility of&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://community.intersystems.com/post/twain-interface-cache-application" rel="noopener noreferrer"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; creating a TWAIN interface to a Caché application&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. There were several great suggestions on how to get data from an imaging device on a web client to a server, then store this data in a database. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;However, in order to implement any of these suggestions, you need to be able to transfer data from a web client to a database server and store the received data in a class property (or a table cell, as was the case in the question). This technique can be useful not only for transferring imaging data received from a TWAIN device, but also for other tasks such as organizing a file archive, an image share, and so forth. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Thus, the main objective of this article is to show how to write a RESTful service to get data from the body of an HTTP POST command either in a raw state or wrapped in a JSON structure.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;REST Basics&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Before getting to the specifics, let’s start with a few words about REST in general and how RESTful services are created in IRIS.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Representational state transfer (REST) is an architectural style for distributed hypermedia systems. The key abstraction of information in REST is a resource which has its proper identifier and can be represented in a JSON, XML, or other format known to both server and client. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Usually, HTTP is used to transfer data between client and server. Each CRUD (create, read, update, delete) operation has its own HTTP method (POST, GET, PUT, DELETE), while each resource or collection of resources has its own URI.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;In this article, I’ll be using only the POST method to insert a new value into the database, so I need to know its constraints. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;POST doesn’t have any limit on the size of data stored in its body according to the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://tools.ietf.org/html/rfc7231#section-4.3.3" rel="noopener noreferrer"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;IETF RFC7231 4.3.3 Post&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; specification. But different web servers and browsers impose their own limits, typically from 1MB to 2GB. For example, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://httpd.apache.org/docs/2.4/mod/core.html#limitrequestbody" rel="noopener noreferrer"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Apache&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; allows a maximum of 2GB. In any case, if you need to send a 2GB file, you might want to rethink your approach.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Requirements for a RESTful Service in IRS&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;In IRIS, in order to implement a RESTful service, you have to:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Create a class broker that extends the abstract class &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%CSP.REST&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. This, in turn, extends &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%CSP.Page&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;, and this makes it possible to access different useful methods, parameters, and objects, in particular &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;%request&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Specify &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;UrlMap&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; to define routes.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Optionally set the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;UseSession&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; parameter to specify whether each REST call is executed in its own web session or shares a single session with other REST calls.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Provide class methods to perform operations defined in routes.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Define the CSP web application and specify its security on the web application page (System Administration &amp;gt; Security &amp;gt; Applications &amp;gt; Web Applications), where the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Dispatch&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; class should hold the name of the user class and &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Name&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;, the first part of the URL for the REST call.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;In general, there are several ways to send big chunks of data (files) and their metadata from client to server, such as:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Base64-encode the file and the metadata and add processing overhead to both the server and the client for encoding/decoding.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Send the file first and return an ID to the client, which then sends the metadata with the ID. The server reassociates the file and the metadata.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Send the metadata first and return an ID to the client, which then sends the file with the ID, and the server reassociates the file and the metadata.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;In this first article, I’m going to basically take the second approach, but without returning ID to the client and adding the metadata (the filename to store as another property) because there’s nothing exceptional about this task. In a second article, I’ll use the first approach, but I’ll package my file and metadata (the filename) in a JSON structure before sending it to the server.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h1&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Implementing the RESTFul Service&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h1&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Now let’s get to the specifics. First, let’s define the class, properties of which we’ll be setting&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Class RestTransfer.FileDesc Extends %Persistent
{
  Property File As %Stream.GlobalBinary;
  Property Name As %String;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Of course, you’ll usually have more metadata to go with the file, but this should suffice for our purposes.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Next, we need to create a class broker, which we’ll expand later with routes and methods:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Class RestTransfer.Broker Extends %CSP.REST
{
  XData UrlMap
  {
    &amp;lt;Routes&amp;gt;
    &amp;lt;/Routes&amp;gt;
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;And lastly, for the preliminary setup we need to specify this application in a list of web applications:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FlkjPLUflbNHXgMKtwm0_pddObiF6-Azydo0NzMbdO3c1WjqPLrL77ek5AS_uGQDM4ugWFQXHS6hJNN5FEEUNP3SI8ERKa5ALdGbwRlbuWBU8taf262ldtPM-wyoFQViNTJiyAEiH" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FlkjPLUflbNHXgMKtwm0_pddObiF6-Azydo0NzMbdO3c1WjqPLrL77ek5AS_uGQDM4ugWFQXHS6hJNN5FEEUNP3SI8ERKa5ALdGbwRlbuWBU8taf262ldtPM-wyoFQViNTJiyAEiH"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Now that the preliminary setup is done, we can write methods to save a file received from a REST client (I’ll use the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://install.advancedrestclient.com/install" rel="noopener noreferrer"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Advanced REST Client&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;) into a database as a &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;File&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; property of an instance of class &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;RestTransfer.FileDesc&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;We’ll start by working with information stored as raw data in the body of POST method. First, let’s add a new route to &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;UrlMap&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Route Url="/file" Method="POST" Call="InsertFileContents"/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;This route specifies that when the service receives a POST command with URL &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;/RestTransfer/file&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;, it should call the &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;InsertFileContents&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; class method. To make things easier, inside this method I’ll create a new instance of a class &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;RestTransfer.FileDesc&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; and set its &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;File&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; property to the received data. This returns the status and a JSON-formatted message indicating either success or error. Here’s the class method:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ClassMethod InsertFileContents() As %Status
{
  Set result={}
  Set st=0    
  set f = ##class(RestTransfer.FileDesc).%New()
  if (f = $$$NULLOREF) {
    do result.%Set("Message","Couldn't create an instance of the class")
  } else {
    set st = f.File.CopyFrom(%request.Content)
    If $$$ISOK(st) {
      set st = f.%Save()
      If $$$ISOK(st) {
        do result.%Set("Status","OK")
      } else {
        do result.%Set("Message",$system.Status.GetOneErrorText(st))
      }
    } else {
      do result.%Set("Message",$system.Status.GetOneErrorText(st))
    }
  }
  write result.%ToJSON()
  Quit st
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;First, it creates a new instance of class &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;RestTransfer.FileDesc&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; and checks that it was created successfully and we have an OREF. If the object couldn’t be created, we form a JSON structure: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;{"Message", "Couldn't create an instance of class"}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;If the object was created, the contents of the request are copied into the property &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;File&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. If copying was not successful, we form a JSON structure with a description of the error: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;{"Message",$system.Status.GetOneErrorText(st)}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;If the contents were copied, we save the object, and if the save is successful, we form a JSON &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;{"Status","OK"}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. If not, the JSON returns an error description. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Finally, we write the JSON to a response and return status &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;st&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Here’s an example of transferring an image:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FJoWOHcPK5liAhznh61zUvlFY66J7Q8TUsLdoea94UEeqSHE1rSnt9jtNbZMLDbn3bv-mQBYjmVEdUkuqKqM2eS3UHq0SkQD8PCNvEWw47H9XTzcHj0s1tIOtsbaF31nSRo4cEt1J" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FJoWOHcPK5liAhznh61zUvlFY66J7Q8TUsLdoea94UEeqSHE1rSnt9jtNbZMLDbn3bv-mQBYjmVEdUkuqKqM2eS3UHq0SkQD8PCNvEWw47H9XTzcHj0s1tIOtsbaF31nSRo4cEt1J"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;How it’s saved in the database:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FSYKHRNrVqBq2O0Mefo5jPrncgU0XAMClnjQQNSPrw-228FG0RiCeCii3HQcwGIabKXMIkP9hPLyK1yD8hhxzE-4nQap2gwwNyOtS1hQec7nYZOoZ5pSDmF4Edju7vSIrBjDrkENz" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FSYKHRNrVqBq2O0Mefo5jPrncgU0XAMClnjQQNSPrw-228FG0RiCeCii3HQcwGIabKXMIkP9hPLyK1yD8hhxzE-4nQap2gwwNyOtS1hQec7nYZOoZ5pSDmF4Edju7vSIrBjDrkENz"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;We can save this stream to a file and see that it was transferred without change:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set f = ##class(RestTransfer.FileDesc).%OpenId(4)
set s = ##class(%Stream.FileBinary).%New()
set s.Filename = "D:\Downloads\test1.jpg"
do s.CopyFromAndSave(f.File)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;The same can be done with a text file:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2F9oH_0YOanIT9Rz2PF6ijXJBWB2PTaCIjuhcVY26v2OwwM8bxYayESfTKCuXgBTvcY7u47W24arTp0BXHRUTeboSApbfaTPQM3HvjrfyiTPyLC5oBjm_Mp5-wQYHeHmBtXXLjOLEM" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2F9oH_0YOanIT9Rz2PF6ijXJBWB2PTaCIjuhcVY26v2OwwM8bxYayESfTKCuXgBTvcY7u47W24arTp0BXHRUTeboSApbfaTPQM3HvjrfyiTPyLC5oBjm_Mp5-wQYHeHmBtXXLjOLEM"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;This will also be visible in globals:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FnEugr5ONsH88ycJsfKKx13df2G1D953YldIqmzRmRVqWn4DDSTJmP6OhE8DpeRs7gBflBML-jLqfKYkH8GQ-aGjT1RcgpWqnKtV13uXb0_nXJbmMXtdZpzlZYyotOsFg6nLvE6TE" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FnEugr5ONsH88ycJsfKKx13df2G1D953YldIqmzRmRVqWn4DDSTJmP6OhE8DpeRs7gBflBML-jLqfKYkH8GQ-aGjT1RcgpWqnKtV13uXb0_nXJbmMXtdZpzlZYyotOsFg6nLvE6TE"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;And we can store executables or any other type of data:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FetYBQ99ftbiRAtktOSdOP2-0dhq6afA03nQX-SEaDoUEmEOgOi6fJ1kunnG0MfFcatYw5Ak5BtFxVobdLXgTn9wXXe3QoGSO5nYFMY1js4nBcV1CpSAMh6l9d7rgvJ1Qa73zKiRs" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FetYBQ99ftbiRAtktOSdOP2-0dhq6afA03nQX-SEaDoUEmEOgOi6fJ1kunnG0MfFcatYw5Ak5BtFxVobdLXgTn9wXXe3QoGSO5nYFMY1js4nBcV1CpSAMh6l9d7rgvJ1Qa73zKiRs"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;We can check the size in globals, and it’s correct:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FG7ykwnx6_J0s8lgGvBwsJtYgQIqYDbuzixUPeel90LWmefvEGMr18qYTVV-ArvnVthFRtNSvRaFKSG-_U6gX2DSzwSYYZv1Zy0aUvTZ0zdCE5QkADgr7rlFJcLeGMB67UsMc9kLS" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FG7ykwnx6_J0s8lgGvBwsJtYgQIqYDbuzixUPeel90LWmefvEGMr18qYTVV-ArvnVthFRtNSvRaFKSG-_U6gX2DSzwSYYZv1Zy0aUvTZ0zdCE5QkADgr7rlFJcLeGMB67UsMc9kLS"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Now that this part works as it should, let’s take a look at the second approach — getting the contents of the file and its metadata (the filename) stored in JSON format and transferred in the body of a POST method. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;You can read more about creating REST services in the InterSystems&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://docs.intersystems.com/iris20191/csp/docbook/Doc.View.cls?KEY=GREST" rel="noopener noreferrer"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; documentation&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;The example code for the both approaches is on &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://github.com/Gra-ach/RESTFileTransfer" rel="noopener noreferrer"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;GitHub&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; and &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="https://openexchange.intersystems.com/package/RESTFileTransfer" rel="noopener noreferrer"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;InterSystems Open Exchange&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;. If you have any questions or suggestions pertaining to either, please don’t hesitate to write them in the comments section.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>rest</category>
      <category>iris</category>
      <category>intersystems</category>
    </item>
    <item>
      <title>Accessing data via ECP with eXTreme for .NET</title>
      <dc:creator>Irene Mykhailova</dc:creator>
      <pubDate>Wed, 04 Nov 2020 18:37:33 +0000</pubDate>
      <link>https://dev.to/intersystems/accessing-data-via-ecp-with-extreme-for-net-3le</link>
      <guid>https://dev.to/intersystems/accessing-data-via-ecp-with-extreme-for-net-3le</guid>
      <description>&lt;p&gt;Some readers of my previous article, &lt;a href="https://community.intersystems.com/post/cach%C3%A9-extreme-net-direct-access-globals-c" rel="noopener noreferrer"&gt;Caché eXTreme for .NET - direct access to globals from C#&lt;/a&gt;, wondered if you could access information not just from the same instance in which you’re working, but also from another instance on the same computer, or from an instance located on another computer in the same local network. Some theorized, correctly, that this would be possible using the Enterprise Cache Protocol (ECP). In this article I’m going to show how it can be done.&lt;/p&gt;

&lt;p&gt;The last I heard, eXTreme for .NET still uses an in-memory connection and runs in the same process as the IRIS instance, though at least &lt;a href="https://community.intersystems.com/post/does-intersystemsdatacacheclientdll-use-tcpip-net-managed-provider-or-not#comment-20996" rel="noopener noreferrer"&gt;one comment&lt;/a&gt; suggested the possibility of moving away from in-memory to TCP/IP.&lt;/p&gt;

&lt;p&gt;But, even if you can’t use TCP/IP to connect to an instance on another computer, you can use ECP to connect your local database instance to another instance on a different computer in a local network and work with this remote database as if it’s the local one. ECP is a distributed data caching architecture that manages the distribution of data and locks among a heterogeneous network of server systems. In this article, I’m going to take advantage of this architecture to store my data to another instance.&lt;/p&gt;

&lt;p&gt;The general idea is that I have a database with my data in one instance of IRIS and this will be my data server. I’m going to call this instance &lt;strong&gt;IRIS&lt;/strong&gt;. I’ll also need another instance to which I’ll connect from my eXTreme application, and this will be my application server. I’ll call this instance &lt;strong&gt;IRIST&lt;/strong&gt;. In this case, both instances are located on the same computer. (I have only one computer with 64-bit anything, in my case Windows). But this doesn’t change the result—I still need to connect the two different instances in order to access the database of one from the other.&lt;/p&gt;

&lt;p&gt;Before doing anything in Visual Studio, however, we need to set up the ECP on both IRIS instances.&lt;/p&gt;

&lt;p&gt;First, we’ll enable the ECP service on both the data (IRIS) and application (IRIST) servers. To do this, go to Management Portal &amp;gt; System Administration &amp;gt; Security &amp;gt; Services. In the list of services, select %Service.ECP and on the Edit Service page, click the Service Enabled checkbox, as shown below. Don’t forget to click the Save button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FYJI09B0o1buLErmVQUVoRtCi1y-LONGxgOOVaT4v2v_6TV2gGdPTMyrmcoRgsd-AIPJk0tN8r3gIu0OO3xQHZcfz_670UV9wRVkFhtbYlDu0RAyZYWhlZKWBJ1tINTn39gPbdsF4" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FYJI09B0o1buLErmVQUVoRtCi1y-LONGxgOOVaT4v2v_6TV2gGdPTMyrmcoRgsd-AIPJk0tN8r3gIu0OO3xQHZcfz_670UV9wRVkFhtbYlDu0RAyZYWhlZKWBJ1tINTn39gPbdsF4"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Next, we’ll configure the data server, incrementing the number of allowed application servers from the default of 1. Again, go to Management Portal &amp;gt; System Administration &amp;gt; Configuration &amp;gt; Connectivity &amp;gt; ECP Settings and in the pane on the right, “This System as an ECP Data Server,” change the “Maximum number of application servers” to 2 (or one more than whatever you have in use already). Then click Save and restart the instance for the change to take effect.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FGa4HgbDhTUWW9PZAAzU8avjDz4xAS0gPnbt6LrPVgvOT8wR0vTOyhiikbxN8K-hTGxSgwf1DK-SbVzcmk4BSbr7rLFALvu6F_LrCwDeOXHXg8yVnGzmdG4C-wwWruP1pYjupURWO" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FGa4HgbDhTUWW9PZAAzU8avjDz4xAS0gPnbt6LrPVgvOT8wR0vTOyhiikbxN8K-hTGxSgwf1DK-SbVzcmk4BSbr7rLFALvu6F_LrCwDeOXHXg8yVnGzmdG4C-wwWruP1pYjupURWO"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Because I’m lazy and this is just an example, I’ll use the USER database, but you can create a new one or use any database you have on hand (that you won’t worry about if it becomes unreadable).&lt;/p&gt;

&lt;p&gt;Next, we’ll configure our application server. The first step is to connect the application server to our data server. Go to Management Portal &amp;gt; System Administration &amp;gt; Configuration &amp;gt; Connectivity &amp;gt; ECP Settings &amp;gt; Data Servers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FnedYiBRc6QmFRANrRCy5nzrvPXcwuN5smIJhfKqKCP8ucixZhrhPu2bcRS7p2hpxWxs5_yS7p2MtmKV0pL-6aS7zvXRl0ymzkL5tePiKMSAKP3aEWx_5o1ZiXiW_OSgIRsYMAgLx" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FnedYiBRc6QmFRANrRCy5nzrvPXcwuN5smIJhfKqKCP8ucixZhrhPu2bcRS7p2hpxWxs5_yS7p2MtmKV0pL-6aS7zvXRl0ymzkL5tePiKMSAKP3aEWx_5o1ZiXiW_OSgIRsYMAgLx"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Then click the Add Server button and fill in the information about your data server. In my case, when I was setting up my data server, I didn’t choose the option Enabled or Required from the radiogroup “ECP SSL/TLS support,” so I don’t check “Use SSL/TLS.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FFebacf76DKafxyDpu7nYXFpuyF6X-pqah40KKoLJDEOyOiEKrSS_GYwRxOChRBCdycdOblpVZv1jilqqfGBjYg4Hz7yymVC9jixWfqh_4EWCRjp8dOoCERdnkCT6IHI7b637iyRW" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FFebacf76DKafxyDpu7nYXFpuyF6X-pqah40KKoLJDEOyOiEKrSS_GYwRxOChRBCdycdOblpVZv1jilqqfGBjYg4Hz7yymVC9jixWfqh_4EWCRjp8dOoCERdnkCT6IHI7b637iyRW"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If you’re using another computer, you need to provide its name or IP address in the Server Name field.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FOH4EGKWkebKlbYswZoANzNXBXwF6PC5lJJ84w1sXWouTCIBXhHbjM_er98mbmRShZJA4Oi6DPAnZtcJzziECqp6mUZgJKyH2ptymKdO1ksHF1bnRYPZSitoLb_n6KDLmxHh8PWqu" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FOH4EGKWkebKlbYswZoANzNXBXwF6PC5lJJ84w1sXWouTCIBXhHbjM_er98mbmRShZJA4Oi6DPAnZtcJzziECqp6mUZgJKyH2ptymKdO1ksHF1bnRYPZSitoLb_n6KDLmxHh8PWqu"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Click Save and you’ll see a new entry in the list of ECP data servers. In my case, the Status is Normal, which means that the connection is operating as it should. You can read more on &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GSCALE_ecp_monitor_states" rel="noopener noreferrer"&gt;ECP Connection States&lt;/a&gt; in the documentation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FG3ig2M790wcLkP-4Hiw-fkcKxbaA_mBElmqoDgKa7LN2u4sy3QOZOxLuR9NdE3506-qKaW4vAAPMAn_TQFww4Q_3Z2lhr9PjgoBwx2gz3TuYeOGnuf619ph3-NP5FdjF4DTF6Hj5" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FG3ig2M790wcLkP-4Hiw-fkcKxbaA_mBElmqoDgKa7LN2u4sy3QOZOxLuR9NdE3506-qKaW4vAAPMAn_TQFww4Q_3Z2lhr9PjgoBwx2gz3TuYeOGnuf619ph3-NP5FdjF4DTF6Hj5"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If you’re connecting instances on different computers on the (local) network, you need to make sure your port (51773, in my case) is open. Check your configuration of firewalls, antivirus, and so forth.&lt;/p&gt;

&lt;p&gt;Once the link is established, we need to map our remote database (USER, from IRIS) to our local application server (IRIST). To do this, we need to create a new database, so go to Management Portal &amp;gt; System Administration &amp;gt; Configuration &amp;gt; System Configuration &amp;gt; Namespaces and click the Create New Namespace button. Give the namespace a name and select “Remote Database” for the options, indicating the default database for Globals and for Routines.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FuayV3uNLQcVkey4Oe4G7_yc-Z8ledsSNDqBoCmX9CXgLM9G6-1OjcFEftWL0tP47R8Q_hLW9SDbVtW3H8OBYM1WVPixcXELxpCpn4lWb_9ezxs3DciF9AJFvQsgOYLMsYL5J-SAg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FuayV3uNLQcVkey4Oe4G7_yc-Z8ledsSNDqBoCmX9CXgLM9G6-1OjcFEftWL0tP47R8Q_hLW9SDbVtW3H8OBYM1WVPixcXELxpCpn4lWb_9ezxs3DciF9AJFvQsgOYLMsYL5J-SAg"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now you need to create this remote database. To do so, click the “Create New Database…” button. Choose the remote server you created in the previous step from the dropdown list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FMYOEHexh7I_dB3qOs8JIwfB6d644ldbJjRtOwTsfBICf0_WdEaZcLNcplSYEG56gQEOfzL-AJBmPiKlUIKcvfnHPe3Bl-DZqq7DkN3_GJYxa30Pn_rVjhw8qfqK13leMcdcniLFT" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FMYOEHexh7I_dB3qOs8JIwfB6d644ldbJjRtOwTsfBICf0_WdEaZcLNcplSYEG56gQEOfzL-AJBmPiKlUIKcvfnHPe3Bl-DZqq7DkN3_GJYxa30Pn_rVjhw8qfqK13leMcdcniLFT"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Then choose the directory of that instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FABeAY_jrslmK6uDW8D4Oq_I4L0t5Jxt5M6MxwBxLnr3uq7v7pHmtKsq0CCcE4jb49iTzC9usnaLyiejlFxdGiU4dvJAiSXZTs9oNSTUi1nws7KxgayIsrZ9qwSVcJSjnuM2-N_5s" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FABeAY_jrslmK6uDW8D4Oq_I4L0t5Jxt5M6MxwBxLnr3uq7v7pHmtKsq0CCcE4jb49iTzC9usnaLyiejlFxdGiU4dvJAiSXZTs9oNSTUi1nws7KxgayIsrZ9qwSVcJSjnuM2-N_5s"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And come up with a new Database Name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FrznbcBdOgvQvUxOIsUF0JVE8BOQdAFWesfGsV_5xHYT8QaJ1CdfgUw0ZbrCP94cGCTK76KkaXAx1yMrNKFanVVKQKzmRurXvoSdQNnBCAUYKa4Z8TQvFfiXEWUaaLNjgoc8bmp4u" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FrznbcBdOgvQvUxOIsUF0JVE8BOQdAFWesfGsV_5xHYT8QaJ1CdfgUw0ZbrCP94cGCTK76KkaXAx1yMrNKFanVVKQKzmRurXvoSdQNnBCAUYKa4Z8TQvFfiXEWUaaLNjgoc8bmp4u"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Click Finish and don’t forget to choose the same database for Routines. Clear the checkbox “Enable namespace for interoperability productions,” click Save at the top of the page, and you’re all set.&lt;/p&gt;

&lt;p&gt;Before we start working with our globals from C#, let’s check that everything is working and that we have access to the data stored in another instance. To do this, you can, for example, open a terminal on the application server (IRIST), switch the current namespace to the one you created, and set the value of some global.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FKOFe3YohAHGyusrk0aM-SAzKbT_BLmR07Jk2sGQTwrx9k1S98Mi5CvhiYX5vMpnIOaxKMRYmlb96LmmV492acYfDff33JQWAmvweCs4_DGzaKgfqOW49w1BZLBDut96EAM0Fqlq1" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FKOFe3YohAHGyusrk0aM-SAzKbT_BLmR07Jk2sGQTwrx9k1S98Mi5CvhiYX5vMpnIOaxKMRYmlb96LmmV492acYfDff33JQWAmvweCs4_DGzaKgfqOW49w1BZLBDut96EAM0Fqlq1"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Then, in a terminal on the data server, you should be able to read this value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FdXWBqUO_hC-w4n0hVLm2dMVyzD1ZyOulzI2mDuHYk_Prv9UgDp1ptmTsUZVti05PJcKZ1glcgBwBMJ37S3FYMw1WC6EMPYuOBdNKZ-0R8IQHkSJzbu2XgMy-WXKE0qvtWJy_NjdI" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FdXWBqUO_hC-w4n0hVLm2dMVyzD1ZyOulzI2mDuHYk_Prv9UgDp1ptmTsUZVti05PJcKZ1glcgBwBMJ37S3FYMw1WC6EMPYuOBdNKZ-0R8IQHkSJzbu2XgMy-WXKE0qvtWJy_NjdI"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We get the correct value, which means we can proceed with a test application in C# and use eXTreme technology to work with data stored in our data server while having an in-memory connection to our application server.&lt;/p&gt;

&lt;p&gt;First, let me remind you about the adjustments that need to be made for it all to work. To start, environmental variables for Windows must be set:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GLOBALS_HOME should contain the full path to the directory where you put the DBMS. In my case, this is C:\InterSystems\IRIST.&lt;/li&gt;
&lt;li&gt;PATH must contain the full path to the Bin directory. In my case, this is C:\InterSystems\IRIST\Bin.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With both of my instances on the same computer, I have to set the path to my application server instance in the environmental variables, because nowhere in my application code am I directly specifying the instance I’ll be working with.&lt;/p&gt;

&lt;p&gt;By the way, if you just set the variables, you’ll need to log into your Windows user instance again for the changes to take effect.&lt;/p&gt;

&lt;p&gt;Now let’s open the existing eXTreme application from my &lt;a href="https://github.com/Gra-ach/eXTreme-example-for-IRIS" rel="noopener noreferrer"&gt;previous article&lt;/a&gt;. To make sure it will work, check that your license allows such connections. Also, see if the version of .NET you chose for your project is the same as the version referenced in your eXTreme library.&lt;/p&gt;

&lt;p&gt;Before switching to the remote database, I decided to check if my program still works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2Fs-Khc0MxZhnHmV9DOD0mm3VKVwCCcHJPfRKIRYSEB30wNhA1IDkfcPQxMIKU14vhS-Cq9e9TquidKusBaEX9E93rV88HAQemnv5kwe72UWna0QYJ69jEVE0HvvIxdWhCtjb0TZRI" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2Fs-Khc0MxZhnHmV9DOD0mm3VKVwCCcHJPfRKIRYSEB30wNhA1IDkfcPQxMIKU14vhS-Cq9e9TquidKusBaEX9E93rV88HAQemnv5kwe72UWna0QYJ69jEVE0HvvIxdWhCtjb0TZRI"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And it works perfectly. I can see my globals in the database. For now, they’re in the local database of the IRIST instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FtSI6QLcZeH6yEZG0mvdX5r69ozKIYfzFFcXqkzLJcLvnohQgR1dcYRhmSASpyslZayVVHWeJmTC2EsBeA8fSF9HJ8KEeoViWaYCRHuSGnEdTXhOS_tP6kU1n2tFf0TfDrg-0vbvB" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FtSI6QLcZeH6yEZG0mvdX5r69ozKIYfzFFcXqkzLJcLvnohQgR1dcYRhmSASpyslZayVVHWeJmTC2EsBeA8fSF9HJ8KEeoViWaYCRHuSGnEdTXhOS_tP6kU1n2tFf0TfDrg-0vbvB"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now all I need to do to switch to my remote database is change the namespace when I’m connecting to the local instance, IRIST.&lt;/p&gt;

&lt;p&gt;So instead of using the following code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connection myConn = ConnectionContext.GetConnection();
myConn.Connect("USER", "_SYSTEM", "SYS");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I’ll use:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connection myConn = ConnectionContext.GetConnection();
myConn.Connect("IRIS_USER", "_SYSTEM", "SYS");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Thus, I’ll be accessing the namespace IRIS_USER from local application server instance IRIST, which is mapped to a remote database of the data server instance IRIS. The output is the same:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FtBFyynQpUYTEtFIFW04MAgy1Zr297mkwRKCwZvz2d5SvegDKwwliwEPNfWnBw2NMukQbMNZX1W9uMXZMTvbe-TFOhXpLfLRp3Eiq7PNprBfnI0zkmXH5Nwt-3kMBqwW78P0Qu4HL" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FtBFyynQpUYTEtFIFW04MAgy1Zr297mkwRKCwZvz2d5SvegDKwwliwEPNfWnBw2NMukQbMNZX1W9uMXZMTvbe-TFOhXpLfLRp3Eiq7PNprBfnI0zkmXH5Nwt-3kMBqwW78P0Qu4HL"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And we can see this global in the IRIS instance:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FhH19J3QzjbEZdk7-0vORBWWwyi_2-zbuzjkKGHn85d6K0XO77-Qp6SyxUj6P2NXCt9zNz-ocTRhuCxo-auqIcKKM3PsMLoWoMA10t_u-IGyUobjcolryrQ0m2DRzOpUXsnM8Il1j" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2FhH19J3QzjbEZdk7-0vORBWWwyi_2-zbuzjkKGHn85d6K0XO77-Qp6SyxUj6P2NXCt9zNz-ocTRhuCxo-auqIcKKM3PsMLoWoMA10t_u-IGyUobjcolryrQ0m2DRzOpUXsnM8Il1j"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And through ECP:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FWOGuUOCNxOFTSTM_p1-Kh34uCJQSDMbnvj1HFY9ctzd2ub7w4IMWyiu59Cua2eGF8PyeCC_d0Gs1AlDjmAkjqcdHeUgrTXMwKdXYL5Vln9Ie2GDHoXAVzzGe3R7EpnLRLGJfTpMJ" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FWOGuUOCNxOFTSTM_p1-Kh34uCJQSDMbnvj1HFY9ctzd2ub7w4IMWyiu59Cua2eGF8PyeCC_d0Gs1AlDjmAkjqcdHeUgrTXMwKdXYL5Vln9Ie2GDHoXAVzzGe3R7EpnLRLGJfTpMJ"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Mission accomplished! You can use the InterSystems.CacheExtreme.dll library, which you can find in ..\bin\debug\ folder of the example, to connect to IRIS. And you can use ECP to connect to a remote database from an eXTreme application.&lt;/p&gt;

&lt;p&gt;You can read more about setting up the ECP environment in &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=AFL_ecp#AFL_ecp_explore" rel="noopener noreferrer"&gt;First Look: Scaling Systems for User Volume with InterSystems Distributed Caching&lt;/a&gt;. The sample project in this article is the same as in the previous one and is on &lt;a href="https://github.com/Gra-ach/eXTreme-example-for-IRIS" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>intersystems</category>
      <category>net</category>
      <category>extreme</category>
      <category>ecp</category>
    </item>
  </channel>
</rss>
