Controlling Database Objects from Node.js
The Native SDK works together with InterSystems External Servers, allowing your external Node.js application to control instances of database classes written in either ObjectScript or Embedded Python. Native SDK inverse proxy objects can use External Server connections to create a target database object, call the target’s instance methods, and get or set property values as easily as if the target were a native Node.js object.
This section covers the following topics:
-
Introducing the Node.js External Server — provides a brief overview of External Servers.
-
Creating Node.js Inverse Proxy Objects — describes methods used to create inverse proxy objects.
-
Controlling Database Objects with IRISObject — demonstrates how inverse proxy objects are used.
Introducing the Node.js External Server
The Node.js External Server allows InterSystems IRIS embedded language objects and Node.js Native SDK objects to interact freely, using the same connection and working together in the same context (database, session, and transaction). External Server architecture is described in detail in Using InterSystems External Servers, but for the purposes of this discussion you can think of it as a simple black box connecting proxy objects on one side to target objects on the other:
As the diagram shows, a forward proxy is a database object that controls an external Node.js target object. The corresponding Native SDK object is an inverse proxy that controls a database target object from an external Node.js application, inverting the normal flow of control.
Creating Node.js Inverse Proxy Objects
You can create an inverse proxy object by obtaining the OREF of a database class instance (for example, by calling the %New() method of an ObjectScript class). The Iris.classMethodObject() method will return an IRISObject instance if the call obtains a valid OREF. The following example uses Iris.classMethodObject() to create an inverse proxy object:
var proxy = irisjs.classMethodObject("User.TestInverse","%New");
-
classMethodObject() calls the %New() method of an ObjectScript class named User.TestInverse
-
The call to %New() creates a database instance of User.TestInverse.
-
classMethodObject() returns inverse proxy object proxy, which is an instance of IRISObject mapped to the database instance.
This example assumes that irisjs is a connected instance of Iris (see “Creating a Connection in Node.js”). See “Calling Class Methods from Node.js” for more information on how to call class methods.
The following section demonstrates how proxy can be used to access methods and properties of the ObjectScript User.TestInverse instance.
Controlling Database Objects with IRISObject
The iris.IRISObject class provides several methods to control the database target object: invoke() and invokeVoid() call an instance method with or without a return value, and accessors get() and set() get and set a property value. .
This example uses an ObjectScript class named User.TestInverse, which includes declarations for methods initialize() and add(), and property name:
Class User.TestInverse Extends %Persistent {
Method initialize(initialVal As %String = "no name") {
set ..name = initialVal
return 0
}
Method add(val1 As %Integer, val2 As %Integer) As %Integer {
return val1 + val2
}
Property name As %String;
}
The first line of the following example creates a new instance of User.TestInverse and returns inverse proxy object proxy, which is mapped to the database instance. The rest of the code uses proxy to access the target instance. Assume that a connected instance of IRIS named irisjs already exists (see “Creating a Connection in Node.js”).
// Create an instance of User.TestInverse and return an inverse proxy object for it
var proxy = irisjs.classMethodObject("User.TestInverse","%New");
// instance method proxy.initialize() is called with one argument, returning nothing.
proxy.invokeVoid('initialize', 'George');
console.log("Current name is "+ proxy.get("name")); // display the initialized property value
// instance method proxy.add() is called with two arguments, returning an int value.
console.log("Sum of 2 plus 3 is " + proxy.invoke("add",2,3));
// The value of property proxy.name is displayed, changed, and displayed again.
proxy.set("name", "Einstein, Albert"); // sets the property to "Einstein, Albert"
console.log("New name is "+ proxy.get("name")); // display the new property value
This example uses the following methods to access methods and properties of the User.TestInverse instance:
-
IRISObject.invokeVoid() invokes the initialize() instance method, which initializes a property but does not return a value.
-
IRISObject.invoke() invokes instance method add(), which accepts two integer arguments and returns the sum as an integer.
-
IRISObject.set() sets the name property to a new value.
-
IRISObject.get() returns the value of property name.
This example used the variant get(), and invoke() methods, but the IRISObject class also provides datatype-specific Typecast Methods for supported datatypes:
In addition to the variant get() method, IRISObject provides the following IRISObject.get() typecast methods: getBytes(), getDecimal() getFloat() getInteger(), getString(), getIRISList(), and getObject().
In addition to invoke() and invokeVoid(), IRISObject provides the following IRISObject.invoke() typecast methods: invokeBytes(), invokeDecimal(), invokeInteger(), invokeString(), invokeIRISList(), and invokeObject().
All of the invoke() methods take a string argument for methodName plus 0 or more method arguments. The arguments may be either Node.js objects, or values of supported datatypes. Database proxies will be generated for arguments that are not supported types.
invoke() can only call instance methods of an IRISObject instance. See “Calling Database Methods and Functions from Node.js” for information on how to call class methods.