Skip to the content.

🏠 Gofer Engine > Developing Interface Channels in OOP Style

Developing Interface Channels in OOP Style

We have strived to make developing interface channels as easy as possible. The goal is to make it so that you can create a channel in a few minutes and have it running immediately in a test environment and then deploy it to a production environment with minimal effort. The Gofer Engine class has methods to quickly and easily create and run channel configuration scripts. The default export is already an instance of the class, so you can just start using it immediately.

listen

To begin a new channel, use the listen method. This method accepts three arguments for TCP listeners:

Or two arguments for HTTP and HTTPS:

See source for typings of HTTPConfig<'I'> and HTPPSConfig<'I'>

Note: Currently only TCP, HTTP, and HTTPS listeners are supported. In a future release, there will be additional methods to listen, read, and accept messages.

// example.ts with TCP listener
import gofer,  { ChannelConfig } from '@gofer-engine/engine'

const ingest = gofer.listen('tcp', 'localhost', 5501)
// we will continue building upon this snippet
// example.ts with HTTP listener
import gofer,  { ChannelConfig } from '@gofer-engine/engine'

const ingest = gofer.listen('http', {
  host: '127.0.0.1',
  port: 8100,
  method: 'POST',
  basicAuth: {
    username: 'user',
    password: 'pass',
  },
})
// we will continue building upon this snippet
// example.ts with HTTPS listener
import gofer,  { ChannelConfig } from '@gofer-engine/engine'
import fs from 'fs'

// could use .env variables instead
const SSL_KEY = fs.readFileSync('yourpath/key.pem')
const SSL_CERT = fs.readFileSync('yourpath/cert.pem')

const ingest = gofer.listen('tcp', {
  host: '127.0.0.1',
  port: 8200,
  method: 'POST',
  basicAuth: {
    username: 'user',
    password: 'pass',
  },
  key: SSL_KEY,
  cert: SSL_CERT,
})
// we will continue building upon this snippet

The listen method returns an IngestionClass.

Back to top

IngestionClass

The IngestionClass provides the following methods:

name

Call the name method to name the channel

// definition
type name = (name: string) => IngestionClass
// example.ts (continued)
ingest.name('A Unique Channel Name')

Back to top

id

Call the id method to override the generated id given to the channel. If not provided the id will be a UUID

// definition
type id = (id: string | number) => IngestionClass
// example.ts (continued)
ingest.id(42)

Back to top

ack

Call the ack method to reply back an HL7 acknowledgment. See Acknowledge Config

// definition
type ack = (ack?: AckConfig) => IngestionClass
// example.ts (continued)
ingest.ack()

Back to top

filter

Call the filter method to filter the message. See Filter Flow for the function definition

// definition
type filter = (filter: FilterFlow<'F'>) => IngestionClass
// example.ts (continued)
ingest.filter((msg) => msg.get('MSH-9.1') === "ADT")

// alternatively you can use the long form get classes
ingest.filter((msg) => 
  msg
    .getSegment('MSH')
    .getField(9)
    .getComponent(1)
    .toString() === 'ADT'
)

Back to top

transform

Call the transform method to transform/modify the message. See Transform Flow for the function definition

// definition
type transform = (transform: TransformFlow<'F'>) = > IngestionClass
// example.ts (continued)
ingest.transform((msg) => msg.set('MSH-5'), 'Gofer')

Back to top

store

Call the store method to persist the message to a data store. See Store Config for the config definition

// definition
type store = (store: StoreConfig) => IngestionClass
// example.ts (continued)
ingest.store({ file: {} })

Back to top

setVar

Call the setVar method to set a variable value for the specific scope. The varValue can either be the value itself or a function to callback to retrieve the value from the message and context. See Variables for more information on using variables.

// definition
type setVar = <V>(scope: 'Msg' | 'Channel' | 'Global', varName: string, varValue: V | (msg: Msg, context?: IMessageContext) => V) => IngestionClass
// example.ts (continued)
ingest.setVar('Msg', 'name', 'FirstName')

// you can extract the value from the message
ingest.setVar('Channel', 'facility', (msg) => msg.get('MSH-3.1'))

// you can strictly specify the type of the value
ingest.setVar<{ bar: string }>('Global', 'foo', { bar: 'baz' })

Back to top

setMsgVar

Call the setMsgVar method to set a variable value for the Message scope. Later in this message will be able to use this variable. The varValue can either be the value itself or a function to callback to retrieve the value from the message and context. See Variables for more information on using variables.

// definition
type setMsgVar = <V>(varName: string, varValue: V | (msg: Msg, context?: IMessageContext) => V) => IngestionClass
// example.ts (continued)
ingest.setMsgVar('name', 'FirstName')

Back to top

setChannelVar

Call the setChannelVar method to set a variable value for the Channel scope. Later in this message or following messages within this same channel will be able to use this variable. The varValue can either be the value itself or a function to callback to retrieve the value from the message and context. See Variables for more information on using variables.

// definition
type setChannelVar = <V>(varName: string, varValue: V | (msg: Msg, context?: IMessageContext) => V) => IngestionClass
// example.ts (continued)
ingest.setChannelVar('facility', msg => msg.get('MSH-3.1'))

Back to top

setGlobalVar

Call the setGlobalVar method to set a variable value for the Global scope. Anywhere later in current or following messages within this same server will be able to use this variable. The varValue can either be the value itself or a function to callback to retrieve the value from the message and context. See Variables for more information on using variables.

// definition
type setGlobalVar = <V>(varName: string, varValue: V | (msg: Msg, context?: IMessageContext) => V) => IngestionClass
// example.ts (continued)
ingest.setGlobalVar('foo', { bar: 'baz' })

Back to top

getVar

Call the getVar method to get a previously set variable for the given scope by name. Define the callback function (cb) to do something with the value of the variable. You can use the value to filter or transform the message, or do something with the MessageContext.

// definition
type getVar = <V>(scope: 'Msg' | 'Channel' | 'Global', varName: string, cb: (val: V | undefined, msg: Msg, context: IMessageContext) => void | Msg | boolean) => IngestionClass
// example.ts (continued)
ingest.getVar('Msg', 'name', (name) => console.log(name))

Back to top

getMsgVar

Call the getMsgVar method to get a previously set variable for the Msg scope.

For example, you can use the value to transform the message

// definition
type getMsgVar = <V>(varName: string, cb: (val: V | undefined, msg: Msg, context: IMessageContext) => void | Msg | boolean) => IngestionClass
// example.ts (continued)
ingest.getMsgVar<string>('name', (name, msg) => msg.set('PID-5.2', name))

Back to top

getChannelVar

Call the getChannelVar method to get a previously set variable for the Channel scope.

For example, you can use the value and the context to log a message

// definition
type getChannelVar = <V>(varName: string, cb: (val: V | undefined, msg: Msg, context: IMessageContext) => void | Msg | boolean) => IngestionClass
// example.ts (continued)
ingest.getChannelVar<string>('facility', (facility, _, { logger }) => {
  logger(`Received message from ${facility}`, 'info')
})

Back to top

getGlobalVar

Call the getGlobalVar method to get a previously set variable for the Channel scope

For example, you can use the value and filter the message by returning false

// definition
type getGlobalVar = <V>(varName: string, cb: (val: V | undefined, msg: Msg, context: IMessageContext) => void | Msg | boolean) => IngestionClass
// example.ts (continued)
ingest.getGlobalVar<{ bar: string }>('foo', ({ bar }) => bar === 'foo')

Back to top

route

Call the route method to route the message to a single destination. This method returns an instance of CompleteClass.

The argument to the route is a function that provides an instance of RouteClass and must return an instance of RouteClass. See RouteClass for the available methods.

// definition
type route = (route: (route: RouteClass) => RouteClass) => CompleteClass
// example.ts (continued)
const comp = ingest.route(route => route.send('tcp', 'localhost', 5502))

Back to top

routes

Call the routes method to route the message to multiple routes. This method returns an instance of CompleteClass.

The argument to the routes is a function that provides a getter of an instance of a RouteClass and must return an array of instances of RouteClasses. This allows multiple routes to be initiated from a single-getter function. See RouteClass for the available methods.

Notice that each array begins by calling the route function. This is different from the single route method above.

// definition
type routes = (routes: (route: () => RouteClass) => RouteClass[]) => CompleteClass
// example.ts (continued)
const comp = ingest.routes(route => [
  // first route
  route().send('tcp', 'localhost', 5502),
  // second route
  route().transform(msg => msg.addSegment('ZZZ|1|GoferEngine')).send('tcp', 'localhost', 5503),
  // third route
  route().getChannelVar<string>('facility', (facility) => facility === 'FACILITY_3').send('tcp', 'localhost', 5504),
])

Back to top

RouteClass

The RouteClass has all of the above methods of the IngestionClass excluding ack, route, and routes. The setVar and getVar have the additional scope "Route", and the RouteClass has these additional methods:

setRouteVar

Call the setRouteVar method to set a variable within the scope of the current route.

// definition
type setRouteVar = <V>(varName: string, varValue: V | (msg: Msg, context?: IMessageContext) => V) => RouteClass
// example.ts (continued)
route.setRouteVar('example', 'test')

Back to top

getRouteVar

Call the getRouteVar method to get a variable within the scope of the current route.

// definition
type getRouteVar = <V>(varName: string, cb: (val: V, msg: Msg, context: IMessageContext) => void | Msg | boolean) => RouteClass
// example.ts (continued)
route.getRouteVar('example', (test) => console.log(test))

Back to top

send

Call the send method to get a variable within the scope of the current route.

// definition
type send = (method: 'tcp', host: string, port: number) => RouteClass
// example.ts (continued)
route.send('tcp', 'localhost', 5505)

NOTE: Currently only TCP clients are supported. In a future release, there will be additional methods to senders, writers, and callback messages.

Back to top

CompleteClass

The CompleteClass is returned by both the route and routes methods of the IngestionClass. This class currently has the following methods:

run

Call the run method to start the channel on the server. This method does not support any arguments

// example.ts (continued)
comp.run()

Back to top

export

Call the export method to export the ChannelConfig JSON script created. This method does not support any arguments

// example.ts (continued)
comp.export()

Back to top

msg

(FUTURE) Call the msg method to define a callback function to call for at the end of each route.

NOTE: This will be used in a future release with non listening channel configs, such as a message pass-through or one-time file read

// definition
type msg = (callback: (msg: Msg, context: IMessageContext) => void) => void
// example.ts (continued)
let msg: string | undefined
comp.msg((m) => {
  msg = m.toString()
})

Back to top