Article
· Nov 2 7m read

Interoperability Naming Convention (IRIS Project Organization Guide)

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.

 

Disclaimer: This guide is a good fit for Interoperability projects. When you have integrations, data flows, when you use IRIS for ETL processes, etc. Overall, when your code is combined with Productions. If you are using the IRIS Data Platform just as a backend, for example, the project structure can be different, of course.

General naming rules

Follow these naming rules always when it is possible:

  • For names of packages and classes, we use the UpperCamelCase
  • The package name must be in the singular form. Exception: when the names of packages are generated automatically (by importing WSDL or XSD, for example) 

          🚫 Incorrect: Messages     ✅ Correct: Message 

          🚫 Incorrect: Processes     ✅ Correct: Process

  • Abbreviation for the package name is possible. Sample: InterSystemsCorporation = ISC
  • Production item name must be the same as the class name. Exception: when we have a few Production items with different settings based on one class. In this case, I advise you to add .Type (some delimiter) at the end of the business host name. For example, we have a class  MyProject.Operation.API and two business hosts use this class: MyProject.Operation.API.Node01 and MyProject.Operation.API.Node02
  • Do not repeat the package name in the class name

          🚫 Incorrect: MyProject.Operation.EmailOperation     ✅ Correct: MyProject.Operation.EmailAlert

  • Only one domain in the full class name (see details below)

          🚫 Incorrect: ISC.Alert.Operation.EmailNotifier     ✅ Correct: ISC.Operation.EmailNotifier

Levels of project structure

Let's look at our subject from the upper level to the project depths. The structure of modules will be as follows: src > Domains > Class Types > Class Files. Next, more details about each level.

0️⃣ Zero level (project root)

 

On this level, we have: 

  • .vscode directory with settings.json inside (created automatically by Visual Studio Code)
  • src folder - all your custom code must be here 
  • .gitignore file, my default looks like:
.vscode
fields.md
.DS_Store
  • Docker files, if you use Docker for deployment
  • Optionally: LICENSE, README.md, and also more deployment-related things 

1️⃣ Level one (domains)

All the following files and folders must be inside src. It's the level of domains, the biggest piece of your code separation. Any complex project on IRIS has many integrated applications and sub-projects combined in a single namespace (within a single Production). At this level can be located only folders (packages) called by companies, projects, sub-modules, or connected systems. It can be folders like: ERP, Kafka, Alert, FHIR, SampleProjectISC. No classes allowed here.

The choice of domain delimiter at the top level is up to you. It depends on your specific needs. A good idea is to use the company's name if you're creating custom code in a typical InterSystems solution. Or use the connected application name if it's an integration project, especially if you have many integrated applications.

In the screenshot below, you can see how sub-module names are used as a level one delimiter. This delimiter was selected because its independent modules, Alert (alerting sub-system) and Broker (message broker), can be used separately. Of course, here could be used a structure like ESB > Alert > ... and ESB > Broker > ... with a common package ESB. But it's against the important principle of this convention: only one domain level. No nested domains allowed.

Also, here is the place for the package with the name Production. In this package must be located your production class uses a fixed name - Main.cls. We are using a folder on the first level, because Production is a common item for all projects, modules, and all what we have in the namespace.

 

You can add more production classes to this package if you are using environment settings separation by production classes (check this discussion), such as Dev.cls, Test.cls, and so on.

2️⃣ Level two (packages by class types)

This is the level of separation by class types. No classes allowed here. This inner folder list will be almost the same for each domain/project folder. Of course, it will depend on your task-specific needs, and you can add suitable only for you packages to this level (don't forget to follow general naming rules). I prepared a list of typical package names that I use at this level.

A few regular packages, common to all projects:

  • 📦 Adapter - package for adapter classes. I am not splitting it into inbound and outbound adapters because, usually, projects do not contain a lot of adapters
  • 📦 Service - your classes, which extend Ens.BusinessService. No folders allowed here, just a list of classes
  • 📦 Message - a package for messages, typically children of Ens.Request and Ens.Response. There can be many nesting levels here. Usually, I use the following structure: Message > Application > Type > Root.cls. Good practice to create message-related classes by XSD import
  • 📦 Process - classes which extend Ens.BusinessProcess. No folders allowed inside
  • 📦 Operation - classes which extend Ens.BusinessOperation. No folders allowed inside
  • 📦 Storage - a place for storing persistent data. It is the classes that extend the %Persistent type. If you need to store some data, you can create your tables here. No folders allowed inside
  • 📦 Transform - transformation classes (extend Ens.DataTransform). All format or protocol-related transformations, also called mappings, must be stored here (SomeJson2SomeXML.cls for example). No folders allowed inside
  • 📦 UnitTest - list of test cases (classes that extend  %UnitTest.TestCase)

And more project-related packages:

  • 📦 WebClient - SOAP clients folder. You must import each client into a new folder, like WebClient > MyCustomClient. Can be a few nested folders automatically created by WSDL import here
  • 📦 API - if you publish REST APIs on the IRIS side. Also, possible nested folders. Sample: API > MyCustomREST - inside this folder, your disp, impl, and spec classes will be located. These classes are generated when we use a specification-first way for API creation. More details about it can be found here
  • 📦 Task - if you use task classes (extend %SYS.Task.Definition). No folders allowed inside
  • 📦 CSP - if you use Cache Server Pages for creating some UI

3️⃣ Level three (single classes)

Level of single classes (.cls files). As explained above, most of your class files must be located on the third level. Try to avoid creating folders here. Actually, this convention does not create a deeply nested structure. And it is true with a few exceptions, like 📦 Message, 📦 WebClient, and 📦 API folders. Mostly because in these cases, we use code generation for creating a folder structure.

 

Benefits

  • Easy to find related classes when you have only a generic problem understanding. For example, the issue sounds like "We have a problem with putting data into Kafka". You can be sure that related classes are located in the package Kafka.Operation.*, because we talk about a specific application (Kafka), and the outbound data flow direction (Operation)
  • You can create any automated processing for business hosts based only on their names. The expression $p(item.ClassName, ".", 2) is always equal to a type of class - Service, Process, Operation, etc.
  • The convention about business host names in Production allows us to quickly find related classes and effectively manage huge Interoperability Productions
  • It's a simple concept for new developers. A similar structure is used in some system packages

Conclusion

Generally, that is all that I want to tell you about my Project Organization Guide. Of course, in addition to the project structure rules, I also have a Code Style Guide with typical patterns and many other details. But let it go next time. A detailed sample of using this convention can be found in the IRIS ESB project. It would be great if someone else could share: what naming convention are you using for packages and class organization?

Discussion (4)3
Log in or sign up to continue