Instructions

Introduction

Most applications consist of a few basic steps. First, input is received and validated. Then the input is manipulated, stored, or used to retrieve other data. Finally, some sort of response is generated. This pattern holds true for server applications, desktop applications, and mobile applications. It holds true for applications running on mobile devices, mainframes, and super computers. Since this is pattern is so strong in the software industry, why do engineers and programmers need to create this pattern over and over each time a new applicaiton, or portion of an application, is needed? QCNode, and other versions of QC, implement this pattern for you and do it in such a way that is flexible, small, and secure. When QCNode is used to create your application, your validation code is always called before any access to data is granted. This security is built in to QCNode.

Only if the validation passes is your data manipulation, retrieval, or storage code called. This is then followed by your response generation code. QCNode always executes your code in this order. You never need to worry that you forgot to make a call to validation, data, or response code.

In addition to being a great starting point for your application, QCNode makes it simple for you to create modular applications. Gone are 'spaghetti code' applications. Each application you create is composed of simple, easily reusable modules known as Control Functions. These Control Functions come in the three 'flavors' you would expect. Validation Control Functions (ValCF's), Data Control Functions (DCF's), and View Control Functions (VCF's).

In QCNode each of these Control Functions is run asynchronously so that further requests for execution are not blocked. Yet with QCNode there is no need to write callback functions. The QCNode framework already contains the needed callback functions and will ensure that the next Control Function in your application is called. While there are other libraries that do something similar, none of them have the ease of use, flexibility, and power that comes with understanding and using QCNode.

Adding QCNode to an Application

In order to use QCNode in your application all you need to do is require two files. This is done like this:

var qc = require('./QuickConnectNode.js')
var funcs = require('./functions.js')

You can then make all of the calls you need to execute the stacks you have built.

Building an Application

QCNode implements the same design pattern as QC implementations in other languages, but has been engineered to take advantage of the strengths of Node.js. In all QC implementations you build your application as a series of 'stacks'. Each stack consists of a list of Control Functions and is represented by a single command. A simple example is in order. This simple example shows only one or two of each type of Control Function but your stacks can consist of any number of any type of Control Function.

Imagine that you are writing the backend for some sort of game application. This imaginary game needs to store player names and scores associated with that user name. Obviously the pattern of validation, data storage, and response generation needs to be followed. When creating a QCNode application each stack is created by executing only three steps.

  1. Design the Stack
  2. Create the Stack
  3. Create the Control Functions
  4. Done!

Designing the Stack

The first thing to do when designing a stack, is to decided upon a descriptive command. In this example 'insertScore' is selected since it describes what the stack will do. Once this decision is made a textual listing of possible control functions is created. Since we need to validate that a user name and score exist in the incoming data, one of the Validation Control Object is called CheckNameAndScoreValCO. While it is not required to end an object name with the type of functionality that it implements, it is advised that you do so. It makes debugging much easier.

Another Validation Control Object is used to see if a session ID has been sent along with the data. In this example it will be called CheckSessionIDValCO. The data will then need to be stored for later potential retrieval. Let's call this control object StoreNameAndScoreDCO. Notice that it ends with the suggested DCO (Data Control Object) designation.

The final Control Object in this stack is a View Control Object (VCO). It will be used to generate a response to the request. In this example let's call it GenerateInsertResponseVCO.


Creating the Stack

Creation of stacks should happen only once in your application. This is done when your application includes the QuickConnectNode.js file by making a require function call. By making this call early in your application's life it insures that QC is available whenever your node application needs it.

QC includes a series of API functions to make stack creation easy. These are seen in this example source. A description of these is also found in the functions portion of this API documentation.

Each Control Function is mapped using the appropriate qc.mapCommandTo*** function. It is regarded as best practice, though not required, to map your stacks in the order of Validation, Data, View. This makes the stacks somewhat self-documenting and can aid in later debugging.

It is important to note that the order within each type of mapping, Validation, Data, or View, is important. Your stack will execute each Control Function in each these sub-groups in the order you map them in your code. However QC will always execute in the sub-groups in the order Validation-Data-View while following the order of your mapping within the sub-groups.

Create the Control Functions

Each Control Function must have one parameter. This parameter must be an associative array or JavaScript object. Thus the functions take on the form "function checkDataValCF( data ){...}". These functions are always defined in the functions.js file..

The function CheckNameAndScoreValCF is a QC Control Function. You can see this simplified Validation Control Function in the example source here. Your validations would obviously need to be more rigorous than just a check for existance and a negative value check as seen in this example.

The parameters associative array creation will be shown later.

In this validation function notice that if validation fails a call is made to qc.handleError. The command 'badNameScore' is passed. This means that in the mappings.js file a mapping there would need to be a mapCommandToECO call that was passed 'badNameScore' and some Control Function or series of Control Functions needed to do any required cleanup and/or response generation. It is not included in the example shown here.

Do notice that qc.STACK_EXIT is returned in the case of validation failure. This will termainate any further stack execution at this point. No further Validation, Data, or View Control objects in the stack will be executed.

If validation passes, then qc.STACK_CONTINUE is returned. This indicates to QC that all is well and the next control function in the current stack should be executed.

While it is valid to call qc.handleError from within any implemented control function it is never valid to call qc.handleRequest from within a control function. If this is done unexpected results may occure since QC is handling all of the parallelism in your handleRequest calls.

Triggering the Stack

QC has a method to trigger a stack, qc.handleRequest. As you can see it has two required parameters, the name of the stack to execute and a series of parameters to use within the stack's Control Functions. The associative array parameters shown here is hard coded. In reality this information would be retrieved from the request made to your NodeJS server. Regardless of where the data comes from they must be placed in an associative array or JavaScript object before they are passed on to the stack using the handleRequest method.

There are functions used to trigger stack execution. One that allows you to execute a series of stacks in parallel with independent parameters and another that allows one or a series of stacks to be executed in series or parallel with a shared parameters associative array. Please see the QuickConnect function API for a full explanation of options.

Functions

The functions listed in this file are those that a developer has available to them to use the QCNode library.

Name Space: qc_node

'qc' is used internally as the namespace for all of the functions and constants available through the QCNode library. It is used to differentiate QCNode functionality from items available through other libraries that your application may be using. It is suggested that you use qc_node, or some variation of it, as the variable name when requiring the QCNode files in your source code.

Mapping Functions

These functions are found in the mappingUtil.js file and are used to build stacks as described in the Instructions.

mapCommandToValCF(aCmd, aValCF)

Parameters:
  aCmd: a descriptive indicator of the stack.
  aValCF: a function from the functions.js file

Maps the specified command to a Validation Control Function (ValCF) in the stack specified by the command. This function may be called any number of times for a given command. Doing so allows multiple ValCF's to be mapped into the indicated stack.

mapCommandToDCF(aCmd, aDCF)

Parameters:
  aCmd: a descriptive indicator of the stack.
  aDCF: a function from the functions.js file

Maps the specified command to a Data Control Function (DCF) in the stack specified by the command. This function may be called any number of times for a given command. Doing so allows multiple DCF's to be mapped into the indicated stack.

mapCommandToVCF(aCmd, aVCF)

Parameters:
  aCmd: a descriptive indicator of the stack.
  aVCF: a function from the functions.js file

Maps the specified command to a View Control Function (VCF) in the stack specified by the command. This function may be called any number of times for a given command. Doing so allows multiple VCF's to be mapped into the indicated stack.

mapCommandToECF(aCmd, anECF)

Parameters:
  aCmd: a descriptive indicator of the stack.
  anECF: a function from the functions.js file

Maps the specified command to an Error Control Function (ECF) in the error stack specified by the command. This function may be called any number of times for a given command. Doing so allows multiple ECF's to be mapped into the indicated error stack.

mapCommandToSubCommands(command, subCommandArray)

Parameters:
  aCmd: a descriptive indicator for the grouping of sub-commands.
  subCommandArray, … : an array of sub-commands that are to be grouped under the 'command' key.

This function allows you to group sub-commands under a single key/command. Each sub-command is executed in parallel rather than serially. This is useful when you want to make stacks that are independent yet re-usable.

Stack Execution Functions

These functions are found in the QuickConnect.js file and are used to execute stacks created as a result of calling the mapping functions.

handleRequest(aCommandArray, requestData, allStacksCompleteCallback, runParallel)

Parameters:
  aCommandArray: an array of commands or groups to be executed by this request.

  requestData: an object that contains the parameters to be shared by all commands or groups executed.

  allStacksCompleteCallback: a function to be executed when the commands have been executed. If the runParallel boolean is set to true, this method is called at the end of each stack for each command. If runParallel is set to false, or left out of the function call, this function is called after all of the stacks have completed.

  runParallel: a boolean indicating if the stacks associated with the array of commands should be run in parallel or serially.

This function triggers the execution of one or more stacks or groups that have previously been defined using the mapping functions listed above. This function may be called from anywhere in your application's code.

handleError(aCmd, errorParameters)

Parameters:
  aCmd: a command, not an array, describing the error stack to be executed by this request.
  errorParameters: an Object/associative array that contains all of parameters needed by the Error Control Functions (ECF's) in the error stack indicated by aCmd.

This function triggers the execution of the indicated error stack. It is usually called from within other Control Functions when an error has been detected, the running stack execution terminated, and some sort of behavior needs to be executed to cleanup the application or some notification needs to be done. An examples would be a validation failure in a ValCF or failed data retrieval by a DCF.

handleBatchRequest(commandParameterPairsArray)

Parameters:
  commandParameterPairsArray: an Array of objects describing the command/group to use as a trigger, the data to be used with that request, and the callback function to be called after that command has been completed.

This function allows you to execute a batch of requests that have independent parameters. The aRequestInfoArray contains descriptors that must conform to this structure: {'cmd':aCommand, 'data':aParametersObject, 'callback':aCallbackFunction}. The handleBatchRequest function is a wrapper for handleRequest and is designed to ease the execution of large numbers of stacks from a single trigger. It executes each command in the descriptor commandParameterPairsArray in parallel with each other.

Async Stack Functions

These functions are found in the QuickConnect.js file and are used to continue or exit stacks from within callback functions to async behaviors such as file IO, database interactions, etc. These methods are used from within data control functions.

asyncStackContinue(uuid, resultKey, results, commandArray , allStacksCompleteCallback, error)

Parameters:
  uuid: the universally unique identifier associated with the executon of the stack. This has been generated by the framework for you and is passed as the second parameter to all control functions when they are executed.

  resultKey: the key you desire to associate with the results of the async computation. The key and the results will be added to the associative array passed as the first parameter to all control functions.

  results: the result or results of the async call as calculated in the async call's callback function.

  commandArray: an array of all the commands sent to the stack execution method, such as handleRequest. This is value is passed to all control functions as the third parameter.

  allStacksCompleteCallback: a function to be executed when the commands have been executed. This is passed as the fourth parameter to all control functions.


This function allows the correct stack to be completed after a data control function makes some sort of asynchronous call to some other functionallity. It should not be called from anywhere else.

asyncStackExit(uuid, resultKey, results, allStacksCompleteCallback)

Parameters:
  uuid: the universally unique identifier associated with the executon of the stack. This has been generated by the framework for you and is passed as the second parameter to all control functions when they are executed.

  resultKey: the key you desire to associate with the results of the async computation. The key and the results will be added to the associative array passed as the first parameter to all control functions.

  results: the result or results of the async call as calculated in the async call's callback function.

  allStacksCompleteCallback: a function to be executed when the commands have been executed. This is passed as the fourth parameter to all control functions.


This function terminates and cleans up the stack. It also ensures that the allStacksCompleteCallback is executed if it exists.

Constants

These constants are found in the QuickConnect.js file. They are returned from Control Functions in order to effect stack execution. They tell the stack

WAIT_FOR_DATA

Usually returned from a Data Control Function (DCF) and indicates that the stack should pause until an asynchronous call to retrieve data returns.

STACK_EXIT

Returned from any type of Control Function to indicate that the no further execution of the stack should be allowed. Returning this constant is usually proceeded by a call to the handleError function.

STACK_CONTINUE

Returned from Control functions when STACK_EXIT and WAIT_FOR_DATA are not appropriate. It indicates that the next Control Function in the stack should be called immediately.

Files

The files described here are those that QCNode expects you to implement in order to use the library. Each has a specific name and reason for existance. For an overall description of QCNode please examine the Instructions.

mappings.js

This is the file in which you will make the mapping calls, described in the functions list, that build your stacks. By centeralizing stack creation in this file, it becomes much easier to debug stacks and the Control Functions of which they are composed.

functions.js

This is the file in which you will define the Control Functions for your application that are mapped to commands in the mappings.js file. Make sure to add the Control Functions you create here to the exports. This makes them available to QCNode for mapping and execution.