<?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: Henrique Gonçalves Dias</title>
    <description>The latest articles on DEV Community by Henrique Gonçalves Dias (@diashenrique).</description>
    <link>https://dev.to/diashenrique</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%2F458021%2F6add098a-e42d-4f94-9d78-87de5d793b7f.png</url>
      <title>DEV Community: Henrique Gonçalves Dias</title>
      <link>https://dev.to/diashenrique</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/diashenrique"/>
    <language>en</language>
    <item>
      <title>fhir-integratedml-example overview</title>
      <dc:creator>Henrique Gonçalves Dias</dc:creator>
      <pubDate>Wed, 23 Feb 2022 15:45:44 +0000</pubDate>
      <link>https://dev.to/intersystems/fhir-integratedml-example-overview-4dgc</link>
      <guid>https://dev.to/intersystems/fhir-integratedml-example-overview-4dgc</guid>
      <description>&lt;p&gt;Talking with a friend of mine, Machine Learning specialist &lt;a class="mentioned-user" href="https://dev.to/renatobanzai"&gt;@renatobanzai&lt;/a&gt; , he brought one of the biggest challenges faced by companies nowadays: deploying ML/AI in live environments.&lt;br&gt;
InterSystems IRIS offers IntegratedML. IntegratedML it's a great feature to train, test, and make deploys of ML/AI models.&lt;/p&gt;

&lt;p&gt;The hardest part in creating ML/AI is to make the data treatment, clean up, and make them trusted.&lt;/p&gt;

&lt;p&gt;This is where we can take advantage of FHIR powerful standard!&lt;/p&gt;

&lt;p&gt;The project idea shows how we can create/train/validate ML/AI models with FHIR and utilize them with data from different sources.&lt;/p&gt;

&lt;p&gt;We believe that this project has great potential and a few ideas that can be explored:&lt;/p&gt;

&lt;p&gt;Reuse/extend DTL transformations in other FHIR databases for custom ML models&lt;br&gt;
Use DTL transformations to normalize FHIR messages and publish ML models as services&lt;br&gt;
Create a kind of models + transformations rules repository for use within any FHIR dataset&lt;br&gt;
Exploring new possibilities with this project, we can imagine data from different sources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hXBXNuex--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ee40db6oosb6owfbubop.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hXBXNuex--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ee40db6oosb6owfbubop.png" alt="fhir-integratedml diagram" width="657" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the image above, the FHIR Resource, consuming the REST API, can be used with an FHIRaaS.&lt;/p&gt;

&lt;p&gt;And not only using FHIRaaS on AWS, but we can also make use of the new service &lt;a href="https://aws.amazon.com/marketplace/pp/prodview-q7ryewpz75cq2?sr=0-9&amp;amp;ref_=beagle&amp;amp;applicationId=AWSMPContessa"&gt;HealthShare Message Transformation Services&lt;/a&gt;, that automates the conversion of HL7v2 to FHIR® to populate Amazon HealthLake, where you can extract more value from your data.&lt;/p&gt;

&lt;p&gt;With these small demonstrations, I see these resources being used very well in larger scenarios, enabling and delivering more easily deploys in production in truly innovative environments, like the &lt;a href="https://aws.amazon.com/healthlake/"&gt;AWS Healthlake&lt;/a&gt;. Why not?! 😃 &lt;/p&gt;

</description>
    </item>
    <item>
      <title>An overview of npm-iris</title>
      <dc:creator>Henrique Gonçalves Dias</dc:creator>
      <pubDate>Mon, 05 Jul 2021 18:15:19 +0000</pubDate>
      <link>https://dev.to/intersystems/an-overview-of-npm-iris-2jbb</link>
      <guid>https://dev.to/intersystems/an-overview-of-npm-iris-2jbb</guid>
      <description>&lt;h2&gt;
  
  
  What is npm-iris?
&lt;/h2&gt;

&lt;p&gt;N.P.M stands for "No Project Mess."&lt;/p&gt;

&lt;p&gt;N.P.M. is a Project &amp;amp; Task Management app that uses InterSystems IRIS and Bootstrap 4.&lt;/p&gt;

&lt;p&gt;No Project Mess is created to help developers and small business companies to reduce complexity in their daily problems, with a simple and intuitive projects and tasks management software. &lt;/p&gt;

&lt;p&gt;It offers different views for your tasks, from a spreadsheet, kanban, calendar, or even Gantt!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;Working within different teams, you’ll see different people that prefer different tools. &lt;/p&gt;

&lt;p&gt;So, many times you’ll be using a Gantt chart for a project, a Kanban for another, a list on a paper in other…&lt;/p&gt;

&lt;p&gt;N.P.M. goes straight to the task. No matters how you and your team prefer to see them. Just click and change your view.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Initial Setup

&lt;ul&gt;
&lt;li&gt;Projects&lt;/li&gt;
&lt;li&gt;Users&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Tasks - Create and manage tasks&lt;/li&gt;
&lt;li&gt;Scheduler – A calendar view for your tasks&lt;/li&gt;
&lt;li&gt;Kanban – Manage your tasks in Kanban Style&lt;/li&gt;
&lt;li&gt;Gantt – See your deadlines, milestones, and your progress using a Gantt chart&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Roadmap for New features / Improvements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;OAuth2 authentication &lt;/li&gt;
&lt;li&gt;Security by Project/Team/User&lt;/li&gt;
&lt;li&gt;Time Tracking&lt;/li&gt;
&lt;li&gt;Custom Calendar (Holidays)&lt;/li&gt;
&lt;li&gt;Support for attached files&lt;/li&gt;
&lt;li&gt;Make use of AppS.REST framework&lt;/li&gt;
&lt;li&gt;Vue.js Edition&lt;/li&gt;
&lt;li&gt;Home dashboard to see the general status for the activities&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Download
&lt;/h3&gt;

&lt;p&gt;You can try the application &lt;strong&gt;for free&lt;/strong&gt; ! =] &lt;br&gt;
&lt;a href="https://openexchange.intersystems.com/package/npm-iris"&gt;npm-iris on OpenExchange&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Tasks&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The task view it's easy to use as filling cells in an Excel spreadsheet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0vzcWAzX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rgp9sfmjdv13qmcpg2i8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0vzcWAzX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rgp9sfmjdv13qmcpg2i8.png" alt="tasks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scheduler&lt;/strong&gt;&lt;br&gt;
Scheduler view gives you the option to see your tasks as appointments, in the week, month, and Agenda viewer, acting as a Google Calendar clone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y1_p0t4a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/okzhhox73hlqonban39g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y1_p0t4a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/okzhhox73hlqonban39g.png" alt="scheduler"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kanban&lt;/strong&gt;&lt;br&gt;
For those who prefers deal with the tasks in a Kanban Style, this view it's perfect to do it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I4Xafc_n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fkdztssq64x6czrf0lh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I4Xafc_n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fkdztssq64x6czrf0lh.png" alt="kanban"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gantt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, for the Project Managers out there, looking forward to follow the project in real time, using a MS Project style, this view is for you!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rsCu6srv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g9jw2ifdf19k71noaroy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rsCu6srv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g9jw2ifdf19k71noaroy.png" alt="gantt"&gt;&lt;/a&gt; &lt;/p&gt;

</description>
      <category>kanban</category>
      <category>gantt</category>
      <category>intersystemsiris</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Building an Alternative IRIS Message Viewer</title>
      <dc:creator>Henrique Gonçalves Dias</dc:creator>
      <pubDate>Wed, 28 Oct 2020 14:41:13 +0000</pubDate>
      <link>https://dev.to/intersystems/building-an-alternative-iris-message-viewer-3pmc</link>
      <guid>https://dev.to/intersystems/building-an-alternative-iris-message-viewer-3pmc</guid>
      <description>&lt;p&gt;&lt;strong&gt;If you had the opportunity to change something in the IRIS Interoperability Message Viewer, what would you do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After publishing the article &lt;a href="https://community.intersystems.com/post/dashboard-iris-history-monitor"&gt;Dashboard IRIS History Monitor&lt;/a&gt;, I received some great feedback and some requests. One request was for an enhanced Message Viewer.&lt;/p&gt;

&lt;p&gt;If you haven’t yet done so, check out the project—it’s definitely worth your time, and it won the Bronze award as one of &lt;a href="https://community.intersystems.com/post/best-intersystems-open-exchange-developers-and-applications-2019"&gt;The Best InterSystems Open Exchange Developers and Applications in 2019&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I started drafting some ideas about the features I’d want to include in the “new” Message Viewer, but how could I show these resources in the fastest and easiest way?&lt;/p&gt;

&lt;p&gt;Well, first things first. You generally start by setting up an interoperability production, then exporting and deploying it on the target system, as indicated in the &lt;a href="https://docs.intersystems.com/iris20194/csp/docbook/Doc.View.cls?KEY=EGDV_deploying"&gt;documentation&lt;/a&gt;. This is a process I really don’t like. Not that there’s anything wrong with it, really. I’ve just idealized doing everything using code.&lt;/p&gt;

&lt;p&gt;I expect that every time someone runs this sort of project, they start like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker-compose build
$ docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And voilá!!!&lt;/p&gt;

&lt;p&gt;With those simple steps in mind, I started to look in the InterSystems community and found a few tips. One of the posts brought up the question I was asking myself: &lt;a href="https://community.intersystems.com/post/how-create-productions-routine"&gt;How to create productions via routine?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In that post,  &lt;a href="https://community.intersystems.com/user/eduard-lebedyuk"&gt;Eduard Lebedyuk&lt;/a&gt; answered, showing how to create a production using code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To create production class automatically you need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create %Dictionary.ClassDefinition object for your test production&lt;/li&gt;
&lt;li&gt;Create Ens.Config.Production object&lt;/li&gt;
&lt;li&gt;Create %Dictionary.XDataDefinition&lt;/li&gt;
&lt;li&gt;Serialize (2) into (3)&lt;/li&gt;
&lt;li&gt;Insert XData (3) into (1)&lt;/li&gt;
&lt;li&gt;Save and compile (1)&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;I also found a comment from &lt;a href="https://community.intersystems.com/user/jenny-ames"&gt;Jenny Ames&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One best practice we often recommend is to build backward. Build business operations first, then business processes, then business services…&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, let’s do it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Requests, Business Operations, and Business Services
&lt;/h2&gt;

&lt;p&gt;The class &lt;strong&gt;diashenrique.messageviewer.util.InstallerProduction.cls&lt;/strong&gt; is, as the name suggests, the class responsible for installing our production. The installer manifest invokes the ClassMethod &lt;strong&gt;Install&lt;/strong&gt; from that class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// Helper to install a production to display capabilities of the enhanced viewer

ClassMethod Install() As %Status
{

    Set sc = $$$OK

    Try {

        Set sc = $$$ADDSC(sc,..InstallProduction()) quit:$$$ISERR(sc)

        Set sc = $$$ADDSC(sc,..GenerateMessages()) quit:$$$ISERR(sc)

        Set sc = $$$ADDSC(sc,..GenerateUsingEnsDirector()) quit:$$$ISERR(sc)

    }

    Catch (err) {

        Set sc = $$$ADDSC(sc,err.AsStatus())

    }

    Return sc

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The classmethod &lt;strong&gt;InstallProduction&lt;/strong&gt; brings together the main structure for creating a production by creating:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a request&lt;/li&gt;
&lt;li&gt;a business operation&lt;/li&gt;
&lt;li&gt;a business service&lt;/li&gt;
&lt;li&gt;an interoperability production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since the idea is to create an interoperability production using code, let’s go into full coding mode to create all classes for the request, the business operation, and the business services. In doing so, we’ll make extensive use of some InterSystems library packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;%Dictionary.ClassDefinition&lt;/li&gt;
&lt;li&gt;%Dictionary.PropertyDefinition&lt;/li&gt;
&lt;li&gt;%Dictionary.XDataDefinition&lt;/li&gt;
&lt;li&gt;%Dictionary.MethodDefinition&lt;/li&gt;
&lt;li&gt;%Dictionary.ParameterDefinition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The classmethod &lt;strong&gt;InstallProduction&lt;/strong&gt; creates two classes that extend from &lt;strong&gt;Ens.Request&lt;/strong&gt;, using the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set sc = $$$ADDSC(sc,..CreateRequest("diashenrique.messageviewer.Message.SimpleRequest","Message")) quit:$$$ISERR(sc)

Set sc = $$$ADDSC(sc,..CreateRequest("diashenrique.messageviewer.Message.AnotherRequest","Something")) quit:$$$ISERR(sc)

ClassMethod CreateRequest(classname As %String, prop As %String) As %Status [ Private ]

{

    New $Namespace

    Set $Namespace = ..#NAMESPACE

    Set sc = $$$OK

    Try {

        Set class = ##class(%Dictionary.ClassDefinition).%New(classname)

        Set class.GeneratedBy = $ClassName()

        Set class.Super = "Ens.Request"

        Set class.ProcedureBlock = 1

        Set class.Inheritance = "left"

        Set sc = $$$ADDSC(sc,class.%Save())

        #; create adapter

        Set property = ##class(%Dictionary.PropertyDefinition).%New(classname)

        Set property.Name = prop

        Set property.Type = "%String"

        Set sc = $$$ADDSC(sc,property.%Save())

        Set sc = $$$ADDSC(sc,$System.OBJ.Compile(classname,"fck-dv"))

    }

    Catch (err) {

        Set sc = $$$ADDSC(sc,err.AsStatus())

    }

    Return sc

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s create the class for a business operation that extends from &lt;strong&gt;Ens.BusinessOperation:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set sc = $$$ADDSC(sc,..CreateOperation()) quit:$$$ISERR(sc)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Besides creating the class, we create the MessageMap and the method Consume:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ClassMethod CreateOperation() As %Status [ Private ]
{
    New $Namespace
    Set $Namespace = ..#NAMESPACE
    Set sc = $$$OK
    Try {
        Set classname = "diashenrique.messageviewer.Operation.Consumer"
        Set class = ##class(%Dictionary.ClassDefinition).%New(classname)
        Set class.GeneratedBy = $ClassName()
        Set class.Super = "Ens.BusinessOperation"
        Set class.ProcedureBlock = 1
        Set class.Inheritance = "left"

        Set xdata = ##class(%Dictionary.XDataDefinition).%New()
        Set xdata.Name = "MessageMap"
        Set xdata.XMLNamespace = "http://www.intersystems.com/urlmap"
        Do xdata.Data.WriteLine("&amp;lt;MapItems&amp;gt;")
        Do xdata.Data.WriteLine("&amp;lt;MapItem MessageType=""diashenrique.messageviewer.Message.SimpleRequest""&amp;gt;")
        Do xdata.Data.WriteLine("&amp;lt;Method&amp;gt;Consume&amp;lt;/Method&amp;gt;")
        Do xdata.Data.WriteLine("&amp;lt;/MapItem&amp;gt;")
        Do xdata.Data.WriteLine("&amp;lt;MapItem MessageType=""diashenrique.messageviewer.Message.AnotherRequest""&amp;gt;")
        Do xdata.Data.WriteLine("&amp;lt;Method&amp;gt;Consume&amp;lt;/Method&amp;gt;")
        Do xdata.Data.WriteLine("&amp;lt;/MapItem&amp;gt;")
        Do xdata.Data.WriteLine("&amp;lt;/MapItems&amp;gt;")      
        Do class.XDatas.Insert(xdata)
        Set sc = $$$ADDSC(sc,class.%Save())

        Set method = ##class(%Dictionary.MethodDefinition).%New(classname)
        Set method.Name = "Consume"
        Set method.ClassMethod = 0
        Set method.ReturnType = "%Status"
        Set method.FormalSpec = "input:diashenrique.messageviewer.Message.SimpleRequest,&amp;amp;output:Ens.Response"
        Set stream = ##class(%Stream.TmpCharacter).%New()
        Do stream.WriteLine("   set sc = $$$OK")
        Do stream.WriteLine("   $$$TRACE(input.Message)")
        Do stream.WriteLine("   return sc")
        Set method.Implementation = stream
        Set sc = $$$ADDSC(sc,method.%Save())

        Set sc = $$$ADDSC(sc,$System.OBJ.Compile(classname,"fck-dv"))
    }
    Catch (err) {
        Set sc = $$$ADDSC(sc,err.AsStatus())
    }
    Return sc
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the last step before actually creating the interoperability production, let’s create the class responsible for the business service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set sc = $$$ADDSC(sc,..CreateRESTService()) quit:$$$ISERR(sc)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class has UrlMap and Routes to receive Http requests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ClassMethod CreateRESTService() As %Status [ Private ]
{
    New $Namespace
    Set $Namespace = ..#NAMESPACE
    Set sc = $$$OK
    Try {
        Set classname = "diashenrique.messageviewer.Service.REST"
        Set class = ##class(%Dictionary.ClassDefinition).%New(classname)
        Set class.GeneratedBy = $ClassName()
        Set class.Super = "EnsLib.REST.Service, Ens.BusinessService"
        Set class.ProcedureBlock = 1
        Set class.Inheritance = "left"

        Set xdata = ##class(%Dictionary.XDataDefinition).%New()
        Set xdata.Name = "UrlMap"
        Set xdata.XMLNamespace = "http://www.intersystems.com/urlmap"
        Do xdata.Data.WriteLine("&amp;lt;Routes&amp;gt;")
        Do xdata.Data.WriteLine("&amp;lt;Route Url=""/send/message"" Method=""POST"" Call=""SendMessage""/&amp;gt;")
        Do xdata.Data.WriteLine("&amp;lt;Route Url=""/send/something"" Method=""POST"" Call=""SendSomething""/&amp;gt;")
        Do xdata.Data.WriteLine("&amp;lt;/Routes&amp;gt;")
        Do class.XDatas.Insert(xdata)
        Set sc = $$$ADDSC(sc,class.%Save())

        #; create adapter
        Set adapter = ##class(%Dictionary.ParameterDefinition).%New(classname)
        Set class.GeneratedBy = $ClassName()
        Set adapter.Name = "ADAPTER"
        Set adapter.SequenceNumber = 1
        Set adapter.Default = "EnsLib.HTTP.InboundAdapter"
        Set sc = $$$ADDSC(sc,adapter.%Save())

        #; add prefix
        Set prefix = ##class(%Dictionary.ParameterDefinition).%New(classname)
        Set prefix.Name = "EnsServicePrefix"
        Set prefix.SequenceNumber = 2
        Set prefix.Default = "|demoiris"
        Set sc = $$$ADDSC(sc,prefix.%Save())

        Set method = ##class(%Dictionary.MethodDefinition).%New(classname)
        Set method.Name = "SendMessage"
        Set method.ClassMethod = 0
        Set method.ReturnType = "%Status"
        Set method.FormalSpec = "input:%Library.AbstractStream,&amp;amp;output:%Stream.Object"
        Set stream = ##class(%Stream.TmpCharacter).%New()
        Do stream.WriteLine("   set sc = $$$OK")
        Do stream.WriteLine("   set request = ##class(diashenrique.messageviewer.Message.SimpleRequest).%New()")
        Do stream.WriteLine("   set data = {}.%FromJSON(input)")
        Do stream.WriteLine("   set request.Message = data.Message")
        Do stream.WriteLine("   set sc = $$$ADDSC(sc,..SendRequestSync(""diashenrique.messageviewer.Operation.Consumer"",request,.response))")
        Do stream.WriteLine("   return sc")
        Set method.Implementation = stream
        Set sc = $$$ADDSC(sc,method.%Save())

        Set method = ##class(%Dictionary.MethodDefinition).%New(classname)
        Set method.Name = "SendSomething"
        Set method.ClassMethod = 0
        Set method.ReturnType = "%Status"
        Set method.FormalSpec = "input:%Library.AbstractStream,&amp;amp;output:%Stream.Object"
        Set stream = ##class(%Stream.TmpCharacter).%New()
        Do stream.WriteLine("   set sc = $$$OK")
        Do stream.WriteLine("   set request = ##class(diashenrique.messageviewer.Message.AnotherRequest).%New()")
        Do stream.WriteLine("   set data = {}.%FromJSON(input)")
        Do stream.WriteLine("   set request.Something = data.Something")
        Do stream.WriteLine("   set sc = $$$ADDSC(sc,..SendRequestSync(""diashenrique.messageviewer.Operation.Consumer"",request,.response))")
        Do stream.WriteLine("   return sc")
        Set method.Implementation = stream
        Set sc = $$$ADDSC(sc,method.%Save())

        Set sc = $$$ADDSC(sc,$System.OBJ.Compile(classname,"fck-dv"))
    }
    Catch (err) {
        Set sc = $$$ADDSC(sc,err.AsStatus())
    }
    Return sc
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using Visual Studio Code
&lt;/h2&gt;

&lt;p&gt;Creating the classes using the %Dictionary package can be difficult, and difficult to read as well, but it’s handy. To demonstrate a slightly more straightforward approach with better code readability, I’ll also create new request, business service, and business operations classes using Visual Studio Code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;diashenrique.messageviewer.Message.SimpleMessage.cls&lt;/li&gt;
&lt;li&gt;diashenrique.messageviewer.Operation.ConsumeMessageClass.cls&lt;/li&gt;
&lt;li&gt;diashenrique.messageviewer.Service.SendMessage.cls
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Class diashenrique.messageviewer.Message.SimpleMessage Extends Ens.Request [ Inheritance = left, ProcedureBlock ]
{
Property ClassMessage As %String;
}

Class diashenrique.messageviewer.Operation.ConsumeMessageClass Extends Ens.BusinessOperation [ Inheritance = left, ProcedureBlock ]
{
Method Consume(input As diashenrique.messageviewer.Message.SimpleMessage, ByRef output As Ens.Response) As %Status
{
    Set sc = $$$OK
    $$$TRACE(pRequest.ClassMessage)
    Return sc
}
XData MessageMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
  &amp;lt;MapItems&amp;gt;
    &amp;lt;MapItem MessageType="diashenrique.messageviewer.Message.SimpleMessage"&amp;gt;
      &amp;lt;Method&amp;gt;Consume&amp;lt;/Method&amp;gt;
    &amp;lt;/MapItem&amp;gt;
  &amp;lt;/MapItems&amp;gt;
} 
}

Class diashenrique.messageviewer.Service.SendMessage Extends Ens.BusinessService [ ProcedureBlock ]
{ 
Method OnProcessInput(input As %Library.AbstractStream, ByRef output As %Stream.Object) As %Status
{
    Set tSC = $$$OK
    // Create the request message
    Set request = ##class(diashenrique.messageviewer.Message.SimpleMessage).%New()
    // Place a value in the request message property
    Set request.ClassMessage = input
    // Make a synchronous call to the business process and use the response message as our response 
    Set tSC = ..SendRequestSync("diashenrique.messageviewer.Operation.ConsumeMessageClass",request,.output)
    Quit tSC
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From a code readability perspective, it’s a huge difference! &lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Interoperability Production
&lt;/h2&gt;

&lt;p&gt;Let’s finish up the creation of our interoperability production. To do so, we’ll create a production class, then associate it with the business Operation and Service classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set sc = $$$ADDSC(sc,..CreateProduction()) quit:$$$ISERR(sc)

ClassMethod CreateProduction(purge As %Boolean = 0) As %Status [ Private ]
{
    New $Namespace
    Set $Namespace = ..#NAMESPACE
    Set sc = $$$OK
    Try {
         #; create new production
        Set class = ##class(%Dictionary.ClassDefinition).%New(..#PRODUCTION)
        Set class.ProcedureBlock = 1
        Set class.Super = "Ens.Production"
        Set class.GeneratedBy = $ClassName()
        Set xdata = ##class(%Dictionary.XDataDefinition).%New()
        Set xdata.Name = "ProductionDefinition"
        Do xdata.Data.Write("&amp;lt;Production Name="""_..#PRODUCTION_""" LogGeneralTraceEvents=""true""&amp;gt;&amp;lt;/Production&amp;gt;")  
        Do class.XDatas.Insert(xdata)
        Set sc = $$$ADDSC(sc,class.%Save())
        Set sc = $$$ADDSC(sc,$System.OBJ.Compile(..#PRODUCTION,"fck-dv"))
        Set production = ##class(Ens.Config.Production).%OpenId(..#PRODUCTION)
        Set item = ##class(Ens.Config.Item).%New()
        Set item.ClassName = "diashenrique.messageviewer.Service.REST"
        Do production.Items.Insert(item)
        Set sc = $$$ADDSC(sc,production.%Save())
        Set item = ##class(Ens.Config.Item).%New()
        Set item.ClassName = "diashenrique.messageviewer.Operation.Consumer"
        Do production.Items.Insert(item)
        Set sc = $$$ADDSC(sc,production.%Save())    
        Set item = ##class(Ens.Config.Item).%New()
        Set item.ClassName = "diashenrique.messageviewer.Service.SendMessage"
        Do production.Items.Insert(item)
        Set sc = $$$ADDSC(sc,production.%Save())    
        Set item = ##class(Ens.Config.Item).%New()
        Set item.ClassName = "diashenrique.messageviewer.Operation.ConsumeMessageClass"
        Do production.Items.Insert(item)
        Set sc = $$$ADDSC(sc,production.%Save())    
    }
    Catch (err) {
        Set sc = $$$ADDSC(sc,err.AsStatus())
    }
    Return sc
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use the class &lt;strong&gt;Ens.Config.Item&lt;/strong&gt; to associate the production class with the business Operation and Service classes. You can do this whether you created your class using the %Dictionary package or with VS Code, Studio, or Atelier.&lt;/p&gt;

&lt;p&gt;In any case, we did it! We created an interoperability production using code.&lt;/p&gt;

&lt;p&gt;But remember the original purpose of all this code: to create a production and messages to show the capabilities of the enhanced Message Viewer. Using the classmethods that follow, we’ll execute both of our business services and generate the messages. &lt;/p&gt;

&lt;h2&gt;
  
  
  Generating Messages using %Net.HttpRequest
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ClassMethod GenerateMessages() As %Status [ Private ]
{
    New $Namespace
    Set $Namespace = ..#NAMESPACE
    Set sc = $$$OK
    Try {
        Set action(0) = "/demoiris/send/message"
        Set action(1) = "/demoiris/send/something"
        For i=1:1:..#LIMIT {
            Set content = { }
            Set content.Message = "Hi, I'm just a random message named "_$Random(30000)
            Set content.Something = "Hi, I'm just a random something named "_$Random(30000)
            Set httprequest = ##class(%Net.HttpRequest).%New()
            Set httprequest.SSLCheckServerIdentity = 0
            Set httprequest.SSLConfiguration = ""
            Set httprequest.Https = 0
            Set httprequest.Server = "localhost"
            Set httprequest.Port = 9980
            Set serverUrl = action($Random(2))
            Do httprequest.EntityBody.Write(content.%ToJSON())
            Set sc = httprequest.Post(serverUrl) 
            Quit:$$$ISERR(sc)
        }
    }
    Catch (err) {
        Set sc = $$$ADDSC(sc,err.AsStatus())
    }
    Return sc
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Generating Messages using EnsDirector
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ClassMethod GenerateUsingEnsDirector() As %Status [ Private ]
{
    New $Namespace
    Set $Namespace = ..#NAMESPACE
    Set sc = $$$OK
    Try {
        For i=1:1:..#LIMIT {
            Set tSC = ##class(Ens.Director).CreateBusinessService("diashenrique.messageviewer.Service.SendMessage",.tService)
            Set message = "Message Generated By CreateBusinessService "_$Random(1000)
            Set tSC = tService.ProcessInput(message,.output)
            Quit:$$$ISERR(sc)
        }
    }
    Catch (err) {
        Set sc = $$$ADDSC(sc,err.AsStatus())
    }
    Return sc
}

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it for the code. You’ll find the complete project at &lt;a href="https://github.com/diashenrique/iris-message-viewer"&gt;https://github.com/diashenrique/iris-message-viewer&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Running the Project
&lt;/h2&gt;

&lt;p&gt;Now let’s see the project in action. First, git clone or git pull the repo into any local directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/diashenrique/iris-message-viewer.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, open the terminal in this directory and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, run the IRIS container with your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we’ll access the Management Portal using &lt;a href="http://localhost:52773/csp/sys/UtilHome.csp"&gt;http://localhost:52773/csp/sys/UtilHome.csp&lt;/a&gt;. You should see our interoperability namespace MSGVIEWER, as in the image below:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XfCQgxn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.intersystems.com/sites/default/files/inline/images/images/iris_managementportal.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XfCQgxn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.intersystems.com/sites/default/files/inline/images/images/iris_managementportal.png" alt="IRIS Management Portal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here’s our baby Production, with two business services and two business operations:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XqTRi21u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.intersystems.com/sites/default/files/inline/images/images/iris_production.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XqTRi21u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.intersystems.com/sites/default/files/inline/images/images/iris_production.png" alt="IRIS Production"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have so many messages:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZkGtSHsW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.intersystems.com/sites/default/files/inline/images/images/standardmessageviewer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZkGtSHsW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://community.intersystems.com/sites/default/files/inline/images/images/standardmessageviewer.png" alt="Standard Message Viewer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With everything up and running in our custom Message Viewer, let’s take a look at some of its features.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Enhanced Message Viewer
&lt;/h2&gt;

&lt;p&gt;Keep in mind that only namespaces that are enabled for interoperability productions will be displayed.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:52773/csp/msgviewer/messageviewer.csp"&gt;http://localhost:52773/csp/msgviewer/messageviewer.csp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xMuoRtTB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/InteroperabilityNamespace.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xMuoRtTB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/InteroperabilityNamespace.png" alt="Interoperability Message Viewer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The enhanced Message Viewer brings features and flexibility that allow you to create different filters, group the columns into n-levels, export to Excel, and much more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nz8rfxDW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/MessageViewer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nz8rfxDW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/MessageViewer.png" alt="Interoperability Message Viewer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use different filters to achieve the results you need. You can also use multiple sorts by pressing Shift and clicking on the column header. You even export the data grid to Excel!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vK1E9ckL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/FilterOption.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vK1E9ckL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/FilterOption.gif" alt="Filters Options"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DYhLTY2c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/FilterPanel.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DYhLTY2c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/FilterPanel.gif" alt="Filter Panel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition, you can create complex filters with the filter builder option.&lt;/p&gt;

&lt;p&gt;You can group data against any column available, grouping the information using the n-levels you want. By default, the group is constructed using the Date Created field.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2VDcQ8al--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/GroupByFunction.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2VDcQ8al--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/GroupByFunction.gif" alt="Group Data"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And there’s a feature that allows you to select columns. The following page has all the columns from Ens.MessageHeader, showing only the default columns in the initial view. But you can choose the other columns using the "Column Chooser" button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8erYdGcr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/ColumnChooser.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8erYdGcr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/ColumnChooser.gif" alt="Column Chooser"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can collapse or expand all groups with a single click.&lt;/p&gt;

&lt;p&gt;Collapse or Expand all groups in a single click.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bqgM3Bnd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/Collapse_Expand.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bqgM3Bnd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/Collapse_Expand.gif" alt="Collapse / Expand"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The information in the SessionId field has a link to the Visual Trace feature.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rZYPmky6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/MessageVisualTrace.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rZYPmky6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/MessageVisualTrace.png" alt="Visual Trace"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can resend messages if you need to. Simply select the messages you need and click to resend. This feature uses the following classMethod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;##class(Ens.MessageHeader).ResendDuplicatedMessage(id)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VOCvuUR4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/ResendMessage.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VOCvuUR4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/ResendMessage.gif" alt="Resend Messages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, as mentioned, you can export your data grid to Excel:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--COL1mSzm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/ExportToExcel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--COL1mSzm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/diashenrique/iris-message-viewer/master/images/ExportToExcel.png" alt="Excel File"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result in Excel will show the same format, content, and group defined in the cache server pages (CSP).&lt;/p&gt;

&lt;p&gt;PS: I want to give special thanks to &lt;a href="https://community.intersystems.com/user/rhenan-lourenco"&gt;Renan Lourenco&lt;/a&gt; who helped me a lot on this journey.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://openexchange.intersystems.com/package/IRIS-Interoperability-Message-Viewer"&gt;Check the related application on InterSystems Open Exchange.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>interoperability</category>
      <category>intersystemsiris</category>
      <category>docker</category>
      <category>objectscript</category>
    </item>
  </channel>
</rss>
