Creating APIs‎ > ‎Logic‎ > ‎Logic Patterns‎ > ‎

Command Pattern

The command pattern is an elegant approach for logging requests and initiating desired behavior. The basic approach is to create a table for the command object and implement the desired behavior in a logic event. Clients invoke the command by Posting to the command object (either the table or a custom resource built on it).

Creating a table unlocks all the software already oriented to RESTful database APIs:

  • Simplified API, so that command requests pass parameters in JSON request objects, like conventional database-oriented APIs.
  • UI creation, such as Data Explorer. For example, you can test your command pattern using Data Explorer.
  • Reporting, for example, to analyze the received requests (for example, volume, results, etc). The arguments are captured naturally.
  • Problem diagnosis, for example, to see the partialResults.

Create the Components used in Command Patterns

The following sections describe how to create the components used in a command pattern, some typical examples, and some considerations.

Create a Command

Create a Command Table

First, create a new table to store request types, for example, RequestCommand. In most cases, you will also define a database-generated key. For convenience, you can use managed data for these tables.

In many cases, you will have more than one type of command to build. Consider the following alternatives (which you can mix and match):

 Approach  Considerations
 Single command per table Command table can be child of domain table, providing easy access to parent attributes.
 Multiple commands per table Useful where there is generic logic shared over command types.

For more information about managed data, see Database Creation.

Add Columns for Arguments

Second, add columns for each parameter, for example, payload, amount, and so forth.

Add Columns for Administration

One of the big advantages of this approach is that you can add additional columns to assist in administration. For example, you can aid in problem diagnosis by adding datetime or record partialResults.

Create a Table Event for Desired Behavior

To effect the desired behavior, create a table event. The row object provides access to the columns you have added.

For more information:

Client Invocation: Post to Command Table

Clients invoke the request by Posting to the command table, with a request body consisting of the arguments. This is the same idea as posting a new Customer, Order etc. In most cases, this will be a custom resource of the command table, to hide administration columns.

Examples

POST: http://localhost:8080/rest/default/mycommands/v1/RequestCommand
JSON: {"command":"giveRaise", payload:{"employeeID":1,"percentRaise": 0.10}}

Give Raise

The reactive logic tutorial illustrates one approach for giving raises (somehow a popular example), using URL arguments. You can also implement this with the command pattern. This provides a useful audit of salary changes.

Define a giveRaise event for insert on the EmpRaise table (a child of the Employee table), such as:

var employee = row.employee;
logicContext.touch(employee);
employee.salary = employee.salary * (1 + percentRaise);
logicContext.update(employee);

For more information about the reactive logic tutorials, see Reactive Logic Tutorial.

Alternatively, you could use the "multiple commands per table" approach, so the giveRaise event would look like:

if(row.command === 'giveRaise'){
  var empID = row.payload.employeeID;
  var percentRaise = row.payload.percentRaise;
  var employee = logicContext.getBeanByPrimaryKey("employee", empID);
  logicContext.touch(employee);
  employee.salary = employee.salary * (1 + percentRaise);
  logicContext.update(employee);
}

For more information about the reactive logic tutorials, see Reactive Logic Tutorial.

Event Sourcing

Event Sourcing is a well-known pattern that preserves transactional information. It is straight-forward pattern that inserts into a child table the change to the employee (parent) name by inserting a new row in the empChanges 'audit' like table.

Using the same data model, create a child of Employee called EmpChanges. Build an event handler for inserts into EmpChanges, such as:

var emp = row.Employee; //get Parent Object
logicContext.touch(emp);
if (row.name !== null) emp.name = row.name;
  // etc for all attributes,
  // or, create a shared lib routine that automates moving same-named attributes
logicContext.update(emp);

For more information about the Event Sourcing pattern, see the Event Sourcing documentation.

Data Sync Request

In the previous examples, the transactions were about data directly managed by Live API Creator. This is not always the case. Numerous applications integrate a source and target system.

Let's presume that a source system Posts a command request containing data to be sent to a target system.

Start by defining local table called SyncRequest, matching the columns (and child data, if any) from the source system. Create an action rule to move this to the target, using a custom resource (TargetAPIDef) that defines the mapping and transformation logic. This example illustrated in the Business to Business example:

var transform = logicContext.transformCurrentRow("TargetAPIDef");
B2B.sendToWebHook(transform, shipper.webHookURL);

For more information about the Business to Business example, including how you can extend logic with table events, see Business to Business Example.

Wake-up request (e.g., poll)

In some cases, the source system is passive, and does not Post requests to initiate integration. You can create a cron job that posts to the command table, for example, PollRequestsThe PollRequest action handler queries the source system (perhaps writing results into command table administration columns). This can result in a list of rows. Since these rows do not correspond to tables in your schema, you must write code to move each attribute to a Post Request JSON.

Considerations

Simplify Database Administration

In some applications, you might not have otherwise required a local database, such as with the previous Data Sync request example. Creating a database might appear to be overhead, but there you can use the following options. You can use the AdminDB or set up an additional Derby database. You can migrate dev to production using MySQL database export, or, for Derby, copy the Derby folder, or create a export script with tools such as DbVisualizer.

Error Handling

Errors can occur. You will typically not want to rollback the transaction, since that removes the command object and the command object can be helpful in diagnosing the failure. Instead, consider creating a column for the result and format the RESTful response as desired using request events.

For more information about request events, see Request Event Handlers.