<?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: Yuri Marx P. Gomes</title>
    <description>The latest articles on DEV Community by Yuri Marx P. Gomes (@yurimpg).</description>
    <link>https://dev.to/yurimpg</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%2F451404%2F536e05df-a64b-4a22-8c55-f6961d1f5b8e.jpg</url>
      <title>DEV Community: Yuri Marx P. Gomes</title>
      <link>https://dev.to/yurimpg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yurimpg"/>
    <language>en</language>
    <item>
      <title>Technical View: Crawler and NLP to do website text analytics</title>
      <dc:creator>Yuri Marx P. Gomes</dc:creator>
      <pubDate>Thu, 11 Aug 2022 22:06:00 +0000</pubDate>
      <link>https://dev.to/intersystems/technical-view-crawler-and-nlp-to-do-website-text-analytics-d1g</link>
      <guid>https://dev.to/intersystems/technical-view-crawler-and-nlp-to-do-website-text-analytics-d1g</guid>
      <description>&lt;p&gt;Web Crawling is a technique used to extract root and related content (HTML, Videos, Images, etc.) from websites to your local disk. This is allows you apply NLP to analyze the content and get important insights. This article detail how to do web crawling and NLP.&lt;/p&gt;

&lt;p&gt;To do web crawling you can choose a tool in Java or Python. In my case I'm using Crawler4J. (&lt;a href="https://github.com/yasserg/crawler4j"&gt;https://github.com/yasserg/crawler4j&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Crawler4j is an open source web crawler for Java which provides a simple interface for crawling the Web. Using it, you can setup a multi-threaded web crawler in few minutes.&lt;/p&gt;

&lt;p&gt;After create your Java project, include maven dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;edu.uci.ics&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;crawler4j&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;4.4.0&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Now, create a class to do the crawler. See you need extends WebCrawler and implement shouldVisit to indicate the file types that will be extracted and visit to get the content and write in your disk. Very simple!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

public class CrawlerUtil extends WebCrawler {

private final static Pattern FILTERS = Pattern.compile(".*(\\.(css|js|gif|jpg|png|mp3|mp4|zip|gz))$");

@Override
public boolean shouldVisit(Page referringPage, WebURL url) {
        System.out.println("shouldVisit: " + url.getURL().toLowerCase());

        String href = url.getURL().toLowerCase();
        boolean result = !FILTERS.matcher(href).matches();

        if (result)
            System.out.println("URL Should Visit");
        else
            System.out.println("URL Should not Visit");

        return result;
    }

    @Override
    public void visit(Page page) {
        String url = page.getWebURL().getURL();
        System.out.println("URL: " + url);

        if (page.getParseData() instanceof HtmlParseData) {
            HtmlParseData htmlParseData = (HtmlParseData) page.getParseData();      
            String text = htmlParseData.getText(); //extract text from page
            String html = htmlParseData.getHtml(); //extract html from page
            Set&amp;lt;WebURL&amp;gt; links = htmlParseData.getOutgoingUrls();

            System.out.println("---------------------------------------------------------");
            System.out.println("Page URL: " + url);
            System.out.println("Text length: " + text.length());
            System.out.println("Html length: " + html.length());
            System.out.println("Number of outgoing links: " + links.size());
            System.out.println("---------------------------------------------------------");

            final String OS = System.getProperty("os.name").toLowerCase();

            FileOutputStream outputStream;

            File file;

            try {

                if(OS.indexOf("win") &amp;gt;= 0) {
                    file = new File("c:\\crawler\\nlp" + UUID.randomUUID().toString() + ".txt");
                } else {
                    file = new File("/var/crawler/nlp/" + UUID.randomUUID().toString() + ".txt");
                }

                outputStream = new FileOutputStream(file);

                byte[] strToBytes = text.getBytes();

                outputStream.write(strToBytes);

                outputStream.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After, you need to create a Java PEX Business Operation to allows IRIS call this Crawler implementation into a production. To do this is necessary extends the class BusinessOperation (from intersystems) and write your code, simple! The method OnInit allows you instantiate the Java Gateway (a middleware from the InterSystems to promote ObjectScript and Java conversation). In the method OnMessage, you use gateway instance into iris variable to send the java results to IRIS.&lt;/p&gt;

&lt;p&gt;The Crawler Java logic in this class run in the executeCrawler. You need set setMaxDepthOfCrawling to config how many sub pages will be visited and setCrawlStorageFolder with folder path to store Crawler4J processing. So you call start passing the number of pages, to limit your crawling. The robotconfig allows you follow the website policies about crawling and another rules. See all the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class WebsiteAnalyzerOperation extends BusinessOperation {

    // Connection to InterSystems IRIS
    private IRIS iris;

    @Override
    public void OnInit() throws Exception {
        iris = GatewayContext.getIRIS();
    }

    @Override
    public Object OnMessage(Object request) throws Exception {
        IRISObject req = (IRISObject) request;

        String website = req.getString("Website");
        Long depth = req.getLong("Depth");
        Long pages = req.getLong("Pages");

        String result = executeCrawler(website, depth, pages);
        IRISObject response = (IRISObject)(iris.classMethodObject("Ens.StringContainer","%New", result));

        return response;
    }

    public String executeCrawler(String website, Long depth, Long pages) {

        final int MAX_CRAWL_DEPTH = depth.intValue();
        final int NUMBER_OF_CRAWELRS = pages.intValue();

        final String OS = System.getProperty("os.name").toLowerCase();

        String CRAWL_STORAGE = "";

        if(OS.indexOf("win") &amp;gt;= 0) {
            CRAWL_STORAGE = "c:\\crawler\\storage";
        } else {
            CRAWL_STORAGE = "/var/crawler/storage";
        }

        CrawlConfig config = new CrawlConfig();
        config.setCrawlStorageFolder(CRAWL_STORAGE);
        config.setIncludeHttpsPages(true);
        config.setMaxDepthOfCrawling(MAX_CRAWL_DEPTH);

        PageFetcher pageFetcher = new PageFetcher(config);
        RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
        RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);

        CrawlController controller;
        try {
            controller = new CrawlController(config, pageFetcher, robotstxtServer);

            controller.addSeed(website);

            controller.start(CrawlerUtil.class, NUMBER_OF_CRAWELRS);

            return "website extracted with success";

        } catch (Exception e) {
            return e.getMessage();
        }

    }

    @Override
    public void OnTearDown() throws Exception {

    }

}

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

&lt;/div&gt;



&lt;p&gt;With the content extracted, you can create a NLP domain pointing to the folder with the extractions, see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;files listname="File_1" batchMode="false" disabled="false" listerClass="%iKnow.Source.File.Lister" path="/var/crawler/nlp/" recursive="false" extensions="txt"&amp;gt;
&amp;lt;parameter value="/var/crawler/nlp/" isList="false" /&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;All the implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Class dc.WebsiteAnalyzer.WebsiteAnalyzerNLP Extends %iKnow.DomainDefinition [ ProcedureBlock ]
{

XData Domain [ XMLNamespace = "http://www.intersystems.com/iknow" ]
{
&amp;lt;domain name="WebsiteAnalyzerDomain" disabled="false" allowCustomUpdates="true"&amp;gt;
&amp;lt;parameter name="DefaultConfig" value="WebsiteAnalyzerDomain.Configuration" isList="false" /&amp;gt;
&amp;lt;data dropBeforeBuild="true"&amp;gt;
&amp;lt;files listname="File_1" batchMode="false" disabled="false" listerClass="%iKnow.Source.File.Lister" path="/var/crawler/nlp/" recursive="false" extensions="txt"&amp;gt;
&amp;lt;parameter value="/var/crawler/nlp/" isList="false" /&amp;gt;
&amp;lt;parameter isList="false" /&amp;gt;
&amp;lt;parameter value="0" isList="false" /&amp;gt;
&amp;lt;/files&amp;gt;
&amp;lt;/data&amp;gt;
&amp;lt;matching disabled="false" dropBeforeBuild="true" autoExecute="true" ignoreDictionaryErrors="true" /&amp;gt;
&amp;lt;metadata /&amp;gt;
&amp;lt;configuration name="WebsiteAnalyzerDomain.Configuration" detectLanguage="true" languages="en,pt,nl,fr,de,es,ru,uk" userDictionary="WebsiteAnalyzerDomain.Dictionary#1" summarize="true" maxConceptLength="0" /&amp;gt;
&amp;lt;userDictionary name="WebsiteAnalyzerDomain.Dictionary#1"&amp;gt;
&amp;lt;/domain&amp;gt;
}

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

&lt;/div&gt;



&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;Now, InterSystems NLP can present the results to you into Text Analytics - Domain Explorer.&lt;/p&gt;

&lt;p&gt;See all implementation code in the github, download and run!&lt;br&gt;
See all the source code, build and run it here: &lt;a href="https://openexchange.intersystems.com/package/website-analyzer"&gt;https://openexchange.intersystems.com/package/website-analyzer&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mastering the %SYSTEM.Encryption class</title>
      <dc:creator>Yuri Marx P. Gomes</dc:creator>
      <pubDate>Thu, 11 Aug 2022 22:00:21 +0000</pubDate>
      <link>https://dev.to/intersystems/mastering-the-systemencryption-class-4hh</link>
      <guid>https://dev.to/intersystems/mastering-the-systemencryption-class-4hh</guid>
      <description>&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9xzk99b9ojoyw8mx1zc.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9xzk99b9ojoyw8mx1zc.png" alt="Types of encryptation and decryptation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The InterSystems IRIS has excellent support for encryption, decryption and hashing operations. Inside the class %SYSTEM.Encryption (&lt;a href="https://docs.intersystems.com/iris20212/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&amp;amp;PRIVATE=1&amp;amp;CLASSNAME=%25SYSTEM.Encryption" rel="noopener noreferrer"&gt;https://docs.intersystems.com/iris20212/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&amp;amp;PRIVATE=1&amp;amp;CLASSNAME=%25SYSTEM.Encryption&lt;/a&gt;) there are class methods for the main algorithms on the market.&lt;/p&gt;

&lt;h2&gt;
  
  
  IRIS Algorithms and Encrypt/Decrypt types
&lt;/h2&gt;

&lt;p&gt;As you can see, the operations are based on keys and include 3 options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symmetric Keys: the parts running encrypt and decrypt operations share the same secret key.&lt;/li&gt;
&lt;li&gt;Asymmetric Keys: the parts conducting encrypt and decrypt operations share the same secret key for encryption. However, for decryption, each partner has a private key. This key cannot be shared with other people, because it is an identity proof.&lt;/li&gt;
&lt;li&gt;Hash: used when you do not need to decrypt, but only encrypt.It is a common approach when it comes to storing user passwords.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Differences Between Symmetric and Asymmetric Encryption&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symmetric encryption uses a single key that needs to be shared among the people who need to receive the message while asymmetric encryption uses a pair of public keys and a private key to encrypt and decrypt messages when communicating.&lt;/li&gt;
&lt;li&gt;Symmetric encryption is an old technique while asymmetric encryption is relatively new.&lt;/li&gt;
&lt;li&gt;Asymmetric encryption was introduced to complement the inherent problem of the need to share the key in a symmetric encryption model, eliminating the need to share the key by using a pair of public-private keys.&lt;/li&gt;
&lt;li&gt;Asymmetric encryption takes relatively more time than symmetric encryption.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Symmetric Encryption:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Smaller cipher text than the original plain text file, &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;used to transmit big data, &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;symmetric key encryption works on low usage of resources, &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;128 or 256-bit key size, &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Symmetric Encryption uses a single key for encryption and decryption,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is an old technique,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A single key for encryption and decryption has chances of the key being compromised,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Symmetric encryption is a fast technique,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RC4, AES, DES, 3DES, and QUAD.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Asymmetric Encryption
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Larger cipher text than the original plain text file,&lt;/li&gt;
&lt;li&gt;Used to transmit small data,&lt;/li&gt;
&lt;li&gt;Asymmetric encryption requires high consumption of resources,&lt;/li&gt;
&lt;li&gt;RSA 2048-bit or higher key size,&lt;/li&gt;
&lt;li&gt;Much safer as two different keys are involved in encryption and decryption,&lt;/li&gt;
&lt;li&gt;Asymmetric Encryption uses two different keys for encryption and decryption,&lt;/li&gt;
&lt;li&gt;It is a modern technique,&lt;/li&gt;
&lt;li&gt;Two keys are separately made for encryption and decryption which removes the need to share a key,&lt;/li&gt;
&lt;li&gt;Asymmetric encryption is slower in terms of speed,&lt;/li&gt;
&lt;li&gt;RSA, Diffie-Hellman, ECC algorithms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source: &lt;a href="https://www.ssl2buy.com/wiki/symmetric-vs-asymmetric-encryption-what-are-differences" rel="noopener noreferrer"&gt;https://www.ssl2buy.com/wiki/symmetric-vs-asymmetric-encryption-what-are-differences&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Using the %SYSTEM.Encryption class to do Encrypt, Decrypt and Hash
&lt;/h2&gt;

&lt;p&gt;To exercise IRIS support to Encrypt, Decrypt and Hash operations, go to &lt;a href="https://github.com/yurimarx/cryptography-samples" rel="noopener noreferrer"&gt;https://github.com/yurimarx/cryptography-samples&lt;/a&gt; and follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Clone/git pull the repo into any local directory
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/yurimarx/cryptography-samples.git

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Open a Docker terminal in this directory and run:
&lt;/li&gt;
&lt;/ul&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;ul&gt;
&lt;li&gt;Run the IRIS container:
&lt;/li&gt;
&lt;/ul&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;ul&gt;
&lt;li&gt;Open IRIS Terminal:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker-compose exec iris iris session iris -U IRISAPP

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

&lt;/div&gt;



&lt;p&gt;IRISAPP&amp;gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To do RSA Encrypt for asymmetric encryption execute this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IRISAPP&amp;gt;Set ciphertext = ##class(dc.cryptosamples.Samples).DoRSAEncrypt("InterSystems")
IRISAPP&amp;gt;Write ciphertext
Ms/eR7pPmE39KBJu75EOYIxpFEd7qqoji61EfahJE1r9mGZX1NYuw5i2cPS5YwE3Aw6vPAeiEKXF
rYW++WtzMeRIRdCMbLG9PrCHD3iQHfZobBnuzx/JMXVc6a4TssbY9gk7qJ5BmlqRTU8zNJiiVmd8
pCFpJgwKzKkNrIgaQn48EgnwblmVkxSFnF2jwXpBt/naNudBguFUBthef2wfULl4uY00aZzHHNxA
bi15mzTdlSJu1vRtCQaEahng9ug7BZ6dyWCHOv74O/L5NEHI+jU+kHQeF2DJneE2yWNESzqhSECa
ZbRjjxNxiRn/HVAKyZdAjkGQVKUkyG8vjnc3Jw==

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To do RSA Decrypt for asymmetric decryption run this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IRISAPP&amp;gt;Set plaintext = ##class(dc.cryptosamples.Samples).DoRSADecrypt(ciphertext)
IRISAPP&amp;gt;Write plaintext
InterSystems

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To do AES CBC Encrypt for symmetric encryption perform this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IRISAPP&amp;gt;Do ##class(dc.cryptosamples.Samples).DoAESCBCEncrypt("InterSystems")
8sGVUikDZaJF+Z9UljFVAA==

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To do AES CBC Decrypt for symmetric encryption complete this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IRISAPP&amp;gt;Do ##class(dc.cryptosamples.Samples).DoAESCBCDecrypt("8sGVUikDZaJF+Z9UljFVAA==")
InterSystems

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To do MD5 hash for an old hash approach conduct this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IRISAPP&amp;gt;Do ##class(dc.cryptosamples.Samples).DoHash("InterSystems")
rOs6HXfrnbEY5+JBdUJ8hw==

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To do SHA hash for recommended hash approach follow this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IRISAPP&amp;gt;Do ##class(dc.cryptosamples.Samples).DoSHAHash("InterSystems")
+X0hDlyoViPlWOm/825KvN3rRKB5cTU5EQTDLvPWM+E=


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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To exit the terminal, do any of the following:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enter HALT or H (not case-sensitive)&lt;/p&gt;

&lt;h2&gt;
  
  
  About the source code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;About the Symmetric key
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# to use with symmetric encrypt/decrypt
ENV SECRETKEY=InterSystemsIRIS

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

&lt;/div&gt;



&lt;p&gt;In the Dockerfile, there was created an Environment key to be used as secret key on symmetric operations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;About the Asymmetric key
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# to use with asymmetric encrypt/decrypt
RUN openssl req  -new -x509 -sha256 -config example-com.conf -newkey rsa:2048 -nodes -keyout 
example-com.key.pem  -days 365 -out example-com.cert.pem

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

&lt;/div&gt;



&lt;p&gt;In the Dockerfile were generated a private key and a public key to be used with asymmetric operations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symmetric Encrypt
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Symmetric Keys sample to encrypt
ClassMethod DoAESCBCEncrypt(plaintext As %String) As %Status
{
    // convert to utf-8
    Set text=$ZCONVERT(plaintext,"O","UTF8")

    // set a secret key
    Set secretkey = $system.Util.GetEnviron("SECRETKEY")
    Set IV = $system.Util.GetEnviron("SECRETKEY")

    // encrypt a text
    Set text = $SYSTEM.Encryption.AESCBCEncrypt(text, secretkey, IV)
    Set ciphertext = $SYSTEM.Encryption.Base64Encode(text)

    Write ciphertext
}

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

&lt;/div&gt;



&lt;p&gt;The operation AES CBC Encrypt was used to encrypt texts.&lt;br&gt;
Base64 Encode returns the results as a pretty/readable text to the user.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symmetric Decrypt
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Symmetric Keys sample to decrypt
ClassMethod DoAESCBCDecrypt(ciphertext As %String) As %Status
{
    // set a secret key
    Set secretkey = $system.Util.GetEnviron("SECRETKEY")
    Set IV = $system.Util.GetEnviron("SECRETKEY")

    // decrypt a text
    Set text=$SYSTEM.Encryption.Base64Decode(ciphertext)
    Set text=$SYSTEM.Encryption.AESCBCDecrypt(text,secretkey,IV)

    Set plaintext=$ZCONVERT(text,"I","UTF8")
    Write plaintext
}

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

&lt;/div&gt;


&lt;p&gt;The operation AES CBC Decrypt was used to decrypt texts.&lt;br&gt;
Base64 Decode returns the encrypted text to a binary one, so it can be used to decrypt.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asymmetric Encrypt
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Asymmetric Keys sample to encrypt
ClassMethod DoRSAEncrypt(plaintext As %String) As %Status
{
    // get public certificate
    Set pubKeyFileName = "/opt/irisbuild/example-com.cert.pem"
    Set objCharFile = ##class(%Stream.FileCharacter).%New()
    Set objCharFile.Filename = pubKeyFileName
    Set pubKey = objCharFile.Read()

    // encrypt using RSA
    Set binarytext = $System.Encryption.RSAEncrypt(plaintext, pubKey)
    Set ciphertext = $SYSTEM.Encryption.Base64Encode(binarytext)

    Return ciphertext
}

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

&lt;/div&gt;


&lt;p&gt;It is necessary to get the public key file content to encrypt with RSA.&lt;br&gt;
The operation RSA Encrypt was used to encrypt texts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asymmetric Decrypt
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Asymmetric Keys sample to decrypt
ClassMethod DoRSADecrypt(ciphertext As %String) As %Status
{
    // get private key
    Set privKeyFileName = "/opt/irisbuild/example-com.key.pem"
    Set privobjCharFile = ##class(%Stream.FileCharacter).%New()
    Set privobjCharFile.Filename = privKeyFileName
    Set privKey = privobjCharFile.Read()

    // get ciphertext in binary format
    Set text=$SYSTEM.Encryption.Base64Decode(ciphertext)

    // decrypt text using RSA
    Set plaintext = $System.Encryption.RSADecrypt(text, privKey)

    Return plaintext
}

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

&lt;/div&gt;


&lt;p&gt;It is necessary to get the private key file content to decrypt with RSA.&lt;br&gt;
The operation RSA Decrypt was used to decrypt texts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hash text using MD5 (old approach)
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Hash sample 
ClassMethod DoHash(plaintext As %String) As %Status
{
    // convert to utf-8
    Set text=$ZCONVERT(plaintext,"O","UTF8")

    // hash a text
    Set hashtext = $SYSTEM.Encryption.MD5Hash(text)

    Set base64text = $SYSTEM.Encryption.Base64Encode(hashtext)

    // convert to hex text to following best practices
    Set hextext = ..GetHexText(base64text)

    // return using lowercase
    Write $ZCONVERT(hextext,"L")
}

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

&lt;/div&gt;


&lt;p&gt;The operation MD5 Hash will encrypt the text, and it will not be possible to decrypt it.&lt;br&gt;
Hash using MD5 is not recommended for new projects because it is considered insecure. That is why it was replaced by SHA. The InterSystems IRIS supports SHA (our next example will demonstrate it).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hash text using SHA (recommend approach)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will use the SHA-3 Hash method for this sample. According to InterSystems documentation, this method generates a hash using one of the U.S. Secure Hash Algorithms - 3. (See Federal Information Processing Standards Publication 202 for more information.).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
// Hash using SHA 
ClassMethod DoSHAHash(plaintext As %String) As %Status
{
    // convert to utf-8
    Set text=$ZCONVERT(plaintext,"O","UTF8")

    // hash a text
    Set hashtext = $SYSTEM.Encryption.SHA3Hash(256, text)

    Set base64text = $SYSTEM.Encryption.Base64Encode(hashtext)

    // convert to hex text to following best practices
    Set hextext = ..GetHexText(base64text)

    // return using lowercase
    Write $ZCONVERT(hextext,"L")
}

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

&lt;/div&gt;



&lt;p&gt;For the SHA method, it is possible to set the bit length used on a hash operation. The greater the number of bits, the more difficult it is to crack the hash. However, the hashing process slows down too. In this sample we used 256 bits. You can choose these options for bit length:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;224 (SHA-224)&lt;/li&gt;
&lt;li&gt;256 (SHA-256)&lt;/li&gt;
&lt;li&gt;384 (SHA-384)&lt;/li&gt;
&lt;li&gt;512 (SHA-512)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>intersystems</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Using Tesseract OCR and Java Gateway</title>
      <dc:creator>Yuri Marx P. Gomes</dc:creator>
      <pubDate>Sun, 19 Jun 2022 11:58:39 +0000</pubDate>
      <link>https://dev.to/intersystems/using-tesseract-ocr-and-java-gateway-57bg</link>
      <guid>https://dev.to/intersystems/using-tesseract-ocr-and-java-gateway-57bg</guid>
      <description>&lt;p&gt;The InterSystems IRIS can be extended using Java or .NET components and its frameworks inside Object Script source code.&lt;/p&gt;

&lt;p&gt;I created an application called OCR Service. It built with Docker and installs Google Tesseract inside docker instance configured with english and portuguese dialects, but is possible install more than other 100 dialects. Google Tesseract can receive images and return text extracted from it, using OCR. The results are very good with the trained dialects. But you can train Tesseract to read car plates and any other textual patterns and load it to extract text. Java has a framework called Tess4J to enable Java call Tesseract instances and functions.  See running:&lt;/p&gt;

&lt;p&gt;OCR in Action&lt;/p&gt;

&lt;p&gt;See the Java code to the OCR service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private String extractTextFromImage(File tempFile) throws TesseractException {

  ITesseract tesseract = new Tesseract();
  tesseract.setDatapath("/usr/share/tessdata/"); //directory to trained models
  tesseract.setLanguage("eng+por"); // choose your language/trained model

  return tesseract.doOCR(tempFile); //call tesseract function doOCR() //passing the file to be processed with OCR technique

}


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

&lt;/div&gt;



&lt;p&gt;Tess4J take care all low level communication with Tesseract with ITesseract interface class and we need only set the OCR model to be used and call doOCR() passing the file. Easy!&lt;/p&gt;

&lt;p&gt;For our luck, we don't have to create a Tess4ObjectScript framework to interact with Tesseract, it is possible, using C callin/callout, but you need to understand how to talk at low level with Tesseract, I prefer use Java Gateway to save many work days!&lt;/p&gt;

&lt;p&gt;To use Java Gateway, you have to install Java into your IRIS OS or docker instance, set JAVA_HOME (variable to know where Java is installed), set the CLASSPATH (variable to point to your Java class, Tess4J java archive and other dependencies) and execute a Java Gateway instance, a proxy to enable ObjectScript and Java to talk. See my dockerfile instructions to install Java and Tesseract to IRIS instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ARG IMAGE=store/intersystems/iris-community:2020.1.0.204.0
ARG IMAGE=intersystemsdc/iris-community:2020.1.0.209.0-zpm
ARG IMAGE=intersystemsdc/iris-community:2020.2.0.204.0-zpm
ARG IMAGE=intersystemsdc/irishealth-community:2020.3.0.200.0-zpm
ARG IMAGE=intersystemsdc/iris-community:2020.3.0.200.0-zpm
ARG IMAGE=intersystemsdc/iris-community:2020.3.0.221.0-zpm
ARG IMAGE=intersystemsdc/iris-community:2020.4.0.521.0-zpm
FROM $IMAGE

USER root   

WORKDIR /opt/irisapp
RUN chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/irisapp
USER ${ISC_PACKAGE_MGRUSER}

COPY  Installer.cls .
COPY  src src

COPY iris.script /tmp/iris.script

RUN iris start IRIS \
    &amp;amp;&amp;amp; iris session IRIS &amp;lt; /tmp/iris.script \
    &amp;amp;&amp;amp; iris stop IRIS quietly

USER root   

# Install Java 8 using apt-get from ubuntu repository
RUN apt-get update &amp;amp;&amp;amp; \
    apt-get install -y openjdk-8-jdk &amp;amp;&amp;amp; \
    apt-get install -y ant &amp;amp;&amp;amp; \
    apt-get clean &amp;amp;&amp;amp; \
    rm -rf /var/lib/apt/lists/* &amp;amp;&amp;amp; \
    rm -rf /var/cache/oracle-jdk8-installer;

# Fix certificate issues, found as of 
# https://bugs.launchpad.net/ubuntu/+source/ca-certificates-java/+bug/983302
RUN apt-get install -y ca-certificates-java &amp;amp;&amp;amp; \
    apt-get clean &amp;amp;&amp;amp; \
    update-ca-certificates -f &amp;amp;&amp;amp; \
    rm -rf /var/lib/apt/lists/* &amp;amp;&amp;amp; \
    rm -rf /var/cache/oracle-jdk8-installer;

# Setup JAVA_HOME, to enable apps to know where the Java was installed
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/
RUN export JAVA_HOME
ENV JRE_HOME /usr/lib/jvm/java-8-openjdk-amd64/
RUN export JRE_HOME

# Setup classpath, to enable apps to know where java classes and java jar libraries was installed
ENV classpath .:/usr/irissys/dev/java/lib/JDK18/*:/opt/irisapp/*:/usr/irissys/dev/java/lib/gson/*
:/usr/irissys/dev/java/lib/jackson/*:/jgw/*
RUN export classpath
ENV CLASSPATH .:/usr/irissys/dev/java/lib/JDK18/*:/opt/irisapp/*:/usr/irissys/dev/java/lib/gson/*
:/usr/irissys/dev/java/lib/jackson/*:/jgw/*
RUN export CLASSPATH

USER root

ARG APP_HOME=/tmp/app

COPY src $APP_HOME/src

# Tess4J and another java libraries used, are into jgw folder and jgw folder is in the classpath
COPY jgw /jgw

# Copy our Java OCR program, packaged into a jar, to the jgw
COPY target/ocr-pex-1.0.0.jar /jgw/ocr-pex-1.0.0.jar  

COPY jgw/* /usr/irissys/dev/java/lib/JDK18/

# Install tesseract using ubuntu apt-get
RUN apt-get update &amp;amp;&amp;amp; apt-get install tesseract-ocr -y

USER root

# Copy trained models eng and por to the models folder
COPY tessdata /usr/share/tessdata

# Install and config default OS locale - it is required to tesseract works fine
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y locales &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/* \
 &amp;amp;&amp;amp; locale-gen "en_US.UTF-8"
ENV LANG=en_US.UTF-8 \
    LANGUAGE=en_US:en \
    LC_ALL=en_US.UTF-8

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

&lt;/div&gt;



&lt;p&gt;When your ObjectScript class is an interoperability business class or operation, set a Java Gateway Business Service (JavaGateway item into my production).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Class dc.ocr.OcrProduction Extends Ens.Production
{

XData ProductionDefinition
{

&amp;lt;Production Name="dc.ocr.OcrProduction" LogGeneralTraceEvents="false"&amp;gt;
  &amp;lt;Description&amp;gt;&amp;lt;/Description&amp;gt;
  &amp;lt;ActorPoolSize&amp;gt;2&amp;lt;/ActorPoolSize&amp;gt;
  &amp;lt;Item Name="OcrService" Category="" ClassName="dc.ocr.OcrService" PoolSize="1" Enabled="true" 
Foreground="false" Comment="" LogTraceEvents="false" Schedule=""&amp;gt;
  &amp;lt;/Item&amp;gt;

  &amp;lt;Item Name="JavaGateway" Category="" ClassName="EnsLib.JavaGateway.Service" PoolSize="1" 
Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule=""&amp;gt;
    &amp;lt;Setting Target="Host" Name="ClassPath"&amp;gt;.:/usr/irissys/dev/java/lib/JDK18/*:/opt/irisapp/*
:/usr/irissys/dev/java/lib/gson/*
:/usr/irissys/dev/java/lib/jackson/*:/jgw/ocr-pex-1.0.0.jar
&amp;lt;/Setting&amp;gt;
    &amp;lt;Setting Target="Host" Name="JavaHome"&amp;gt;/usr/lib/jvm/java-8-openjdk-amd64/&amp;lt;/Setting&amp;gt;
  &amp;lt;/Item&amp;gt;

&amp;lt;/Production&amp;gt;

}

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

&lt;/div&gt;



&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;Into the production we have our ObjectScript OCRService too. This ObjectScript class receive the file uploaded from a HTTP multipart request and uses JavaGateway to load the Java class, pass the file and get the text from OCR process, so returns the response. See:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Class dc.ocr.OcrService Extends Ens.BusinessService
{

// extends Ens.BusinessService to create a custom Business service using Object Script

// This class receive a file from a multipart http request and save 
// to the folder configured into folder parameter

// choose an adapter to get data from a source of data

// HTTP.InboundAdapter allows you get data from an http request

Parameter ADAPTER = "EnsLib.HTTP.InboundAdapter";

// custom parameter to allows production user set destination folder to multipart file uploaded 

Property Folder As %String(MAXLEN = 100);

// when you set parameter Folder to SETTINGS parameter, the production IRIS interface 
// create a field to the user fills
// so the user will inform host path for the uploaded file 

Parameter SETTINGS = "Folder,Basic";

// This method is mandatory to have a business service. It receives the multipart file into pInput 

// and returns a result to the caller using pOutput

Method OnProcessInput(pInput As %GlobalBinaryStream, pOutput As %RegisteredObject) As %Status
{
    //try to do the actions
    try {
        Set reader = ##class(%Net.MIMEReader).%New() //creates a MIMEReader to extract files 
//from multipart requests 
        Do reader.OpenStream(pInput) //reader open the file

        Set tSC = reader.ReadMIMEMessage(.message) //the reader put the file uploaded into a MIME Message
        //Get Header obtains headers from the request and the multipart file, like content-type or content 
//disposition the content disposition have 3 headers: Content-Disposition: form-data; name="file"; 
//filename="filename.ext". This split content-disposition header into 3 parts
        Set filenameHeader = $PIECE(message.GetHeader("CONTENT-DISPOSITION", .header),";",3) 
        //get filename header value
        Set filename = $EXTRACT(filenameHeader, 12, $LENGTH(filenameHeader)-1)
        //Headers are not more needed. It clean the header to remains only the file content to be saved
        Do message.ClearHeaders()

        //create a file object to save the multipart file
        Set file=##class(%Stream.FileBinary).%New()
        //points the file to folder informed into folder parameter, plus upload filename from header
        Set file.Filename=..Folder_filename 
        //save body message (the file content) to file object
        Do file.CopyFromAndSave(message.Body)

        // Connect a Gateway instance to server JavaGate on the host machine
        set GW = ##class(%Net.Remote.Gateway).%New()
        set st = GW.%Connect("127.0.0.1", "55555", "IRISAPP",,)
        //instantiate java ocr class
        set proxyOcr = ##class(%Net.Remote.Object).%New(GW,"community.intersystems.pex.ocr.OcrOperation")
        //call ocr method to get text from image
        set pResponse = proxyOcr.doOcr(file.Filename)
        //returns to the service
        Set pOutput = pResponse
        Set tSC=$$$OK

    //returns error message to the user
    } catch e {
        Set tSC=e.AsStatus()
        Set pOutput = tSC
    }

    Quit tSC
}

}


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

&lt;/div&gt;



&lt;p&gt;Now, IRIS can do OCR to images and PDF, but with JavaGateway function can do many amazing things. See all details into my app code: &lt;a href="https://openexchange.intersystems.com/package/OCR-Service"&gt;https://openexchange.intersystems.com/package/OCR-Service&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ocr</category>
      <category>java</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>OCR and NLP together into InterSystems IRIS</title>
      <dc:creator>Yuri Marx P. Gomes</dc:creator>
      <pubDate>Sun, 19 Jun 2022 11:51:58 +0000</pubDate>
      <link>https://dev.to/intersystems/ocr-and-nlp-together-into-intersystems-iris-2gcg</link>
      <guid>https://dev.to/intersystems/ocr-and-nlp-together-into-intersystems-iris-2gcg</guid>
      <description>&lt;p&gt;According to IDC, more than 80% of information it is NoSQL, especially text into documents. When the digital services or applications not process all this information, the business lose. To face this challenge, it is possible use OCR technology. OCR uses machine learning and/or trained image patterns to transform image pixels into text. This is important, because many documents are scanned into images inside PDF, or many documents contains images with text inside. So OCR are an important step to get all possible data from a document.&lt;/p&gt;

&lt;p&gt;To do OCR, the main open source solution used is Google Tesseract, the most popular solution into the Python and Java community. Tesseract has support to more than 100 idioms and can be trained with new models to recognize car plates, captchas and so on. Tesseract was created in C++, so Java uses it consuming an intermediate, called Tess4J. My following code shows it to you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private String extractTextFromImage(File tempFile) throws TesseractException {

  ITesseract tesseract = new Tesseract();
  tesseract.setDatapath("/usr/share/tessdata/"); //directory to trained models
  tesseract.setLanguage("eng+por"); // choose your language/trained model

  return tesseract.doOCR(tempFile); //call tesseract function doOCR() passing the file to be processed with OCR technique

}

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

&lt;/div&gt;



&lt;p&gt;To allows IRIS to use this Java Class and get the results from Java, we need to use PEX and Java Gateway solutions.&lt;/p&gt;

&lt;p&gt;First it is necessary config Java Proxy into the production and second, config a PEX business operation or service to communicate IRIS and Java into a production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Class dc.ocr.OcrProduction Extends Ens.Production
{

XData ProductionDefinition
{
&amp;lt;Production Name="dc.ocr.OcrProduction" LogGeneralTraceEvents="false"&amp;gt;

  &amp;lt;Description&amp;gt;&amp;lt;/Description&amp;gt;
  &amp;lt;ActorPoolSize&amp;gt;2&amp;lt;/ActorPoolSize&amp;gt;

&amp;lt;Item Name="OcrService" Category="" ClassName="dc.ocr.OcrService" PoolSize="1" Enabled="true" 
Foreground="false" Comment="" LogTraceEvents="false" Schedule=""&amp;gt; &amp;lt;/Item&amp;gt;

&amp;lt;Item Name="JavaGateway" Category="" ClassName="EnsLib.JavaGateway.Service" PoolSize="1" 
Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule=""&amp;gt;
  &amp;lt;Setting Target="Host" Name="ClassPath"&amp;gt;.:/usr/irissys/dev/java/lib/JDK18/*:/opt/irisapp/*
:/usr/irissys/dev/java/lib/gson/*
:/usr/irissys/dev/java/lib/jackson/*:/jgw/ocr-pex-1.0.0.jar&amp;lt;/Setting&amp;gt; 

&amp;lt;Setting Target="Host" Name="JavaHome"&amp;gt;/usr/lib/jvm/java-8-openjdk-amd64/&amp;lt;/Setting&amp;gt; 
&amp;lt;/Item&amp;gt; 

&amp;lt;Item Name="OcrOperation" Category="" ClassName="EnsLib.PEX.BusinessOperation" PoolSize="1" 
Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule=""&amp;gt; 
    &amp;lt;Setting Target="Host" Name="%gatewayPort"&amp;gt;55555&amp;lt;/Setting&amp;gt; 
    &amp;lt;Setting Target="Host" Name="%remoteClassname"&amp;gt;community.intersystems.pex.ocr.OcrOperation&amp;lt;/Setting&amp;gt; 
    &amp;lt;Setting Target="Host" Name="%gatewayExtraClasspaths"&amp;gt;.:/usr/irissys/dev/java/lib/JDK18/*
:/opt/irisapp/*:/usr/irissys/dev/java/lib/gson/*
:/usr/irissys/dev/java/lib/jackson/*
:/jgw/ocr-pex-1.0.0.jar
&amp;lt;/Setting&amp;gt; 
&amp;lt;/Item&amp;gt; 

&amp;lt;/Production&amp;gt;
}

}

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

&lt;/div&gt;



&lt;p&gt;Now any IRIS production can communicate with Java and Tesseract! See:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  //call ocr method to get text from image, if you want to use pex
  Set pRequest = ##class(dc.ocr.OcrRequest).%New()
  Set pRequest.FileName = file.Filename

  // call java pex operation to do ocr, passing file into pRequest and receive ocr text with pResponse
  Set tSC = ..SendRequestSync("OcrOperation", pRequest, .pResponse, 1200)

  //save the results into database to use text analytics - nlp
  Set ocrTable = ##class(dc.ocr.OcrTable).%New()
  Set ocrTable.FileName = file.Filename
  Set ocrTable.OcrText = pResponse.StringValue

  Set tSC = ocrTable.%Save()

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

&lt;/div&gt;



&lt;p&gt;All code details, with comments can be found into my OCR Service repository (&lt;a href="https://openexchange.intersystems.com/package/OCR-Service"&gt;https://openexchange.intersystems.com/package/OCR-Service&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Now, with the text extracted, we need to use IRIS NLP engine to analyze textual data and get insights to support decisions. For this, when a text is extracted, it is saved into a table, and this table is used by NLP engine as text source. See the table %Save() above and see the following code with NLP referencing OCRTable (place with texts extracted). See:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Class dc.ocr.OcrNLP Extends %iKnow.DomainDefinition [ ProcedureBlock ]
{

XData Domain [ XMLNamespace = "http://www.intersystems.com/iknow" ]
{
&amp;lt;domain name="OcrNLP" disabled="false" allowCustomUpdates="true"&amp;gt;
&amp;lt;parameter name="DefaultConfig" value="OcrNLP.Configuration" isList="false" /&amp;gt;

&amp;lt;data dropBeforeBuild="true"&amp;gt;
&amp;lt;table listname="OcrNLPTable" batchMode="true" disabled="false" 
listerClass="%iKnow.Source.SQL.Lister" tableName="dc_ocr.OcrTable" idField="ID" 
groupField="ID" dataFields="OcrText" metadataColumns="FileName" metadataFields="filename" /&amp;gt;
&amp;lt;/data&amp;gt;

&amp;lt;matching disabled="false" dropBeforeBuild="true" autoExecute="true" ignoreDictionaryErrors="true" /&amp;gt;

&amp;lt;metadata&amp;gt;
&amp;lt;field name="filename" operators="=" dataType="STRING" storage="0" caseSensitive="false" disabled="false" /&amp;gt;
&amp;lt;/metadata&amp;gt;

&amp;lt;configuration name="OcrNLP.Configuration" detectLanguage="true" languages="en,pt" 
userDictionary="OcrNLP.Dictionary#1" summarize="true" maxConceptLength="0" /&amp;gt;

&amp;lt;userDictionary name="OcrNLP.Dictionary#1" /&amp;gt;

&amp;lt;/domain&amp;gt;

}

}

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

&lt;/div&gt;



&lt;p&gt;See full details and configuration into my OCR Service github repository.&lt;/p&gt;

&lt;p&gt;Now we can upload some files and go to the Explorer to see concepts and CRC generated.&lt;/p&gt;

&lt;p&gt;See my animation with all steps discussed here:&lt;/p&gt;

&lt;p&gt;Happy OCR/NLP hacking!&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>nlp</category>
      <category>ocr</category>
      <category>api</category>
    </item>
    <item>
      <title>InterSystems IRIS REST Application Patterns</title>
      <dc:creator>Yuri Marx P. Gomes</dc:creator>
      <pubDate>Wed, 23 Feb 2022 14:54:35 +0000</pubDate>
      <link>https://dev.to/intersystems/intersystems-iris-rest-application-patterns-4a27</link>
      <guid>https://dev.to/intersystems/intersystems-iris-rest-application-patterns-4a27</guid>
      <description>&lt;p&gt;This article suggests to you some patterns to create REST API applications using IRIS.&lt;/p&gt;

&lt;p&gt;Note: source code in &lt;a href="https://github.com/yurimarx/movie" rel="noopener noreferrer"&gt;https://github.com/yurimarx/movie&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Class Pattern to the REST Application
&lt;/h2&gt;

&lt;p&gt;To begin, see my suggestion for classes needed to create IRIS API applications:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdplqjtvyaaio8bchnzq.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdplqjtvyaaio8bchnzq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IRISRESTApplication: CSP.REST class that will be the central controller for all REST requests and responses processed by the business services.&lt;/li&gt;
&lt;li&gt;BusinessService: class with a business topic implementation. It can use one or more Persistent Domain Classes to persist and query data required by the business topic requirements.&lt;/li&gt;
&lt;li&gt;Persistent Domain: persistent class to manage a SQL table. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prereqs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;VSCode;&lt;/li&gt;
&lt;li&gt;Docker Desktop;&lt;/li&gt;
&lt;li&gt;InterSystems ObjectScript Extension Pack.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Class Diagram to the Sample Application
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I will create a Movie Catalog application to demonstrate the patterns suggested in the article:
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqq7qouy3bt5vnjjaosax.png" alt="Image description"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: thanks to the &lt;a href="https://openexchange.intersystems.com/package/iris-rest-api-template" rel="noopener noreferrer"&gt;https://openexchange.intersystems.com/package/iris-rest-api-template&lt;/a&gt; application. It was the base to this tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup the Sample Application
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a folder movie in your file system. Open this folder in a new VSCode window&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdi70drh4bpbekw1ezq1.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdi70drh4bpbekw1ezq1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the Dockerfile file inside movie folder to run IRIS Community edition into a Docker container instance. Content:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ARG IMAGE=intersystemsdc/iris-community:2020.3.0.221.0-zpm
ARG IMAGE=intersystemsdc/iris-community:2020.4.0.524.0-zpm
ARG IMAGE=intersystemsdc/iris-community

FROM $IMAGE

USER root   

WORKDIR /opt/irisapp

RUN chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/irisapp

USER ${ISC_PACKAGE_MGRUSER}

COPY  src src

COPY module.xml module.xml

COPY iris.script /tmp/iris.script

RUN iris start IRIS \
    &amp;amp;&amp;amp; iris session IRIS &amp;lt; /tmp/iris.script \
    &amp;amp;&amp;amp; iris stop IRIS quietly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create the docker-compose.yml file inside movie folder to allows you run your docker instance and other instances together (not in this sample, but it is a good practice run from docker-compose instead dockerfile. Content:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.6'
services:
  iris:
    build: 
      context: .
      dockerfile: Dockerfile
    restart: always
    ports: 
      - 51773
      - 1972:1972
      - 52773:52773
      - 53773
    volumes:
      - ./:/irisdev/app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create the iris.script file inside movie folder to do some actions before run IRIS. This file is important to do custom terminal actions necessary for the application, like disable password expiration. Content:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;do $System.OBJ.LoadDir("/opt/irisapp/src","ck",,1)

zn "%SYS"

Do ##class(Security.Users).UnExpireUserPasswords("*")

zn "USER"

zpm "load /opt/irisapp/ -v":1:1

halt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create the module.xml file inside movie folder to install and run your application using ZPM. This file is important to do the application endpoint configuration and install swagger-ui (web app used to run and test your API using swagger file). Content:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;Export generator="Cache" version="25"&amp;gt;
  &amp;lt;Document name="movie.ZPM"&amp;gt;
    &amp;lt;Module&amp;gt;
      &amp;lt;Name&amp;gt;movie&amp;lt;/Name&amp;gt;
      &amp;lt;Version&amp;gt;1.0.0&amp;lt;/Version&amp;gt;
      &amp;lt;Packaging&amp;gt;module&amp;lt;/Packaging&amp;gt;
      &amp;lt;SourcesRoot&amp;gt;src&amp;lt;/SourcesRoot&amp;gt;
      &amp;lt;Resource Name="dc.movie.PKG"/&amp;gt;
      &amp;lt;Dependencies&amp;gt;
        &amp;lt;ModuleReference&amp;gt;
          &amp;lt;Name&amp;gt;swagger-ui&amp;lt;/Name&amp;gt;
          &amp;lt;Version&amp;gt;1.*.*&amp;lt;/Version&amp;gt;
        &amp;lt;/ModuleReference&amp;gt;
      &amp;lt;/Dependencies&amp;gt;
       &amp;lt;CSPApplication 
        Url="/movie-api"
        DispatchClass="dc.movie.MovieRESTApp"
        MatchRoles=":{$dbrole}"
        PasswordAuthEnabled="1"
        UnauthenticatedEnabled="0"
        Recurse="1"
        UseCookies="2"
        CookiePath="/movie-api"
       /&amp;gt;
    &amp;lt;/Module&amp;gt;
  &amp;lt;/Document&amp;gt;
&amp;lt;/Export&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see CSPApplication tag, used to run the application API in the /movie-api URI and enable or disable password to consume the API.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the LICENSE file inside movie folder to setting the license of your application. Content:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MIT License
Copyright (c) 2019 InterSystems Developer Community Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create the README.md file inside movie folder to document your application to the users using markdown language. Content:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## movie-rest-application
This is a sample of a REST API application built with ObjectScript in InterSystems IRIS.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create .vscode folder inside movie folder. Create settings.json file inside .vscode folder to configure server connection between VSCode and your IRIS instance. Content:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "files.associations": {
        "Dockerfile*": "dockerfile",
        "iris.script": "objectscript"
      },

    "objectscript.conn" :{
      "ns": "USER",
      "username": "_SYSTEM",
      "password": "SYS",
      "docker-compose": {
        "service": "iris",
        "internalPort": 52773
      },

      "active": true
    },

    "sqltools.connections": [
      {
        "namespace": "USER",
        "connectionMethod": "Server and Port",
        "showSystem": false,
        "previewLimit": 50,
        "server": "localhost",
        "port": 52773,
        "askForPassword": false,
        "driver": "InterSystems IRIS",
        "name": "objectscript-docker",
        "username": "_SYSTEM",
        "password": "SYS"
      }
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create the folder src inside movie folder to put your source code folders and files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create dc folder inside src folder. This is a convention when your build projects to the InterSystems Developer Community, otherwise is not necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create movie folder inside dc folder. This folder will be the folder to your objectscript classes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create our first class, MovieRESTApp.cls file, inside src\dc\movie folder. This file will be the IRISRESTApplication class. Content:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Class dc.movie.MovieRESTApp Extends %CSP.REST
{

Parameter CHARSET = "utf-8";
Parameter CONVERTINPUTSTREAM = 1;
Parameter CONTENTTYPE = "application/json";
Parameter Version = "1.0.0";
Parameter HandleCorsRequest = 1;

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap"]
{
&amp;lt;Routes&amp;gt;

&amp;lt;!-- Server Info --&amp;gt;
&amp;lt;Route Url="/" Method="GET" Call="GetInfo" Cors="true"/&amp;gt;

&amp;lt;!-- Swagger specs --&amp;gt;
&amp;lt;Route Url="/_spec" Method="GET" Call="SwaggerSpec" /&amp;gt;

&amp;lt;/Routes&amp;gt;
}


ClassMethod %ProcessResult(pStatus As %Status = {$$$OK}, pResult As %DynamicObject = "") As %Status [ Internal ]
{

  #dim %response As %CSP.Response

  SET tSC = $$$OK

  IF $$$ISERR(pStatus) {

    SET %response.Status = 500

    SET tSC = ..StatusToJSON(pStatus, .tJSON)

    IF $isobject(tJSON) {

      SET pResult = tJSON

    } ELSE {

      SET pResult = { "errors": [ { "error": "Unknown error parsing status code" } ] }

    }

  } 

  ELSEIF pStatus=1 {

    IF '$isobject(pResult){

      SET pResult = {

      }

    }

  }

  ELSE {

    SET %response.Status = pStatus

    SET error = $PIECE(pStatus, " ", 2, *)

    SET pResult = {

      "error": (error)

    }

  }

  IF pResult.%Extends("%Library.DynamicAbstractObject") {

    WRITE pResult.%ToJSON()

  }

  ELSEIF pResult.%Extends("%JSON.Adaptor") {

    DO pResult.%JSONExport()

  }

  ELSEIF pResult.%Extends("%Stream.Object") {

    DO pResult.OutputToDevice()

  }

  QUIT tSC

}


ClassMethod SwaggerSpec() As %Status
{

  Set tSC = ##class(%REST.API).GetWebRESTApplication($NAMESPACE, %request.Application, .swagger)

  Do swagger.info.%Remove("x-ISC_Namespace")

  Set swagger.basePath = "/movie-api" 

  Set swagger.info.title = "Movie API"

  Set swagger.info.version = "1.0"

  Set swagger.host = "localhost:52773"

  Return ..%ProcessResult($$$OK, swagger)

}

}
```

`
Note 1: The class extends CSP.REST to be used as the REST Endpoint.

Note 2: the parameter chaset is used to encode requests and responses with UTF-8.

Note 3: the CONVERTINPUTSTREAM is used to force the request content in the UTF-8, without this you can have problems with special latin chars.

Note 4: CONTENTTYPE is used to declare the content using JSON, not XML.

Note 5: HandleCorsRequest = 1 is necessary to allows you consume the API from other servers different from the IRIS server.

Note 6: Routes are used to declare API URI to each class method.

Note 7: SwaggerSpec from CSP.REST class allows you generate the API swagger (API web documentation) content.

Now you have the following folders and files:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aur5um97ewhmsqvjd5d1.png)

13. Open VSCode Terminal (menu Terminal &amp;gt; New Terminal) and type:

```
docker-compose up -d --build
```
This will build the docker instance and run it.

14. Test your API with Swagger-UI. In the browser and type: http://localhost:52773/swagger-ui/index.html. Pay attention to the address bar (fix the url, if necessary to correct address)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0w0ti5aunovfpl5nuw02.png)

## Connection beetween VSCode and IRIS  
1. Click in the ObjectScript bar (in the VSCode footer)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3uabr9fvhjgimjlw6bzm.png)

2. Select Toogle Connection in the Top:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0rruhp6g423v8im0hoh7.png)

3. Check the connection status into ObjectScript Explorer (you will be able to see folders and classes created):
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stcugup3e5lnvi2yo4wx.png)

## Persistent Classes to the Movie Catalog Application  
In this section we will create the persistent domain classes to store and query the business data. See the DBeaver Diagram:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pb25ndbkqsta01p4963g.png)

1. Create the folder model inside src\dc\movie folder.

2. Create the Actor.cls file inside model folder. Write the content:  

`

```
Class dc.movie.model.Actor Extends (%Persistent, %JSON.Adaptor)
{
Parameter %JSONREFERENCE = "ID";

Property actorId As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ];
Property name As %VarString(MAXLEN = 120);  
Property dob As %Date;
Property genre As %Integer(VALUELIST = ",1,2");

}

```

`
3. Create the Movie.cls file inside model folder. Write the content:

`

```
Class dc.movie.model.Movie Extends (%Persistent, %JSON.Adaptor)
{

Parameter %JSONREFERENCE = "ID";

Property movieId As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ]; 
Property name As %VarString(MAXLEN = 120);
Property releaseDate As %Date;
Property duration As %Integer;
Property imdb As %String(MAXLEN = 300);
Property movieCategory As dc.movie.model.MovieCategory;
ForeignKey MovieCategoryFK(movieCategory) References dc.movie.model.MovieCategory();

}
```

`
4. Create the MovieCategory.cls file inside model folder. Write the content:

`

```
Class dc.movie.model.MovieCategory Extends (%Persistent, %JSON.Adaptor)
{

Parameter %JSONREFERENCE = "ID";

Property movieCategoryId As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ]; 
Property name As %VarString(MAXLEN = 120);

}
```

`
5. Create the Casting.cls file inside model folder. Write the content:

`

```
Class dc.movie.model.Casting Extends (%Persistent, %JSON.Adaptor)
{


Parameter %JSONREFERENCE = "ID";

Property castingId As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ];
Property movie As dc.movie.model.Movie;
ForeignKey MovieFK(movie) References dc.movie.model.Movie();
Property actor As dc.movie.model.Actor;
ForeignKey ActorFK(actor) References dc.movie.model.Actor();
Property characterName As %String(MAXLEN = 100);

Index CastingIndex On (movie, actor) [ Unique ];

}
```

`
See the created files:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i1n22lvk121fmwn6a5bx.png)

Note 1: Parameter %JSONREFERENCE = "ID" allows return ID value inside JSON response.

Note 2: Property actorId As %Integer [ Calculated, SqlComputeCode = { set {*}={%%ID}}, SqlComputed ] and the other similar properties are used to return class+id into JSON response.

Note 3: (VALUELIST = "1,2") set possible values to 1 or 2 only.

Note 4: ForeignKey MovieFK(movie) References dc.movie.model.Movie() and similar are used to create a SQL foreign key reference.

Note 5: Index CastingIndex On (movie, actor) [ Unique ] and similar are used to not allows duplicate values combining properties in the On (movie and actor).

Note 6: I'm using Camel Case to property names because a best practice for JSON attribute names.

## Business Service Classes to the Movie Catalog Application 
In this section we will create the classes with business logic (methods to do persistence, query and calculations).

1. Create the service folder inside src\dc\movie.

2. Create CrudUtilService.cls file inside service folder. Write the content:

`

```
Class dc.movie.service.CrudUtilService Extends %CSP.REST
{

Parameter CHARSET = "utf-8";
Parameter CONVERTINPUTSTREAM = 1;
Parameter CONTENTTYPE = "application/json";
Parameter Version = "1.0.0";
Parameter HandleCorsRequest = 1;

/// Return all the records
ClassMethod GetAll(DomainClass As %Persistent) As %Status
{

    #dim tSC As %Status = $$$OK
    Set rset = DomainClass.ExtentFunc()
    Set %response.ContentType = ..#CONTENTTYPEJSON
    Set %response.Headers("Access-Control-Allow-Origin")="*"

    Write "["

    if rset.%Next() {
        Set actor = DomainClass.%OpenId(rset.ID)    
        Do actor.%JSONExport()
    }

    While rset.%Next() {   
        Write "," 
        Set actor = DomainClass.%OpenId(rset.ID)    
        Do actor.%JSONExport()
    }

    Write "]"

    Quit tSC
}

/// Return one record
ClassMethod GetOne(DomainClass As %Persistent, id As %Integer) As %Status
{

    #dim tSC As %Status = $$$OK
    #dim e As %Exception.AbstractException

    #; Set the response header to plain text
    Set %response.ContentType = ..#CONTENTTYPEJSON
    Set %response.Headers("Access-Control-Allow-Origin")="*"

    Set domain = DomainClass.%OpenId(id)

    If '$IsObject(domain) Quit ..Http404()

    Do domain.%JSONExport()

    Quit tSC

}


/// Creates a new record
ClassMethod Create(DomainClass As %Persistent) As %Status
{

    #dim tSC As %Status = $$$OK
    #dim e As %Exception.AbstractException

    Set domain = DomainClass.%New()
    Set data = {}.%FromJSON(%request.Content)

    $$$TOE(tSC, domain.%JSONImport(data))
    $$$TOE(tSC, domain.%Save())

    Write domain.%JSONExport()

    Set %response.Status = 204
    Set %response.ContentType = ..#CONTENTTYPEJSON
    Set %response.Headers("Access-Control-Allow-Origin")="*"

    Quit tSC

}


/// Update a record with id
ClassMethod Update(DomainClass As %Persistent, id As %Integer) As %Status
{

    #dim tSC As %Status = $$$OK 
    #dim e As %Exception.AbstractException

    Set domain = DomainClass.%OpenId(id) 

    If '$IsObject(domain) Return ..Http404()

    Set data = {}.%FromJSON(%request.Content)

    $$$TOE(tSC, domain.%JSONImport(data))

    $$$TOE(tSC, domain.%Save())

    Write domain.%JSONExport()

    Set %response.Status = 200

    Set %response.ContentType = ..#CONTENTTYPEJSON

    Set %response.Headers("Access-Control-Allow-Origin")="*"

    Quit tSC

}


/// Delete a record with id
ClassMethod Delete(DomainClass As %Persistent, id As %Integer) As %Status
{

    #dim tSC As %Status = $$$OK
    #dim e As %Exception.AbstractException

    Set domain = DomainClass.%OpenId(id)

    If '$IsObject(domain) Return ..Http404()

    $$$TOE(tSC, domain.%DeleteId(id))

    Set %response.Status = 200

    Set %response.ContentType = ..#CONTENTTYPEJSON

    Set %response.Headers("Access-Control-Allow-Origin")="*"

    Quit tSC

}

}
```

`
3. Create MovieService.cls file inside service folder. Write the content:

`

```
Class dc.movie.service.MovieService Extends %CSP.REST
{

ClassMethod GetAll() As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).GetAll(##class(dc.movie.model.Movie).%New())

}


ClassMethod GetOne(id As %Integer) As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).GetOne(##class(dc.movie.model.Movie).%New(), id)

}


ClassMethod Create() As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).Create(##class(dc.movie.model.Movie).%New())

}


ClassMethod Update(id As %Integer) As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).Update(##class(dc.movie.model.Movie).%New(), id)

}

ClassMethod Delete(id As %Integer) As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).Delete(##class(dc.movie.model.Movie).%New(), id)

}

/// Return casting from the movie
ClassMethod GetMovieCasting(id As %Integer) As %Status
{

    #dim tSC As %Status = $$$OK

    Set qry = "SELECT actor-&amp;gt;name AS actorName, characterName, movie-&amp;gt;name AS movieName FROM dc_movie_model.Casting WHERE movie = ?"

    Set tStatement = ##class(%SQL.Statement).%New()  

    Set qStatus = tStatement.%Prepare(qry)

    If tSC'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}

    Set rset = tStatement.%Execute(id)
    Set %response.ContentType = ..#CONTENTTYPEJSON
    Set %response.Headers("Access-Control-Allow-Origin")="*"

    Set result = []

    While rset.%Next() {

        Set item = {}

        Set item.actorName = rset.actorName

        Set item.movieName = rset.movieName

        Set item.characterName = rset.characterName

        Do result.%Push(item)

    }

    Write result.%ToJSON()

    Quit tSC
}

}
```

`
4. Create MovieCategoryService.cls file inside service folder. Write the content:

`

```
Class dc.movie.service.MovieCategoryService
{

ClassMethod GetAll() As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).GetAll(##class(dc.movie.model.MovieCategory).%New())

}


ClassMethod GetOne(id As %Integer) As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).GetOne(##class(dc.movie.model.MovieCategory).%New(), id)

}

ClassMethod Create() As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).Create(##class(dc.movie.model.MovieCategory).%New())

}


ClassMethod Update(id As %Integer) As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).Update(##class(dc.movie.model.MovieCategory).%New(), id)

}

ClassMethod Delete(id As %Integer) As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).Delete(##class(dc.movie.model.MovieCategory).%New(), id)

}

}
```

`
5. Create ActorService.cls file inside service folder. Write the content:

`

```
Class dc.movie.service.ActorService
{


ClassMethod GetAll() As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).GetAll(##class(dc.movie.model.Actor).%New())

}


ClassMethod GetOne(id As %Integer) As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).GetOne(##class(dc.movie.model.Actor).%New(), id)

}


ClassMethod Create() As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).Create(##class(dc.movie.model.Actor).%New())

}


ClassMethod Update(id As %Integer) As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).Update(##class(dc.movie.model.Actor).%New(), id)

}


ClassMethod Delete(id As %Integer) As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).Delete(##class(dc.movie.model.Actor).%New(), id)

}

}
```

`
6. Create CastingService.cls file inside service folder. Write the content:

`

```
Class dc.movie.service.CastingService
{


ClassMethod GetAll() As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).GetAll(##class(dc.movie.model.Casting).%New())

}


ClassMethod GetOne(id As %Integer) As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).GetOne(##class(dc.movie.model.Casting).%New(), id)

}


ClassMethod Create() As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).Create(##class(dc.movie.model.Casting).%New())

}


ClassMethod Update(id As %Integer) As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).Update(##class(dc.movie.model.Casting).%New(), id)

}


ClassMethod Delete(id As %Integer) As %Status
{

    Return ##class(dc.movie.service.CrudUtilService).Delete(##class(dc.movie.model.Casting).%New(), id)

}

}
```

`
7. Update the file MovieRESTApp.cls to create paths to all new service class methods. Write the content:

`

```
Class dc.movie.MovieRESTApp Extends %CSP.REST
{


Parameter CHARSET = "utf-8";
Parameter CONVERTINPUTSTREAM = 1;
Parameter CONTENTTYPE = "application/json";
Parameter Version = "1.0.0";
Parameter HandleCorsRequest = 1;

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{

&amp;lt;Routes&amp;gt;

&amp;lt;!-- Server Info --&amp;gt;
&amp;lt;Route Url="/" Method="GET" Call="GetInfo" Cors="true"/&amp;gt;

&amp;lt;!-- Swagger specs --&amp;gt;
&amp;lt;Route Url="/_spec" Method="GET" Call="SwaggerSpec" /&amp;gt;


&amp;lt;!-- List all movies --&amp;gt;
&amp;lt;Route Url="/movies" Method="GET" Call="GetAllMovies" /&amp;gt;

&amp;lt;!-- Get a movie --&amp;gt;
&amp;lt;Route Url="/movies/:id" Method="GET" Call="GetMovie" /&amp;gt;

&amp;lt;!-- Get the movie casting --&amp;gt;
&amp;lt;Route Url="/movies/casting/:id" Method="GET" Call="GetMovieCasting" /&amp;gt;

&amp;lt;!-- Create new movie --&amp;gt;
&amp;lt;Route Url="/movies" Method="POST" Call="CreateMovie" /&amp;gt;

&amp;lt;!-- Update a movie --&amp;gt;
&amp;lt;Route Url="/movies/:id" Method="PUT" Call="UpdateMovie" /&amp;gt;

&amp;lt;!-- Delete a movie --&amp;gt;
&amp;lt;Route Url="/movies/:id" Method="DELETE" Call="DeleteMovie" /&amp;gt;


&amp;lt;!-- List all movie categories --&amp;gt; 
&amp;lt;Route Url="/categories" Method="GET" Call="GetAllMovieCategories" /&amp;gt;

&amp;lt;!-- Get a movie category --&amp;gt;
&amp;lt;Route Url="/categories/:id" Method="GET" Call="GetMovieCategory" /&amp;gt;

&amp;lt;!-- Create new movie category --&amp;gt;
&amp;lt;Route Url="/categories" Method="POST" Call="CreateMovieCategory" /&amp;gt;

&amp;lt;!-- Update a movie category --&amp;gt;
&amp;lt;Route Url="/categories/:id" Method="PUT" Call="UpdateMovieCategory" /&amp;gt;

&amp;lt;!-- Delete a movie category --&amp;gt;
&amp;lt;Route Url="/categories/:id" Method="DELETE" Call="DeleteMovieCategory" /&amp;gt;


&amp;lt;!-- List all actors --&amp;gt;
&amp;lt;Route Url="/actors" Method="GET" Call="GetAllActors" /&amp;gt;

&amp;lt;!-- Get a actor --&amp;gt;
&amp;lt;Route Url="/actors/:id" Method="GET" Call="GetActor" /&amp;gt;

&amp;lt;!-- Create new actor --&amp;gt;
&amp;lt;Route Url="/actors" Method="POST" Call="CreateActor" /&amp;gt;

&amp;lt;!-- Update a actor --&amp;gt;
&amp;lt;Route Url="/actors/:id" Method="PUT" Call="UpdateActor" /&amp;gt;

&amp;lt;!-- Delete a actor --&amp;gt;
&amp;lt;Route Url="/actors/:id" Method="DELETE" Call="DeleteActor" /&amp;gt;


&amp;lt;!-- List all castings --&amp;gt;
&amp;lt;Route Url="/castings" Method="GET" Call="GetAllCastings" /&amp;gt;

&amp;lt;!-- Get a actor --&amp;gt;
&amp;lt;Route Url="/castings/:id" Method="GET" Call="GetCasting" /&amp;gt;

&amp;lt;!-- Create new actor --&amp;gt;
&amp;lt;Route Url="/castings" Method="POST" Call="CreateCasting" /&amp;gt;

&amp;lt;!-- Update a actor --&amp;gt;
&amp;lt;Route Url="/castings/:id" Method="PUT" Call="UpdateCasting" /&amp;gt;

&amp;lt;!-- Delete a actor --&amp;gt;
&amp;lt;Route Url="/castings/:id" Method="DELETE" Call="DeleteCasting" /&amp;gt;

&amp;lt;/Routes&amp;gt;

}


/// List movies
ClassMethod GetAllMovies() As %Status
{

  Return ##class(dc.movie.service.MovieService).GetAll()

}


/// Get movie casting
ClassMethod GetMovieCasting(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.MovieService).GetMovieCasting(id)

}


/// Get a movie
ClassMethod GetMovie(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.MovieService).GetOne(id)

}


// Create a new movie
ClassMethod CreateMovie() As %Status
{

  Return ##class(dc.movie.service.MovieService).Create()

}


// Update a movie
ClassMethod UpdateMovie(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.MovieService).Update(id)

}


// Delete a movie
ClassMethod DeleteMovie(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.MovieService).Delete(id)

}


/// List movies categories
ClassMethod GetAllMovieCategories() As %Status
{

  Return ##class(dc.movie.service.MovieCategoryService).GetAll()

}


/// Get a movie category
ClassMethod GetMovieCategory(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.MovieCategoryService).GetOne(id)

}


// Create a new movie category
ClassMethod CreateMovieCategory() As %Status
{

  Return ##class(dc.movie.service.MovieCategoryService).Create()

}


// Update a movie category
ClassMethod UpdateMovieCategory(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.MovieCategoryService).Update(id)

}

// Delete a movie category
ClassMethod DeleteMovieCategory(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.MovieCategoryService).Delete(id)

}

/// List actors
ClassMethod GetAllActors() As %Status
{

  Return ##class(dc.movie.service.TestActorService).GetAll()

}

/// Get an actor
ClassMethod GetActor(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.ActorService).GetOne(id)

}

// Create a new actor
ClassMethod CreateActor() As %Status
{

  Return ##class(dc.movie.service.ActorService).Create()

}

// Update an actor
ClassMethod UpdateActor(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.ActorService).Update(id)

}

// Delete an actor
ClassMethod DeleteActor(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.ActorService).Delete(id)

}

/// List castings
ClassMethod GetAllCastings() As %Status
{

  Return ##class(dc.movie.service.CastingService).GetAll()

}

/// Get a casting
ClassMethod GetCasting(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.CastingService).GetOne(id)

}

// Create a new casting item
ClassMethod CreateCasting() As %Status
{

  Return ##class(dc.movie.service.CastingService).Create()

}

// Update a casting
ClassMethod UpdateCasting(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.CastingService).Update(id)

}

// Delete a casting
ClassMethod DeleteCasting(id As %Integer) As %Status
{

  Return ##class(dc.movie.service.CastingService).Delete(id)

}


/// General information
ClassMethod GetInfo() As %Status
{

  SET version = ..#Version
  SET fmt=##class(%SYS.NLS.Format).%New("ptbw")

  SET info = {
    "Service": "Movie API",
    "version": (version),
    "Developer": "Yuri Gomes",
    "Status": "Ok",
    "Date": ($ZDATETIME($HOROLOG))
  }

  Set %response.ContentType = ..#CONTENTTYPEJSON
  Set %response.Headers("Access-Control-Allow-Origin")="*"

  Write info.%ToJSON()

  Quit $$$OK

}


ClassMethod %ProcessResult(pStatus As %Status = {$$$OK}, pResult As %DynamicObject = "") As %Status [ Internal ]
{

  #dim %response As %CSP.Response

  SET tSC = $$$OK

  IF $$$ISERR(pStatus) {
    SET %response.Status = 500
    SET tSC = ..StatusToJSON(pStatus, .tJSON)

    IF $isobject(tJSON) {
      SET pResult = tJSON

    } ELSE {

      SET pResult = { "errors": [ { "error": "Unknown error parsing status code" } ] }

    }

  } 

  ELSEIF pStatus=1 {

    IF '$isobject(pResult){
      SET pResult = {

      }

    }

  }

  ELSE {

    SET %response.Status = pStatus

    SET error = $PIECE(pStatus, " ", 2, *)

    SET pResult = {

      "error": (error)

    }

  }


  IF pResult.%Extends("%Library.DynamicAbstractObject") {
    WRITE pResult.%ToJSON()

  }

  ELSEIF pResult.%Extends("%JSON.Adaptor") {
    DO pResult.%JSONExport()

  }

  ELSEIF pResult.%Extends("%Stream.Object") {
    DO pResult.OutputToDevice()

  }

  QUIT tSC

}


ClassMethod SwaggerSpec() As %Status
{

  Set tSC = ##class(%REST.API).GetWebRESTApplication($NAMESPACE, %request.Application, .swagger)

  Do swagger.info.%Remove("x-ISC_Namespace")
  Set swagger.basePath = "/movie-api" 
  Set swagger.info.title = "Movie API"
  Set swagger.info.version = "1.0"
  Set swagger.host = "localhost:52773"
  Return ..%ProcessResult($$$OK, swagger)

}

}
```

`
8. The files and folders to the final project are:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j084teyir18qq0aq4ifs.png)

9. Test your new methods acessing http://localhost:52773/swagger-ui/index.html.

Note 1: REST paths are following business topic in plural with /id when we need pass id to the entity and camel case to paths to.

Note 2: We use verb GET to queries, POST to new records, PUT to update record and DELETE to delete a record.

Note 3: In &amp;lt;Route Url="/movies/casting/:id" Method="GET" Call="GetMovieCasting" /&amp;gt; I used /casting indicating a second purpose (get the movie and it casting). This method runs ToJSON(), because is a DynamicArray ([]) with Dynamic items ({}).

Note 4: I created the CrudUtilService class utility to do generic CRUD methods, following the Dont Repeat Yourself principle.


Enjoy this tutorial! 



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

&lt;/div&gt;

</description>
      <category>rest</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Learning Path for beginners</title>
      <dc:creator>Yuri Marx P. Gomes</dc:creator>
      <pubDate>Wed, 23 Feb 2022 12:48:07 +0000</pubDate>
      <link>https://dev.to/intersystems/learning-path-for-beginners-46d0</link>
      <guid>https://dev.to/intersystems/learning-path-for-beginners-46d0</guid>
      <description>&lt;p&gt;The &lt;a href="https://learning.intersystems.com/"&gt;InterSystems Learning Website&lt;/a&gt; has many important iterative courses. So if you want to learn about InterSystems and start to work with InterSystems this is the path:&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction to InterSystems Products and Technologies: &lt;a href="https://learning.intersystems.com/course/view.php?id=1168&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1168&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fundamentals:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;InterSystems ObjectScript Basics: &lt;a href="https://learning.intersystems.com/course/view.php?id=959&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=959&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;InterSystems SQL Overview: &lt;a href="https://learning.intersystems.com/course/view.php?id=960&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=960&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;InterSystems IRIS Objects Introduction: &lt;a href="https://learning.intersystems.com/course/view.php?id=938&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=938&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Migrate to IRIS (contribution from Kristina Lauer): &lt;a href="https://learning.intersystems.com/course/view.php?name=MigratingToIRIS"&gt;https://learning.intersystems.com/course/view.php?name=MigratingToIRIS&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Backend Development:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Setting Up RESTful Services: &lt;a href="https://learning.intersystems.com/course/view.php?id=1298&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1298&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Using JSON in InterSystems IRIS: &lt;a href="https://learning.intersystems.com/course/view.php?id=972&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=972&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hands-On with InterSystems API Manager for Developers: &lt;a href="https://learning.intersystems.com/course/view.php?id=1747&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1747&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Building Data-Driven Web Apps: &lt;a href="https://learning.intersystems.com/course/view.php?id=1237&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1237&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Integration Development:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Integration Architecture: &lt;a href="https://learning.intersystems.com/course/view.php?id=908&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=908&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Building BPL Business Processes: &lt;a href="https://learning.intersystems.com/course/view.php?id=1290&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1290&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Building Custom Business Operations: &lt;a href="https://learning.intersystems.com/course/view.php?id=1288&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1288&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Building Custom Business Services: &lt;a href="https://learning.intersystems.com/course/view.php?id=1291&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1291&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Data Transformations Basics: &lt;a href="https://learning.intersystems.com/course/view.php?id=1170&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1170&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Very nice external resource: &lt;a href="https://github.com/grongierisc/formation-template"&gt;https://github.com/grongierisc/formation-template&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Interoperability Course (contribution from &lt;a class="mentioned-user" href="https://dev.to/guillaume"&gt;@guillaume&lt;/a&gt; Rongier): &lt;a href="https://community.intersystems.com/post/ensemble-interoperability-traini"&gt;https://community.intersystems.com/post/ensemble-interoperability-traini&lt;/a&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Analytics Development:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;IRIS BI Architect: &lt;a href="https://learning.intersystems.com/course/view.php?id=1752&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1752&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;IRIS BI Analyzer: &lt;a href="https://learning.intersystems.com/course/view.php?id=1793&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1793&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;BI Data Models: &lt;a href="https://learning.intersystems.com/course/view.php?id=1796&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1796&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;InterSystems IRIS Adaptive Analytics Essentials: &lt;a href="https://learning.intersystems.com/course/view.php?id=1715&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1715&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Getting Started with InterSystems Reports: &lt;a href="https://learning.intersystems.com/course/view.php?id=1538&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1538&amp;amp;ssoPass=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hands-On with IntegratedML: &lt;a href="https://learning.intersystems.com/course/view.php?id=1535&amp;amp;ssoPass=1"&gt;https://learning.intersystems.com/course/view.php?id=1535&amp;amp;ssoPass=1&lt;/a&gt;
Paths from learning.intersystems.com (contribution from &lt;a class="mentioned-user" href="https://dev.to/jenny"&gt;@jenny&lt;/a&gt; Ames)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  If you're looking to get started, you can also personalize which paths you take based on what you're trying to do:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Building a Server-Side Application with InterSystems: &lt;a href="https://learning.intersystems.com/course/view.php?name=IRIS%20Server%20Side"&gt;https://learning.intersystems.com/course/view.php?name=IRIS%20Server%20Side&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Building Business Integrations with InterSystems IRIS: &lt;a href="https://learning.intersystems.com/course/view.php?name=InteroperabilityForBusiness"&gt;https://learning.intersystems.com/course/view.php?name=InteroperabilityForBusiness&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Analyzing Data with InterSystems IRIS BI: &lt;a href="https://learning.intersystems.com/course/view.php?name=BuildingAnalyzer"&gt;https://learning.intersystems.com/course/view.php?name=BuildingAnalyzer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Build Data Models Using Adaptive Analytics: &lt;a href="https://learning.intersystems.com/course/view.php?name=AALP"&gt;https://learning.intersystems.com/course/view.php?name=AALP&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Delivering Data Visually with InterSystems Reports: &lt;a href="https://learning.intersystems.com/course/view.php?name=InterSystemsReports"&gt;https://learning.intersystems.com/course/view.php?name=InterSystemsReports&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Predicting Outcomes with IntegratedML in InterSystems IRIS: &lt;a href="https://learning.intersystems.com/course/view.php?name=Learn%20IntegratedML"&gt;https://learning.intersystems.com/course/view.php?name=Learn%20IntegratedML&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alternately, there are a several larger paths for implementation partners (or others who will be doing everything, paths are open to all) here: &lt;a href="https://learning.intersystems.com/course/view.php?name=IPLPs"&gt;https://learning.intersystems.com/course/view.php?name=IPLPs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>Mapping Intersystems IRIS documentation to a Corporate Data Architecture</title>
      <dc:creator>Yuri Marx P. Gomes</dc:creator>
      <pubDate>Thu, 17 Sep 2020 15:53:53 +0000</pubDate>
      <link>https://dev.to/intersystems/mapping-intersystems-iris-documentation-to-a-corporate-data-architecture-2b1j</link>
      <guid>https://dev.to/intersystems/mapping-intersystems-iris-documentation-to-a-corporate-data-architecture-2b1j</guid>
      <description>&lt;p&gt;If you need write your organization Data Architecture and map to the InterSystems IRIS, consider this Data Architecture Diagram and references to the Intersystems IRIS documentation above:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KUkGLIKB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iv3o7rgifgs4n607kvgs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KUkGLIKB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iv3o7rgifgs4n607kvgs.png" width="801" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Architecture mapping:&lt;/strong&gt;&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;SQL Database: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GSQL"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GSQL&lt;/a&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;Managed Files: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=AFL_mft"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=AFL_mft&lt;/a&gt; and &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=SETEDIGuides"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=SETEDIGuides&lt;/a&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;IoT Broker, Events and Sensors: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=EMQTT"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=EMQTT&lt;/a&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;Messages: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=EMQS"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=EMQS&lt;/a&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;NoSQL: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GDOCDB"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GDOCDB&lt;/a&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;API and Web Services: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GREST"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GREST&lt;/a&gt;, &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GSOAP"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GSOAP&lt;/a&gt;, &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=AFL_iam"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=AFL_iam&lt;/a&gt; and &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=PAGE_interoperability"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=PAGE_interoperability&lt;/a&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;ETL: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=SETAdapters"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=SETAdapters&lt;/a&gt;, &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=EDTL"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=EDTL&lt;/a&gt;, &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=EBPL"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=EBPL&lt;/a&gt; and &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;EAI Connectors: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=SETAdapters"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=SETAdapters&lt;/a&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;XEP Events: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=BJAVXEP"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=BJAVXEP&lt;/a&gt;, &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=BNETXEP"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=BNETXEP&lt;/a&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;Big Data Ingestion: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=BSPK"&gt;https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=BSPK&lt;/a&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;AI: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=PAGE_text_analytics"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=PAGE_text_analytics&lt;/a&gt;, &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=APMML"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=APMML&lt;/a&gt;, &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=PAGE_python_native"&gt;https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=PAGE_python_native&lt;/a&gt;, &lt;a href="https://www.intersystems.com/br/resources/detail/machine-learning-made-easy-intersystems-integratedml/"&gt;https://www.intersystems.com/br/resources/detail/machine-learning-made-easy-intersystems-integratedml/&lt;/a&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;Processes: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=EBPL"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=EBPL&lt;/a&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;Corporate Service: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=EESB"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=EESB&lt;/a&gt; and &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=AFL_iam"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=AFL_iam&lt;/a&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;In memory: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GSCALE_ecp"&gt;https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GSCALE_ecp&lt;/a&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;Content: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GDOCDB"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GDOCDB&lt;/a&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;Textual: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AFL_textanalytics"&gt;https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AFL_textanalytics&lt;/a&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;Protection: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=SETSecurity"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=SETSecurity&lt;/a&gt;, &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=TSQS_Applications"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=TSQS_Applications&lt;/a&gt;,  &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GCDI"&gt;https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GCDI&lt;/a&gt; and &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GCAS"&gt;https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GCAS&lt;/a&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;Inventory: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GSA_using_portal"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GSA_using_portal&lt;/a&gt; and &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GOBJ_xdata"&gt;https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GOBJ_xdata&lt;/a&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;Privacy: &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=GCAS_encrypt"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GCAS_encrypt&lt;/a&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;IT Lifecycle, Backup and Restore: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GSA_using_portal"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GSA_using_portal&lt;/a&gt;, &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GCDI_backup"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GCDI_backup&lt;/a&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;Access Management: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=TSQS_Authentication"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=TSQS_Authentication&lt;/a&gt;, &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=TSQS_Authorization"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=TSQS_Authorization&lt;/a&gt;, &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=TSQS_Applications"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=TSQS_Applications&lt;/a&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;Replication and HA: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=PAGE_high_availability"&gt;https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=PAGE_high_availability&lt;/a&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;Monitoring: &lt;a href="https://docs.intersystems.com/sam/csp/docbook/DocBook.UI.Page.cls?KEY=ASAM"&gt;https://docs.intersystems.com/sam/csp/docbook/DocBook.UI.Page.cls?KEY=ASAM&lt;/a&gt; and &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=PAGE_monitoring"&gt;https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=PAGE_monitoring&lt;/a&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;IT Operation: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=PAGE_platform_mgmt"&gt;https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=PAGE_platform_mgmt&lt;/a&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;Visualization: &lt;a href="https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=PAGE_bi"&gt;https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=PAGE_bi&lt;/a&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>database</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Integrate SAP and InterSystems IRIS using OData</title>
      <dc:creator>Yuri Marx P. Gomes</dc:creator>
      <pubDate>Wed, 12 Aug 2020 14:48:58 +0000</pubDate>
      <link>https://dev.to/intersystems/integrate-sap-and-intersystems-iris-using-odata-2b2m</link>
      <guid>https://dev.to/intersystems/integrate-sap-and-intersystems-iris-using-odata-2b2m</guid>
      <description>&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;SAP offers a broad support to OData in all your products. So, OData can be an excellent option to exchange data between SAP and InterSystems IRIS.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Follow the instructions in the article &lt;a href="https://community.intersystems.com/post/odata-and-intersystems-iris"&gt;https://community.intersystems.com/post/odata-and-intersystems-iris&lt;/a&gt; to expose your IRIS data as REST OData services.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;To consume InterSystems IRIS data from SAP using OData, follow these steps (credits to the next steps of this tutorial: &lt;a href="https://sapyard.com/sapui5-for-abapers-consuming-odata-service-from-sapui5-application-crud-operations/"&gt;https://sapyard.com/sapui5-for-abapers-consuming-odata-service-from-sapui5-application-crud-operations/&lt;/a&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;Create a new SAPUI5 application by the name crud_demo.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Create a XML view ‘crud_demo.view’. Write below code in it.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;controllerName="crud_demo.crud_demo" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:l="sap.ui.commons.layout"&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Page title="CRUD Operations"&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;content&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;l:AbsoluteLayout width="10rem" height="10rem"&amp;gt;&amp;lt;/l:AbsoluteLayout&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;VBox xmlns="sap.m" id="vboxid"&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;items&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;HBox xmlns="sap.m"&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;items&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;l:AbsoluteLayout width="20px" height="20px"&amp;gt;&amp;lt;/l:AbsoluteLayout&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Button xmlns="sap.m" id="cbtn" press="oDataCall" text="Create"&amp;gt;&amp;lt;/Button&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;l:AbsoluteLayout width="20px" height="20px"&amp;gt;&amp;lt;/l:AbsoluteLayout&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Button xmlns="sap.m" id="rbtn" press="oDataCall" text="Read"&amp;gt;&amp;lt;/Button&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;l:AbsoluteLayout width="20px" height="20px"&amp;gt;&amp;lt;/l:AbsoluteLayout&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Button xmlns="sap.m" id="ubtn" press="oDataCall" text="Update"&amp;gt;&amp;lt;/Button&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;l:AbsoluteLayout width="20px" height="20px"&amp;gt;&amp;lt;/l:AbsoluteLayout&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Button xmlns="sap.m" id="dbtn" press="oDataCall" text="Delete"&amp;gt;&amp;lt;/Button&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/items&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/HBox&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;HBox xmlns="sap.m"&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;items&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;l:AbsoluteLayout width="20px" height="20px"&amp;gt;&amp;lt;/l:AbsoluteLayout&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Input xmlns="sap.m" id="uniqueid" placeholder="ID" value="1"&amp;gt;&amp;lt;/Input&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;l:AbsoluteLayout width="20px" height="20px"&amp;gt;&amp;lt;/l:AbsoluteLayout&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Input xmlns="sap.m" id="nameid" placeholder="Name" value="test"&amp;gt;&amp;lt;/Input&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;l:AbsoluteLayout width="20px" height="20px"&amp;gt;&amp;lt;/l:AbsoluteLayout&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;l:AbsoluteLayout width="20px" height="20px"&amp;gt;&amp;lt;/l:AbsoluteLayout&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Input xmlns="sap.m" id="mobid" placeholder="Mobile" value="8888888888"&amp;gt;&amp;lt;/Input&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/items&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/HBox&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;HBox xmlns="sap.m"&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;items&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;l:AbsoluteLayout width="20px" height="20px"&amp;gt;&amp;lt;/l:AbsoluteLayout&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Table xmlns="sap.m"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;id="userdatatable" headerText="User Data"&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;items&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;ListItemBase xmlns="sap.m" id="id1"&amp;gt;&amp;lt;/ListItemBase&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/items&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;columns&amp;gt; &amp;lt;!-- sap.m.Column --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Column xmlns="sap.m"&amp;gt; &amp;lt;header&amp;gt; &amp;lt;Text xmlns="sap.m" text="Id" &amp;gt;&amp;lt;/Text&amp;gt;&amp;lt;/header&amp;gt;&amp;lt;/Column&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Column xmlns="sap.m"&amp;gt; &amp;lt;header&amp;gt; &amp;lt;Text xmlns="sap.m" text="Name" &amp;gt;&amp;lt;/Text&amp;gt;&amp;lt;/header&amp;gt;&amp;lt;/Column&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Column xmlns="sap.m"&amp;gt; &amp;lt;header&amp;gt; &amp;lt;Text xmlns="sap.m" text="Email" &amp;gt;&amp;lt;/Text&amp;gt;&amp;lt;/header&amp;gt;&amp;lt;/Column&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;Column xmlns="sap.m"&amp;gt; &amp;lt;header&amp;gt; &amp;lt;Text xmlns="sap.m" text="Mobile" &amp;gt;&amp;lt;/Text&amp;gt;&amp;lt;/header&amp;gt;&amp;lt;/Column&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/columns&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/Table&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/items&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/HBox&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/items&amp;gt; &amp;lt;!-- sap.ui.core.Control --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/VBox&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/content&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/Page&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;lt;/core:View&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;ol start="4"&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Create crud_demo.controller.js. Write below code in it.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;onInit: function() {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;that = this;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;// Create Model Instance of the oData service&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;var oModel = new sap.ui.model.odata.v2.ODataModel("/sap/opu/odata/sap/ZCRUD_DEMO_SRV");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;sap.ui.getCore().setModel(oModel, "myModel");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;oDataCall:function(oEvent)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;// call oData service's function based on which button is clicked.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;debugger;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;var myModel = sap.ui.getCore().getModel("myModel");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;myModel.setHeaders({&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;"X-Requested-With" : "X"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;// CREATE******************&lt;/span&gt;&lt;/span&gt;&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 ('Create' == oEvent.oSource.mProperties.text) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;var obj = {};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;obj.id = that.getView().byId("uniqueid").getValue();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;obj.name = that.getView().byId("nameid").getValue();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;obj.email = that.getView().byId("emailid").getValue();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;obj.mobile = that.getView().byId("mobid").getValue();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;myModel.create('/userdataSet', obj, {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;success : function(oData, oResponse) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;debugger;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;alert('Record Created Successfully...');&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;error : function(err, oResponse) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;debugger;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;alert('Error while creating record - '&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;.concat(err.response.statusText));&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;// READ******************&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;else if ('Read' == oEvent.oSource.mProperties.text) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;var readurl = "/userdataSet?$filter=(id eq '')";&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;myModel.read(readurl, {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;success : function(oData, oResponse) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;debugger;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;var userdata = new sap.ui.model.json.JSONModel({&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;"Result" : oData.results&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;var tab = that.getView().byId("userdatatable");&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;tab.setModel(userdata);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;var i = 0;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;tab.bindAggregation("items", {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;path : "/Result",&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;template : new sap.m.ColumnListItem({&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;cells : [ new sap.ui.commons.TextView({&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;text : "{id}",&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;design : "H5",&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;semanticColor : "Default"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;}), new sap.ui.commons.TextView({&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;text : "{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;design : "H5",&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;semanticColor : "Positive"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;}), new sap.ui.commons.TextView({&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;text : "{email}",&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;design : "H5",&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;semanticColor : "Positive"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;}), new sap.ui.commons.TextView({&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;text : "{mobile}",&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;design : "H5",&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;semanticColor : "Positive"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;}), ]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;error : function(err) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;debugger;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;} &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;// UPDATE******************&lt;/span&gt;&lt;/span&gt;&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 ('Update' == oEvent.oSource.mProperties.text) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;var obj = {};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;obj.id = that.getView().byId("uniqueid").getValue();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;obj.email = that.getView().byId("emailid").getValue();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;var updateurl = "/userdataSet(id='"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;+ that.getView().byId("uniqueid").getValue() + "')";&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;myModel.update(updateurl, obj, {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;success : function(oData, oResponse) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;debugger;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;alert('Record Updated Successfully...');&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;error : function(err, oResponse) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;debugger;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;alert('Error while updating record - '&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;.concat(err.response.statusText));&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;} &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;// DELETE******************&lt;/span&gt;&lt;/span&gt;&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 ('Delete' == oEvent.oSource.mProperties.text) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;var delurl = "/userdataSet(id='"&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;+ that.getView().byId("uniqueid").getValue() + "')";&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;myModel.remove(delurl, {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;success : function(oData, oResponse) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;debugger;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;alert('Record Removed Successfully...');&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;error : function(err, oResponse) {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;debugger;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;alert('Error while removing record - '&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;.concat(err.response.statusText));&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;ol start="4"&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Save, Deploy and Run the application. You should be able to run the application using below URL &lt;a href="http://hostname:8000/sap/bc/ui5_ui5/sap/zcrud_demo/index.html"&gt;http://hostname:8000/sap/bc/ui5_ui5/sap/zcrud_demo/index.html&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt; &lt;/p&gt;

&lt;ol start="6"&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Output:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sjut0OW8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sjgno7tme704pewbbo49.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sjut0OW8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sjgno7tme704pewbbo49.png" width="609" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>database</category>
    </item>
    <item>
      <title>OData and InterSystems IRIS</title>
      <dc:creator>Yuri Marx P. Gomes</dc:creator>
      <pubDate>Wed, 12 Aug 2020 14:37:41 +0000</pubDate>
      <link>https://dev.to/intersystems/odata-and-intersystems-iris-370f</link>
      <guid>https://dev.to/intersystems/odata-and-intersystems-iris-370f</guid>
      <description>&lt;h2&gt;&lt;span&gt;&lt;strong&gt;&lt;span&gt;&lt;span&gt;What is the OData&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;OData (Open Data Protocol) is an &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;a href="https://www.oasis-open.org/news/pr/iso-iec-jtc-1-approves-oasis-odata-standard-for-open-data-exchange"&gt;ISO/IEC approved&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;a href="https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=odata"&gt;OASIS standard&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; that defines a set of best practices for building and consuming RESTful APIs. OData helps you focus on your business logic while building RESTful APIs without having to worry about the various approaches to define request and response headers, status codes, HTTP methods, URL conventions, media types, payload formats, query options, etc. OData also provides guidance for tracking changes, defining functions/actions for reusable procedures, and sending asynchronous/batch requests (source: OData.org).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;&lt;span&gt;&lt;strong&gt;&lt;span&gt;&lt;span&gt;The OData use cases&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Deploy data as REST Services with an interoperable format without development effort;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Allows BI, data visualization, ERP, CRM, ESB, Workflow tools and engines consume data using REST without development effort;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Virtualize corporate data in API Management tools;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;OData advocates a standard way of implementing REST APIs that allows for SQL-like querying capabilities using these RESTful APIs. OData is essentially SQL for the web built n top of standard protocols – HTTP, JSON &amp;amp; ATOM – while leveraging the REST architecture style (progress.com);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;OData has a broad adoption, see: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;OData helps to implement FHIR: FHIR, or Fast Healthcare Interoperability Resources Specification, is a standard for exchanging healthcare information electronically. In order to make FHIR truly interoperable, it is &lt;a href="http://hl7.org/fhir/search.html"&gt;recommended that systems use the rules specified by OData specification &lt;/a&gt;for the $search parameter. Further, FHIR also uses OAuth in order to establish a trusted relationship with the client for an extra layer of security (progress.com);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;OData supports pagination, batch requests and different formats like JSON, ATOM, XML, etc.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;span&gt;&lt;strong&gt;&lt;span&gt;&lt;span&gt;OData and InterSystems IRIS&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;The InterSystems IRIS does not support OData but is possible use the OData Server for InterSystems IRIS to allows expose Persistent classes as REST. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Follow these instructions:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Clone the source code of the IRIS OData Server: git clone &lt;a href="https://github.com/yurimarx/isc-iris-odata.git"&gt;https://github.com/yurimarx/isc-iris-odata.git&lt;/a&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;Go to: isc-iris-odata folder&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Execute: mvnw install (MS Windows) or ./mvnw install (linux or mac)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Execute: docker build -t odata:1.0.0 .&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Execute: docker run -p 8080:8080 odata:1.0.0. Your OData Server started:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_aljOjIn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yidexai1nxhqd7mfe0es.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_aljOjIn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yidexai1nxhqd7mfe0es.png" width="747" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol start="6"&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Start your InterSystems IRIS instance with any persistent class, in my ca&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;In your browser access:   &lt;a href="http://localhost:8080/"&gt;http://localhost:8080/&lt;/a&gt;. Set parameters on the screen:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cTO_5pmI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ylak0pil3z6hsdm7ye3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cTO_5pmI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ylak0pil3z6hsdm7ye3w.png" width="774" height="147"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol start="8"&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;This is parameters to my instance. Set the parameters to your IRIS instance. In namespace set your iris namespace, in the schema, the SQL Table schema, and in the port, the port to your JDBC database connection. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Press submit and RELOAD YOUR ODATA SERVER DOCKER INSTANCE TO APPLY PARAMETERS.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Access &lt;a href="http://localhost:8080/odata.svc/"&gt;http://localhost:8080/odata.svc/&lt;/a&gt; to see all persistent classes to your IRIS schema. In my case is:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GvEUmwPr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gob48pkdrga7367syq8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GvEUmwPr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gob48pkdrga7367syq8q.png" width="408" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol start="11"&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;To navigate to a persistent class browse: &lt;a href="http://localhost:8080/odata.svc/%3cPersistent_Class%3e"&gt;http://localhost:8080/odata.svc/&amp;lt;Persistent_Class&amp;gt;&lt;/a&gt; e.g.: &lt;a href="http://localhost:8080/odata.svc/Animal"&gt;http://localhost:8080/odata.svc/Animal&lt;/a&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;The OData server list Animal data, see:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vIqSZ2j7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u0swfoi81qae4bk87cuv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vIqSZ2j7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u0swfoi81qae4bk87cuv.png" width="555" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol start="13"&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;To see in JSON format browse: &lt;a href="http://localhost:8080/odata.svc/Animal?%24format=application/json"&gt;http://localhost:8080/odata.svc/Animal?$format=application/json&lt;/a&gt;. See:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y7EiGEdb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7cjdqk0g1cqzm6hw2yi5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y7EiGEdb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7cjdqk0g1cqzm6hw2yi5.png" width="415" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol start="14"&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; To see details about a row browse: &lt;a href="http://localhost:8080/odata.svc/Animal(8)?%24format=application/json"&gt;http://localhost:8080/odata.svc/Animal(8)?$format=application/json&lt;/a&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;To delete send a DELETE in your postman with &lt;a href="http://localhost:8080/odata.svc/Animal(8)"&gt;http://localhost:8080/odata.svc/Animal(8)&lt;/a&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;To insert send a POST in your postman with &lt;a href="http://localhost:8080/odata.svc/Animal"&gt;http://localhost:8080/odata.svc/Animal&lt;/a&gt; and a JSON body with property name and value pairs, like:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yIfl0PVQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ogzvq9np2dz26aw6twad.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yIfl0PVQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ogzvq9np2dz26aw6twad.png" width="452" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol start="17"&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;So you can do all CRUD operations with your persistent classes.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Many other features will be released in the future, if IRIS OData Server get the community adoption.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;Thanks! &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

</description>
      <category>database</category>
    </item>
  </channel>
</rss>
