#ObjectScript

0 Followers · 1.5K Posts

InterSystems ObjectScript is a scripting language to operate with data using any data model of InterSystems Data Platform (Objects, Relational, Key-Value, Document, Globals) and to develop business logic for serverside applications on InterSystems Data Platform.

Documentation.

Article Muhammad Waseem · Feb 28, 2025 7m read

Hi Community, 
In this article, we will explore the concepts of Dynamic SQL and Embedded SQL within the context of InterSystems IRIS, provide practical examples, and examine their differences to help you understand how to leverage them in your applications.

InterSystems SQL provides a full set of standard relational features, including the ability to define table schema, execute queries, and define and execute stored procedures. You can execute InterSystems SQL interactively from the Management Portal or programmatically using a SQL shell interface. Embedded SQL enables you to embed SQL statements in your ObjectScript code, while Dynamic SQL enables you to execute dynamic SQL statements from ObjectScript at runtime. While static SQL queries offer predictable performance, dynamic and embedded SQL offer flexibility and integration, respectively.

8
4 376
Article Ashok Kumar T · Oct 20, 2025 11m read

What is XML?

XML(eXtensible Markup Language) is a flexible, text-based, andplatform-independentformat used to store and transport data in a well-structured way that is both human- and machine-readable. XML permits users to define custom tags to describe the meaning and organization of their data. For example: <book><title>The Hitchhiker's Guide</title></book>.

3
5 163
Article Rob Tweed · Feb 26, 2025 6m read

Introduction

My guess is that most IRIS developers create their applications using its native ObjectScript language or, if using an external language, then most likely using either Java, Python or perhaps C++.

I suspect that only a minority have considered using JavaScript as their language of choice, which, if true, is a great shame, because, In my opinion and experience, JavaScript is the closest equivalent to ObjectScript in terms of its ability to integrate with the IRIS's underlying multi-dimensional database. 

1
2 270
Article Andrew Sklyarov · Nov 2, 2025 7m read

Over time, while I was working with Interoperability on the IRIS Data Platform, I developed rules for organizing a project code into packages and classes. That is what is called a Naming Convention, usually. In this topic, I want to organize and share these rules. I hope it can be helpful for somebody.

 

4
2 82
Article Robert Cemper · Oct 21, 2025 2m read

If you start with InterSystems ObjectScript, you will meet the XECUTE command.
And beginners may ask: Where and Why may I need to use this ?

The official documentation has a rich collection of code snippets. No practical case.
Just recently, I met a use case that I'd like to share with you.

The scenario:

When you build an IRIS container with Docker, then, in most cases,
you run the  initialization script  

iris session iris < iris.script 
1
3 78
Question Jorge Gea Martínez · Oct 22, 2025

Hi,

I'm trying to run some scripting in Windows. I'm using an instance of the IRISHealth community. 

I'm just trying to run a simple sequence of commands so I can run irissession in a non-interactive mode, like:

irissession.exe IRISHEALTH -U "%SYS" < "myprogram.iris"

 

The contents of my program.iris are, for instance, these ones, to run an online backup:

set$namespace="%SYS"set cbk = "C:\Test1.cbk"set log = "C:\Test1.log"w$$BACKUP^DBACK("","F","MyBackup",cbk,"Y",log,"NOINPUT","Y","Y", 1000, "Test1")
HALT

The execution starts, but then gets completely hung, I see infinitely:

2
0 49
Article Vachan C Rannore · Oct 21, 2025 3m read

Hello!!!

Data migration often sounds like a simple "move data from A to B task" until you actually do it. In reality, it is a complex process that blends planning, validation, testing, and technical precision.

Over several projects where I handled data migration into a HIS which runs on IRIS (TrakCare), I realized that success comes from a mix of discipline and automation.

Here are a few points which I want to highlight.

1. Start with a Defined Data Format.

Before you even open your first file, make sure everyone, especially data providers, clearly understands the exact data format you expect. Defining templates early avoids unnecessary bank-and-forth and rework later. 

While Excel or CSV formats are common, I personally feel using a tab-delimited text file (.txt) for data upload is best. It's lightweight, consistent, and avoids issues with commas inside text fields. 

PatID   DOB Gender  AdmDate
10001   2000-01-02  M   2025-10-01
10002   1998-01-05  F   2025-10-05
10005   1980-08-23  M   2025-10-15

Make sure that the date formats given in the file is correct and constant throughout the file because all these files are usually converted from an Excel file and an Basic excel user might make mistakes while giving you the date formats wrong. Wrong date formats can irritate you while converting into horolog.

8
1 103
Article Vachan C Rannore · Sep 15, 2025 2m read

Starting out with ObjectScript, it is really exciting, but it can also feel a little unusual if you're used to other languages. Many beginners trip over the same hurdles, so here are a few "gotchas" you'll want to watch out for. (Also few friendly tips to avoid them)

NAMING THINGS RANDOMLY

We have all been guilty of naming something Test1 or MyClass just to move on quickly. But once your project grows, these names become a nightmare. 

➡ Pick clear, consistent names from the start. Think of it as leaving breadcrumbs for your future self and your teammates.

MIXING UP GLOBALS AND VARIABLES

15
2 280
Article Robert Cemper · Oct 14, 2025 3m read

To better understand Streams in IRIS I'll start with a short

History

In the beginning (before IRIS), there was just basic access to external devices.
The 4 commands OPEN, CLOSE, READ, WRITE still work and are documented 
by  Introduction to I/O in detail.
Especially for files, this is a direct access to your actual file system.
You have to take care of any status or other signal in your code.  
Also, any code conversion or similar is up to you. 

2
3 80
Question Scott Roth · Oct 13, 2025

I have a custom defined priority field that is being stored as a number type

<record name="LocalClinicalMeSHTerms" type="serial">
<field name="LocalClinicalExpertiseCodedValue" type="{CODETYPE}" codeFamily="HSPD" codeTable="LocalClinicalExpertise" codeScheme="{MASTER}"/>
<field name="LocalCliniclDisplayOrder" type="number"/>
</record>

However, within the overviewIndividual.cls form

0
0 37
Article Yuri Marx · Oct 9, 2025 4m read

The ObjectScript language has incredible JSON support through classes like %DynamicObject and %JSON.Adaptor. This support is due to the JSON format's immense popularity over the previous dominance of XML. JSON brought less verbosity to data representation and increased readability for humans who needed to interpret JSON content. To further reduce verbosity and increase readability, the YAML format was created. The very easy-to-read YAML format quickly became the most popular format for representing configurations and parameterizations, due to its readability and minimal verbosity. While XML is

1
1 67
Question Gopal Mani · Oct 7, 2025

Hi Community,
I’m trying to execute a directory query in InterSystems IRIS using %SQL.Statement, but encountering an unexpected error.

Details:
The following command confirms that the directory exists:

Set dirPath="\\MYNETWORK_DRIVE\DFS-Shared_Product\GXM"
Write ##class(%File).DirectoryExists(dirPath)

It returns 1, meaning the path is valid and accessible.

However, when I try to execute this SQL query:

Set File=##Class(%SQL.Statement).%New()
Set Status=File.%PrepareClassQuery("%File","FileSet")
Set Result=File.%Execute(dirPath)
If Result.%SQLCODE {
    Write Result.%Message
}

I get the error:

3
0 62
Article Andrew Sklyarov · Oct 3, 2025 8m read

I was really surprised that such a flexible integration platform with a rich toolset specifically for app connections has no out-of-the-box Enterprise Service Bus solution. Like Apache ServiceMix, Mule ESB, SAP PI/PO, etc, what’s the reason? What do you think? Has this pattern lost its relevance completely nowadays? And everybody moved to message brokers, maybe?

0
1 65
Article Raef Youssef · Oct 2, 2025 5m read

Why This Matters

Managing IAM can be tedious when done manually — especially when your APIs are already well-documented using OpenAPI (Swagger) specs. Wouldn't it be great if you could automatically generate Kong services and routes directly from your OpenAPI spec?

That's exactly what this ObjectScript method does: it reads an OpenAPI 2.0 spec stored in the XData block of your spec class and generates a decK-compatible YAML file that can be used to sync your IAM configuration.

This approach:

  • Reduces manual configuration errors
  • Keeps your gateway in sync with your API spec
  • Speeds up deployment and onboarding

Prerequisites:

  • InterSystems IRIS or IRIS based platform
  • InterSystems API Manager
  • Deck CLI tool

What the Method Does

The method ConvertOpenAPIXDataToDeckYAML:

  1. Reads the OpenAPI spec from an XData block named OpenAPI in a given class.
  2. Parses the JSON into a dynamic object.
  3. Extracts endpoints and HTTP methods.
  4. Generates a YAML file that defines:
    • A Kong service pointing to the API host and base path
    • Routes for each endpoint
    • A rate-limiting plugin on each route (optional enhancement)

Example Spec Class

You can use the below sample spec class or use the class generated from posting the spec file that is included in the previous post linked below.

Class MyApp.spec
{
XData OpenAPI [ MimeType = application/json ]
{
{
  "swagger": "2.0",
  "host": "api.example.com",
  "basePath": "/v1",
  "paths": {
    "/users": {
      "get": { "summary": "Get users" },
      "post": { "summary": "Create user" }
    },
    "/products": {
      "get": { "summary": "Get products" }
    }
  }
}
}
}

The Method and Use

Below is the ClassMethod. You can of course tweak to suit your needs.

/// Convert OpenAPI XData to Deck YAML
ClassMethod ConvertOpenAPIXDataToDeckYAML(specClassName As %String, outputFilePath As %String = "") As %Status
{
    Try {
        // Read the XData block named "OpenAPI"
        Set reader = ##class(%Dictionary.XDataDefinition).%OpenId(specClassName _ "||OpenAPI")
        If reader = "" {
            Write "Error: XData block 'OpenAPI' not found in class ", specClassName, !
            //Quit $$$ERROR
        }
        // Read the stream content into a string
        Set stream = reader.Data
        Set specJSON = ""
        While 'stream.AtEnd {
            Set specJSON = specJSON _ stream.ReadLine()
        }
        // Test call
        //Do ##class(ConsentAPI.Utils).ConvertOpenAPIXDataToDeckYAML("SpecAPI.spec")

        // Parse the JSON into a dynamic object
        Set spec = ##class(%DynamicObject).%FromJSON(specJSON)

        // Initialize YAML structure
        Set deckYAML = "services:" _ $CHAR(13)

        // Extract host and basePath
        Set host = $PIECE($SYSTEM, ":", 1)
        Set basePath = spec.basePath

        // Create service block
        Set deckYAML = deckYAML _ "  - name: " _ host _ $CHAR(13)
        Set deckYAML = deckYAML _ "    url: "_$c(34)_"http://" _ host _ basePath _$c(34)_ $CHAR(13)
        Set deckYAML = deckYAML _ "    routes:" _ $CHAR(13)
        
        // Iterate over paths
        Set pathIter = spec.paths.%GetIterator()
        While pathIter.%GetNext(.key, .value) {
            Set pathKey = key
            Set path = spec.paths.key
            Set routeName = $REPLACE(key , "/", "")
            Set deckYAML = deckYAML _ "      - name: " _ routeName _ $CHAR(13)
            Set deckYAML = deckYAML _ "        strip_path: false"_$CHAR(13)
            Set deckYAML = deckYAML _ "        preserve_host: false"_$CHAR(13)
            Set deckYAML = deckYAML _ "        paths:"_$CHAR(13)
            Set deckYAML = deckYAML _ "          - " _ pathKey _ $CHAR(13)
            Set deckYAML = deckYAML _ "        methods:"_$CHAR(13)
            Set methodIter = value.%GetIterator()
            While methodIter.%GetNext(.key, .value) {
                Set methodKey = key
                Set deckYAML = deckYAML _ "          - " _ $ZCONVERT(methodKey, "U") _ $CHAR(13)

            }
            Set deckYAML = deckYAML _ "        plugins:"_$CHAR(13)
            Set deckYAML = deckYAML _ "        - name: " _ "rate-limiting" _ $CHAR(13)
            Set deckYAML = deckYAML _ "          config:"_$CHAR(13)
            Set deckYAML = deckYAML _ $REPLACE($J("",12),"",$C(32))_"minute: 20" _ $CHAR(13)
            Set deckYAML = deckYAML _ $REPLACE($J("",12),"",$C(32))_"hour: 500" _ $CHAR(13)
        }

        // Output to file or console
        If outputFilePath '= "" {
            Set file = ##class(%Stream.FileCharacter).%New()
            Set file.Filename = outputFilePath
            Do file.Write(deckYAML)
            Do file.%Save()
            Write "YAML saved to: ", outputFilePath, !
        } Else {
            Write deckYAML, !
        }
        //Quit $$$OK
    } Catch ex {
        Write "Error: ", ex.DisplayString(), !
        //Quit ex.AsStatus()
    }
}

To use the method and have it generate a yaml file, just call it from a terminal session AKA IRIS CLI

Do ##class(MyUtils.APIConverter).ConvertOpenAPIXDataToDeckYAML("MyApp.spec", "/tmp/deck.yaml")

Or you can just print the yaml to console

Do ##class(MyUtils.APIConverter).ConvertOpenAPIXDataToDeckYAML("MyApp.spec")


What to Do Next

Once the YAML file is generated, you can use decK to sync it with your IAM instance:

deck gateway sync --workspace <WorkSpace> deck.yml

This will create or update services and routes in IAM based on your spec.


Final Thoughts

This method bridges the gap between spec driven development and gateway configuration. It’s ideal for teams using InterSystems IRIS or HealthShare and IAM in their architecture.

Want to extend it?

  • Include authentication plugins
  • Generate multiple services based on tags

Let me know in the comments or reach out if you'd like help customizing it!

0
2 42
Article Megumi Kakechi · Oct 2, 2025 2m read

InterSystems FAQ rubric

The ^%GCMP utility can be used to compare the contents of two globals.

For example, to compare ^test and ^test in the USER and SAMPLES namespaces, it would look like this:
*In the example below, 700 identical globals are created in the two namespaces, and the contents of one of them is changed to make it the detection target.

0
1 69
Question Eugene.Forde · Aug 31, 2025

I’ve been exploring options for connecting Google Cloud Pub/Sub with InterSystems IRIS/HealthShare, but I noticed that IRIS doesn’t seem to ship with any native inbound/outbound adapters for Pub/Sub. Out of the box, IRIS offers adapters for technologies like Kafka, HTTP, FTP, and JDBC, which are great for many use cases, but Pub/Sub appears to be missing from the list.

Has anyone here implemented such an integration successfully?

For example:

2
1 75
Article Beatrice Zorzoli · Sep 10, 2025 4m read

I joined InterSystems less than a year ago. Diving into ObjectScript and IRIS was exciting, but also full of small surprises that tripped me up at the beginning. In this article I collect the most common mistakes I, and many new colleagues, make, explain why they happen, and show concrete examples and practical fixes. My goal is to help other new developers save time and avoid the same bumps in the road.

1. Getting lost among system classes and where to start

11
2 260
Article Sanjib Pandey · Sep 26, 2025 19m read

Introduction

HL7 messages often contain multiple repeating segments such as NTE, AL1, OBX, ZTX, DG1, and others. These segments sometimes require individual processing and routing to different downstream systems. This technical paper introduces a configurable template designed to automate the splitting of these repeating HL7 segments, improving message handling and integration efficiency.

3
0 76
Question Ashok Kumar T · Sep 28, 2025

Hello Community

The InitialExpression keyword values does not to set default values for properties in classes that extend %CSP.Page, unlike in other class types such as %Persistent or %RegisteredObject, where it works as expected during object instantiation (typically via %New()).

  1. Is %CSP.Page instantiated using %New() under the hood, or does it use a different initialization mechanism?
  2. Are there specific limitations or behaviors in CSP pages that prevent InitialExpression from working as expected?

Thank you!

5
0 54
Article Robert Cemper · Sep 22, 2025 2m read

Finishing my previous example for multiple IRIS instances, I tried
to compose a local single instance version.  The step from the external
Python app to a version using embedded Python seemed to be obvious.
This was a wrong assumption, as some Python libraries just refused installation
into my local Windows-based environment.

3
2 68
Question Jochen Roese · Sep 15, 2025

Hi,

so we introduced GIT in our workflow and we exported all files with $SYSTEM.OBJ.ExportUDL

Everything fine so far. But for some reason the export adds an extra line for classes (Routines are OK as far as I can see):

On Serverside it isn't there

The Problem is now that when we checkout a branch and a class changed we automatically compile it from the repository to a namespace that is made for the developer. E.g. DEV_001, DEV_002 and so on. 

2
0 48
Article Evgeny Shvarov · Sep 3, 2025 5m read

Hi folks!

Sometimes, when designing a class method and feeding it with more and more useful features, very soon the number of parameters can reach 10 and even more.

It becomes pretty difficult for users of useful methods to remember the position of the important parameter, and it is very easy to misuse the position and transfer the wrong value to the wrong parameter.

Here is an example of such a method (I asked GPT to create a method with 20 params):

ClassMethod GenerateReportWith20Params(
    pTitle As%String = "",
    pAuthor As%String = "",
    pDate As%String = "",            // e.g. 2025-09-03
    pCompany As%String = "",
    pDepartment As%String = "",
    pVersion As%String = "1.0",
    pFormat As%String = "pdf",       // pdf|html|docx
    pIncludeCharts As%Boolean = 1,
    pIncludeSummary As%Boolean = 1,
    pIncludeAppendix As%Boolean = 0,
    pConfidentiality As%String = "Public",
    pLanguage As%String = "en",
    pReviewers As%String = "",       // CSV, e.g. "Alice,Bob"
    pApprover As%String = "",
    pLogoPath As%String = "",
    pWatermarkText As%String = "",
    pColorScheme As%String = "default",
    pPageSize As%String = "A4",
    pOrientation As%String = "Portrait",
    pOutputPath As%String = "report.pdf"
) As%Status
{

// implementation
}
0
1 70