0 Followers · 433 Posts

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write.

Article Heloisa Paiva · Mar 15, 2024 5m read

Introduction

In the next few weeks, my coworkers are planning to start using VSCode to code with InterSystems' products. Among the many advantages of that, I would emphasize being able to connect with other technologies, such as GitHub, with ease. Besides, VSCode also offers an extensive extensions store, where you can find many free add-ons that make coding faster and more efficient. Last but not least, to conquer the heart of every developer, it is open source.

With that being said, let's start the tutorial. Feel free to skip some steps if you're comfortable doing them alone.

2
2 914
Question Ali Chaib · Mar 13, 2024

Dear,

I'm trying to configure a new interface that reads HL7, transform them into FHIR messages and then send POST or PUT or DELETE depending on HL7 doc type.

1-I added an HL7 TCP service that reads ADTs messages

2a-Send ADTs to a process to transform them into SDA  (using the following command:  do ##class(HS.Gateway.HL7.HL7ToSDA3).GetSDA(request,.con))

2b-Extract the patient MRN and add it to the AdditionalInfo property  (using the following request message class: HS.Message.XMLMessage)

3-Send the SDA message to the built in process: HS.FHIR.DTL.Util.HC.SDA3.FHIR.Process.

5
0 262
Article Vadim Aniskin · Mar 13, 2024 4m read

JSON is a lightweight data interchange format for representing and exchanging data between a server and a web application. Its popularity has led to its widespread use in applications based on InterSystems technology, as well as demand for a converter that transforms globals to JSON and back. Therefore, @Evgeny Shvarov suggested developing Global->JSON->Global converter. Implementing such a converter is important to ensure interoperability, simplify data exchange, support web services, and provide a standardized approach to data representation across different software ecosystems. This article, the second in the "Implemented Ideas" series, focuses on several projects created by the legend of InterSystems Developer Community @Robert Cemper that deal with this task:

   

1
2 329
Article Alberto Fuentes · Mar 4, 2024 2m read

I would like to share with you a little trick to customize how messages are displayed in the Message Viewer. In particular, how you can display messages as JSON (instead of the default XML representation).

image

Messages are objects that are used to communicate interoperability productions components. In my example I have defined a message that later I serialize as JSON to send to an external API. This message is defined as a regular message and also as a %JSON.Adaptor so I can export / import directly to or from JSON.

Class interop.msg.DeviceOrderReq Extends (Ens.Request, %JSON.Adaptor)
{

Parameter %JSONNULL As BOOLEAN = 1;

Property externalOrderId As %String(MAXLEN = "");

Property orderStatus As %String;

Property requestedServiceId As %String(MAXLEN = "");

Property patientData As interop.msg.elements.PatientData;

}

This message is working fine when I run different tests in my interoperability production. However in the Message Viewer it is displayed as an XML (this is the default representation).

image

This representation is fine, but in this case it would be much more intuitive for me being able to see the contents as JSON. Luckily, you can override the %ShowContents method in the message.

In my case, I've created a class called JSONMessage (so I can later re-use that). This class overrides the %ShowContents method to display the message as a formatted JSON.

Class interop.msg.JSONMessage Extends (Ens.Request, %JSON.Adaptor)
{

/// This method is called by the Management Portal to determine the content type that will be returned by the <method>%ShowContents</method> method.
/// The return value is a string containing an HTTP content type.
Method %GetContentType() As %String
{
	Quit "text/html"
}

/// This method is called by the Management Portal to display a message-specific content viewer.<br>
/// This method displays its content by writing out to the current device.
/// The content should match the type returned by the <method>%GetContentType</method> method.<br>
Method %ShowContents(pZenOutput As %Boolean = 0)
{
   do ..%JSONExportToString(.jsonExport)
    set formatter = ##class(%JSON.Formatter).%New()
    do formatter.FormatToString(jsonExport, .json)
    &html<<pre>#(json)#</pre>>
}

}

Finally, you only need to change the original message so it extends from JSONMessage:

Class interop.msg.DeviceOrderReq Extends (JSONMessage, Ens.Request)
{

Parameter %JSONNULL As BOOLEAN = 1;

Property externalOrderId As %String(MAXLEN = "");

Property orderStatus As %String;

Property requestedServiceId As %String(MAXLEN = "");

Property patientData As interop.msg.elements.PatientData;

}
2
4 511
Question Lowell Buschert · Feb 25, 2024

I am sending an httpRequest from ObjectScript to a python server.   I am not receiving a response in OS
 
OS config On the client side

// Create an HTTP request object
    Set httpRequest = ##class(%Net.HttpRequest).%New()
    
    // Set the server URL
    Set httpRequest.Server = "http://127.0.0.1:8080"
    
    // Set content type to JSON
    Set httpRequest.ContentType = "application/json"

5
0 251
Question Sinon Galvin · Feb 9, 2024

I save / compile a class and instantly run a debug.  No issue

A few seconds later, try to run the same debug and get presented with either: 

1) Target Source is not compiled (Open launch json) dialog box

                                                    OR

2) The version of the file on the server is newer.

In the meantime I have made no edits to the VS Code window at all. 

5
0 255
Question Eyal Levin · Feb 25, 2024

Hi,

I have a scenario where I recognize that I have a duplicate patient in FHIR , both have a different set of data attached to them (Specimens / Observations / Conditions) and I want to transfer all the data from patient X to patient Y,  and maybe mark patient X as not relevant or delete it IDK yet.

since Patch currently supports only single patch,

"The Conditional Patch query identified more than one resource."

I can't use it as a bulk, but I need to loop through all the resources I find that are connected to patient X,

so I guess my question is how would you do it?

5
0 332
Article Dan Pasco · Feb 22, 2024 4m read

There is an interesting new feature in the recently announced 2024.1 preview, JSON_TABLE. JSON_TABLE is one of a family of functions introduced by the 2016 version of the SQL Standard (ISO Standard, published in early 2017). It allows for JSON values to be mapped to columns and queried using SQL. JSON_TABLE is valid in the FROM clause of some SQL statements.

The syntax of JSON_TABLE is quite large, allowing for exceptional conditions where the provided JSON values don't match expectations, nested structures and so on.

The basic syntax is quite straightforward. The first argument passed to the JSON_TABLE is the JSON value that is to be queried. It can be a literal, a column reference, or a function call. The second argument is a JPL (JSON path language) expression that allows for filtering the provided value. Then comes the COLUMNS clause - right in the middle of a function call. The COLUMNS clause looks very much like the columns definitions in a CREATE TABLE statement but with one very necessary addition - the PATH. PATH is a JPL expression that is applied to the JSON value to produce the column value.

This is an example just to demonstrate a simple mapping.

SELECT * 
    FROM JSON_TABLE('[{"name":"New York","capital":"Albany"},{"name":"Wyoming","capital":"Cheyenne"}]', '$'COLUMNS(
                state_name VARCHAR(40) PATH'$.name',
                capital_name VARCHAR(40) PATH'$.capital'
            )
        ) as s

 

state_namecapital_name
New YorkAlbany
WyomingCheyenne

2 Rows(s) Affected

JSON_TABLE also allows for a column to provide the JSON value. This value can then be joined back to its containing row using something called a lateral join. This example creates a simple table and populates it with a few rows with interesting values.

DROPTABLE demo_intersystems.Person;

CREATETABLE demo_intersystems.Person (
                                          nameVARCHAR(40),
                                          street VARCHAR(60),
                                          city VARCHAR(30),
                                          state VARCHAR(4),
                                          postal_code VARCHAR(10),
                                          phone_nbrs VARCHAR(2000)
);

INSERTINTO demo_intersystems.Person (name, street, city, state, postal_code, phone_nbrs)
    VALUES (
        'Caroline',
        'One Memorial',
        'Cambridge',
        'MA', '02142',
        '[{"type":"office","number":"(617) 225-5555"},{"type":"mobile","number":"(617) 555-1111"}]'
    );

INSERTINTO demo_intersystems.Person (name, street, city, state, postal_code, phone_nbrs)
    VALUES (
        'Doe, John',
        '123 Main Street',
        'Cambridge',
        'MA',
        '02142',
        '[{"type":"mobile","country_code":"1","number":"999-999-9999"},{"type":"work","country_code":"1","number":"888-888-8888"}]'
    );

INSERTINTO demo_intersystems.Person (name, street, city, state, postal_code, phone_nbrs)
VALUES (
    'Smith, Georgia',
    '100 Privet Lane, Unit 20',
    'Melrose',
    'MA',
    '02176',
    '[{"type":"mobile","country_code":"1","number":"555-867-5309"},{"type":"home","country_code":"1","number":"555-123-1234"},{"type":"office","number":"555-000-0000"}]'
    );

INSERTINTO demo_intersystems.Person (name, street, city, state, postal_code, phone_nbrs)
VALUES (
    'Jones, Thomas',
    '63 North Park Way',
    'Princeton',
    'NJ',
    '08540',
    '[{"type":"mobile","country_code":"1","number":"555-555-5555"},{"type":"work","country_code":"1","number":"555-BR5-4949"}]'
    );

SELECT p.%ID, p.name, p.street, p.city, p.state, p.postal_code,
    pn.phone_type, pn.country_code, pn.phone_nbr
FROM demo_intersystems.Person p,
    JSON_TABLE(p.phone_nbrs, '$'COLUMNS(
    phone_type VARCHAR(10) path'$.type',
    country_code VARCHAR(8) path'$."country_code"',
    phone_nbr VARCHAR(12) path'$.number'
    )
    ) pn;

 

| ID | name | street | city | state | postal_code | phone_type | country_code | phone_nbr | | -- | -- | -- | -- | -- | -- | -- | -- | -- | | 1 | Caroline | One Memorial | Cambridge | MA | 02142 | office | | (617) 225-5555 | | 1 | Caroline | One Memorial | Cambridge | MA | 02142 | mobile | | (617) 555-1111 | | 2 | Doe, John | 123 Main Street | Cambridge | MA | 02142 | mobile | 1 | 999-999-9999 | | 2 | Doe, John | 123 Main Street | Cambridge | MA | 02142 | work | 1 | 888-888-8888 | | 3 | Smith, Georgia | 100 Privet Lane, Unit 20 | Melrose | MA | 02176 | mobile | 1 | 555-867-5309 | | 3 | Smith, Georgia | 100 Privet Lane, Unit 20 | Melrose | MA | 02176 | home | 1 | 555-123-1234 | | 3 | Smith, Georgia | 100 Privet Lane, Unit 20 | Melrose | MA | 02176 | office | | 555-000-0000 | | 4 | Jones, Thomas | 63 North Park Way | Princeton | NJ | 08540 | mobile | 1 | 555-555-5555 | | 4 | Jones, Thomas | 63 North Park Way | Princeton | NJ | 08540 | work | 1 | 555-BR5-4949 |

9 Rows(s) Affected

4
3 516
Question Kurro Lopez · Feb 8, 2024

Hi all,

We have a class response inherited from %JSON.Adaptor with the following properties, also dependent classes:

 

Kurro.app.Msg.Search.Response

3
0 208
Question Kurro Lopez · Feb 7, 2024

Hi community.

Yes, I know that there is other question "VS Code - debugging doesn't work" that is the same issue, but my IRIS instance is not using IIS.

Some times ago, I could debug without problems, but after some updates of Visual Studio, I get the following error

Failed to start the debug session. Check that the Intersystems server's web server supports WebSockets

I've activated the WebSocket protocol in the server (Windows Server 2019) but it still doesn't work.

The IRIS instance is not using IIS, I think it is using the Apache by default.

Do I need to do anything in special?

3
0 257
Article Sylvain Guilbaud · Feb 1, 2024 5m read

Hello Community,

SQL language remains the most practical way to retrieve information stored in a database.

The JSON format is very often used in data exchange.

It is therefore common to seek to obtain data in JSON format from SQL queries.

Below you will find simple examples that can help you meet this need using ObjectScript and Python code.

ObjectScript : using Dynamic SQL with %SQL.StatementJSON structures with %DynamicObject and %DynamicArray

1
4 518
Article Oliver Wilms · Feb 3, 2024 2m read

The architect of the JSON schema (MS) asked if IRIS could  perform schema validation. I asked on Discord objectscript channel how we could validate a Dynamic Object against a JSON schema. Dmitry Maslennikov replied that probably the easiest way would be to use python, but it would require converting ObjectScript JSON to Python dict.

I refer to this as my first real use case for Embedded Python, because previous examples I had tried I could have implemented in ObjectScript just as easily as in Python.

0
1 269
Question Nicki Vallentgoed · Jan 24, 2024

I receive JSON from a webservice and parse it to an object:

Set wout=0set stream=##class(%Stream.TmpCharacter).%New()
For {
	Quit:(httprequest.HttpResponse.Data.AtEnd || wout)
	d stream.Write(httprequest.HttpResponse.Data.Read(32000,.tSC))
}
Set jsonob={}.%FromJSON(stream)

jsonob contains a sub entity "pdf" which is a base64 string and %GetTypeOf() tells me it is a string.
However I am unable to read the nested jsonob.pdf into a stream or anything else as any attempt to use it result in a MAXLEN error.

9
1 616
Article Oliver Wilms · Jan 31, 2024 2m read

An App that converts HL7 messages to JSON objects. About a year ago I started a GitHub repo for collecting stuff related to HL7. Recently my team added an HL7 interface to our Interoperability Production and we were asked to persist HL7 messages. We created a Kafka topic to receive HL7 messages. We use Kafka Bridges to send messages to Kafka topics. Kafka messages are sent to the Kafka Bridge in JSON format.

0
0 232
Question Kevin B Lavallee · Sep 30, 2022

Hello,

I am trying to use the %ToJSON method on my dynamic object, calling it with a "DO" and not passing in outstrm parameter.

We are trying to avoid MAXSTRING errors that we get with some of our abnormally large messages.  In order to do this, I am trying to update my code to not call the socket's "Write" method after converting the dynamic object to a JSON string using the %ToString method's output.  Per the documentation on the %ToJSON method:
    If outstrm is not specified and the method is called via DO, the JSON string is written to the current output device

10
0 415
Question Oliver Wilms · Jan 11, 2024

Hello, I tried to convert HL7 message to JSON in a business process and I got errors. Has anybody converted HL7 to JSON? Are certain characters not allowed in JSON?

I just tried to set a property to quote request.RAWContent and quote. I will try to put example in GitHub and share here later.

5
0 1156
Question Emil Odobasic · Dec 14, 2023

Hello everyone!
I have to build a REST service that receives a POST HTTP-request, collect a file from that request in the Form data and then send it in another HTTP Post request through Form Data. However I can't really seem to send the file, and I do not know where it has gone wrong. All I am getting told is that no file is being received from my HTTP Post request. I am reaching the REST Service I am supposed to send the request to, but nothing is being sent.
I would be really thankful if someone could give some insight why nothing is being sent in my request. Thanks beforehand! :)

6
0 922
Question David Hickman · Dec 12, 2023

I'm receiving a JSON payload via a REST API, I'd like to %JSONImport this stream into a class which extends %JSON.Adaptor. The problem is that the JSON is an array whose elements have no key (as you can see in the example JSON below). Right now I'm having to do some manipulations to convert the stream into a dynamic object and do a %Set which inserts a made up key "record" so "thingone" and "thingtwo" have an associated key that I can use when referencing "thingone" and "thingtwo"...such as record.GetAt(1).thingone

3
0 345
Question Sapan Parikh · Dec 5, 2023

What changes are to be made while customizing a FHIR server package when adding a new field. As provided in the documentation, we have a sample JSON package of favorite color and it is added in the table, but when we are adding a new field 'Insurance', it does not imports the package and says package already exists. We have three files of JSON 

1) Package.JSON

2) SearchParameter.JSON

3) StructureDefination.JSON 

What should we have to change for adding new field.

2
0 231
Announcement Ronnie Hershkovitz · Nov 19, 2023

Hi Community,

We're pleased to invite you to the upcoming webinar in Hebrew: 

👉Advanced JSON & DocDB👈

📅 Date & time: November 29th, 3:00 PM IDT

JSON has become the leading language in interfaces in recent years. 

In this Webinar we will learn about the use of JSON Adapter and its mappings,

How to convert information from SQL to JSON in a single command, 

And how can information be saved as raw JSON without saving as an object in DocDB.

 Presenter:

@Keren Skubach, Senior Sales Engineer, InterSystems 

 ➡ Register today! 

1
0 309
Question Yone Moreno · Nov 28, 2023

Hello,

First of all thanks for your help, time, and answers.

We would like to know what are we doing wrong and how could we improve it and fix it.

We need to convert the Api Monitor Metrics which are a String with this format:

iris_cache_efficiency 13449.122
iris_cpu_pct{id="CSPDMN"} 0
iris_cpu_pct{id="ECPWorker"} 0

[...]

iris_wdwij_time 11
iris_wd_write_time 8
iris_wij_writes_per_sec 0

To JSON.

We would expect them to look like a normal JSON as follows:

{
"iris_cache_efficiency": "13449.122",
"iris_cpu_pct{id='CSPDMN'}": "0",

[...]
"iris_wij_writes_per_sec": 0
}

4
1 228
Article Zacchaeus Chok · Nov 28, 2023 3m read

Overview

In our previous post, we discussed the motivation for developing a chatbot agent with access to FHIR resources. In this post, we will dive into the high-level design aspects of integrating a Streamlit-based chat interface with a Java SpringBoot backend, and enabling a LangChain agent with access to FHIR (Fast Healthcare Interoperability Resources) via APIs.


1
0 356
Article Niels Genne · Nov 24, 2023 4m read

How can IRIS productions be deployed more quickly and with greater peace of mind?

The aim of interoperability productions is to enable you to connect systems in order to transform and route messages between them. To connect systems, you develop, configure, deploy and manage productions that integrate several software systems.

That’s what the InterSystems documentation on its reference website tells us, but what do you actually have to do to deploy a production ?

Go for it !

Productions can be composed to connect external systems to the IRIS Data Platform. To do this, it is necessary to create an environment specific to each production, including the following components :

  • a Business service 📨
  • a Business process (optional) 📘
  • a Business operation 💉
  • table definition schemas (.cls; classes) 📅
  • a namespace initialization file (.cpf) 📋

Of course, the importance of using productions to process messages lies in the fact that each message can be traced back to any undesirable events.

And what if I told you that you could deploy your productions using our IRIS interoperability framework with the wave of a magic wand ?🪄

Wait, what?

Explanations

The mainframe approach on which our framework is based means that IRIS InterSystems® productions can be deployed at high speed, without having to recreate all the components manually.

The use of the framework allows us to add an interesting feature that enables data to be read from the tables to be deployed with the production : the addition of an outgoing API (RestForms2) !

Sounds good :)

➡️ Data can be queried and returned in JSON format.

The framework will generate all the components based on a functional specification file filled out in agreement with the business and our project manager (whose role is to ensure that all the necessary information finds its place).

The script works in two stages : building the ETL flow and the data drop point. 📦🪂

Once filled in as required, the functional specifications file is used firstly to generate the message serialization file (data classes; obj.py), the data structure file for each message (msg.py), the message generation file (bs.py) and the message ingestion file for the corresponding database (bo.py); secondly it creates or deletes tables (if exist) in the database in the form of a SQL script with DDL (Data Definition Language) instructions.

A real time-saver ! ⌚

And best of all, the framework can be easily deployed from a Docker container ! 🐳

Xssshhh

Interests

Still not convinced ? How would using this framework can save 80% of your time?⏱️

What if I told you that the code deployed by the framework is validated by the InterSystems® editor, that it enables your team to work on standardized code, that during maintenance campaigns this possibility encourages you to be more efficient when updating code or looking for bugs, that it enables you to interact with your data using a REST API mechanism (available from the repository of InterSystems IRIS-compatible packages for all versions). Does it make sense for you ?👌

What do we mean by “the code is validated by the editor”?✅ Simply that it respects Python standards and those of the editor in terms of architecture, calls to internal IRIS InterSystems® mechanisms, and can interface with the ObjectScript language and vice versa.

Bye ObjectScript

Next

If this article resonates with your needs, or if you’re simply curious to see how this framework could revolutionize the way you work with IRIS InterSystems®: please visit our website and/or ask for join our Discord Server to speak to one of our experts.

Follow us also on our LinkedIn profile profile.

In the next issue, you’ll see a case study of the framework in an operational environment 😉 !

1
0 319