Logic Execution

Logic Execution
lac52
CA Live API Creator
 executes your business logic in response to REST POST/PUT/DELETE requests. This article provides information about how API Server operates so that you can debug your API. Shown conceptually in the following Reactive Logic video, this article illustrates how to use rules, how rules work in 
CA Live API Creator
, and how event rules integrate with resource events.
For more information about resource events, see Manage Resource Events.
In this article:
 
 
3
 
 
Watch the Video
The Reactive Logic video describes the concepts and operation of reactive logic for the following:
  • Definition
  • Execution: watch, react, chain
 

 
For more information about reactive logic, see Reactive Logic.
Verify the Prerequisites
Before reviewing the information in this article, ensure that you have completed the following prerequisites:
  • You are familiar with the Logic Demo and the CA Live API Creator Architecture.
  • You understand the JavaScript object model. The JavaScript object model provides for GET events which you can handle in JavaScript.For more information about the JavaScript object model, see Row Objects.
Usage Overview
 
CA Live API Creator
 uses your business rules (reactive logic) to process RESTful updates (POST, PUT, DELETE).
Connect and Declare Rules
When you create an API and you connect API Creator to your database, 
CA Live API Creator
 creates a JavaScript object model and creates a row object type for each base table. You can think of these as Object-Relational Mapping (ORM) objects: they provide access to attributes, related objects, and persistence. These objects also expose update resource events that you can handle in JavaScript.
For more information about the 
row
 object, see Row Objects.
Many ORMs require tedious synchronization between your schema and objects. The use of JavaScript means that these objects are dynamic and require no code generation. The objects automatically stay in sync with your model. ORM objects are logic aware. That is, they encapsulate both declarative rules and conventional resource events. You can think of these objects as declarative persistence objects. The declarative rules are expressions for deriving/validating data. The first validation rule ensures that the balance does not exceed the credit limit (else the transaction is rolled back). The second rule computes the balance by summing the related orders:
Validation
: return row.CreditLimit >= row.Balance
Derive Balance as
Sum
(Orders.AmountTotal where ShippedDate === null)
The expression operands are derived from the schema: tables, columns, and foreign key relationships. You enter rule expressions using a combination of forms and server-side JavaScript functions that provide, for example if/else logic and access to libraries. You can execute these functions in rules.
RESTful Update Processing
After you have created the rules, RESTful-update processing calls the rules, orders the rules, and reads/writes the data. The following subsections explain how 
CA Live API Creator
 processes update requests. The following diagram shows the workflow:
  update-request.png  
Request Processing
API Server raises request events. API Server raises a request event once for the entire update request. Your JavaScript can inspect/alter the JSON request body.
For more information about request events, see Event Handlers.
Mapping Phase
You can define multiple custom resources on the same underlying base table. The resources can represent projects and aliases of table columns. Integrity demands that the base table logic is enforced regardless of the resource used.
Resource/object mapping is required to map the resource objects onto their respective row objects. This includes column name de-aliasing and materialization of columns not projected (sometimes called "hydrated"). The declarative and event logic deals with a full row. 
CA Live API Creator
 shares that logic over all resources that you explicitly define in API Creator. To do this, 
CA Live API Creator
 must read the database, with concurrency control supplied by the DBMS.
So that you can define logic based on data changes, 
CA Live API Creator
 builds the following row objects:
  •  
    row
    . This object reflects client changes from JSON, and all logic processing.
  •  
    oldRow
    . This object reflects the row before the transaction started. This object is from the database read.
API Server ensures that updated rows do not overlay the updates of other users by performing optimistic locking checks. The check is on a time-stamp field, if provided. Otherwise it is the hash of all attributes in the resource row.
For more information:
Pre-Insert Event Rule
For inserts, 
CA Live API Creator
 processes the logic when resource rows are mapped to table rows. The logic occurs in advance of the other events. You can have 
CA Live API Creator
 generate an alphanumeric primary key using a pre-insert event rule that computes the keys.
You do not need to create pre-insert event rules for database-generated primary keys. The database handles these keys automatically.
Database Key Generation
Databases support system-generated primary keys. The requirements for processing JSON POSTs include child rows for these tables, such as the items for an order. 
CA Live API Creator
 must "stamp" the generated order# into each item before it executes logic and when it performs managed parent.
When using a resource with nested children (for example, Customer contains Orders, contains Items), you can POST (insert) a new Customer, Order, and Items in a single transaction. You can do this only when 
CA Live API Creator
 can propagate the primary key of the parent (Customer or Orders) down to the child (for example, Orders or Items).
For more information:
Logic Phase: Row Logic Cycle
 
CA Live API Creator
 processes each submitted row in the order it receives them, as follows:
  1. Calls early event rules, supplied with the 
    row
    oldRow
    , and 
    logicContext
     variables. Your event rule can inspect/alter the row before rules fire. For example, you can compute network-unique primary keys.
  2. Executes (only) those rules whose dependent row data has changed (based on comparing 
    row
     with 
    oldRow
    ). It computes the rule execution order based on rule dependencies, discovered by automatic rule parsing. The rule updates the row (state), so it is visible to ensuing rules.
  3. Executes event rules so that you can do whatever is not expressed in declarative logic. For example, send email, post data to other systems, and credit card checks. You are passed 
    row
    oldRow
    , and 
    logicContext
    . The effects of rule changes are visible in your row objects.
    You can alter the row, but you must save your changes.
    For more information about event rules, see Event Rule Types.
  4. If the logic has altered data that rules in related objects reference, 
    CA Live API Creator
     instantiates rows for them and invokes their logic. For example, altering 
    OrderTotal
     updates the related customer's balance, whose rules would verify the 
    CreditLimit
     . This is an efficient one-row update, not an aggregate query.
CA Live API Creator
 uses a transaction for all updates of a given request, both rows from the client, and chained updates (step 4). It buffers rows into the write-cache so that multiple updates to the same row (for example, many line items might adjust the 
PurchaseorderamountTotal
 .
Commit Phase: Row Commit Cycle
For each submitted row, 
CA Live API Creator
 executes commit event rules and commit validation rules. These rules reflect the logic from the complete transaction. If it does not detect errors, 
CA Live API Creator
 flushes to disk the updates that have been buffered to cache and commits the transaction (it automatically transaction-brackets each request).
CA Live API Creator
 flushes the write-cache to the database at the end of the transaction, after it processes all rows. Your logic specifications for validation rules and event rules can stipulate that they run during normal per-row execution or can be deferred until commit. If you elect your validation rules and event rules run during normal per-row execution, 
CA Live API Creator
 executes the logic only prior flushing the transaction. 
CA Live API Creator
 has completed the Logic Phase, so the logic for the rows are visible in your row objects.
For example, you want to ensure Purchase Orders have at least one line item. You can define a 
Purchaseorder.item_count
, with a 
Purchaseorder
 validation rule that 
item_count > 0
.
While a good approach, this would fail. Why? 
CA Live API Creator
 processes the 
Purchaseorder
 insert first before line items. At this point, the count is zero (0), so the validation fails. Instead, you can create commit event rules. These validation rules and event rules must operate on the end-result of logic processing for all the rows in the entire transaction.
For more information:
Request Events (Response)
Request events provide and entry point after server processing is complete, just before returning to the client. You can reformat the response message, as illustrated in the 
CA Live API Creator
 raises request post events. You can alter the response message or you can perform other functions such as logging.
Forward Chaining
With forward chaining, if you change a referenced value, 
CA Live API Creator
 recomputes the derived referencing attributes. The term chaining correctly infers that a derived attribute (for example, 
Purchaseorder.amount_total
) is itself referenced in another derivation (
Customer.balance
). 
CA Live API Creator
 tracks these references and performs the forward chaining, automatically.
For formulas (for example, price * quantity), forward chaining entails evaluating the expression (though see ordering, in the following sections). Forward chaining is more complicated for dependencies and multi-table derivations.
Ordering
Columns dependent on changed columns can themselves have interdependencies. For example:
a = b + x
b = x + 2
It is clear that 
a
 depends on 
b
, so if 
x
 is altered, 
CA Live API Creator
 must recompute 
b
 before it recomputes 
a
. You can state these rules in any order. You can change the rules during maintenance, without concern for ordering.
Parent Adjustment
Continuing our 
Customer.balance
 example, imagine a simple update where a 
Purchaseorder
 is marked paid. We need to recompute the new balance. A dreadful approach is to issue a SQL Sum query to add all the existing orders. In general, there could be thousands! And worse, this could be chained, where the summed attributes depend on further summed attributes. That is, in fact, just the case here: the 
Purchaseorder.amount_total
 is itself a sum of the 
Lineitem.amount
. This is a significant performance factor. ORM products are often blamed for poor performance due to excessive use of chained aggregate queries.
 
CA Live API Creator
 adjusts the parent sum by the change in the child. The result is a one-row update (unless it was pruned).
Child Cascade
Analogous considerations are where the client alters a parent attribute referred to in child logic (for example, a formula). When this occurs, 
CA Live API Creator
 visits each related child to run the dependent logic. Running the dependent logic might update the child, and might trigger further adjustment / cascade processing to other related data.
For more information about formulas, see Formula Rule Type.
Multi-table Chaining
Adjustment and cascade-processing make updates to related data. 
CA Live API Creator
 often issues SQL updates for data beyond that originally sent from the client. This is a natural consequence of your logic and exactly what business logic is supposed to do. These triggered updates are subjected to the full logic analysis/chaining process, so will often result in still other updates. For example, consider a simple update to a 
Lineitem.quantity
:
  •  
    Lineitem.amount
     is derived as price*quantity, so is recomputed.
  •  
    Purchaseorder.amount_total
     is derived as Sum (
    Lineitem.amount
    ), so it is recomputed (adjusted).
  • Customer.balance is derived as Sum (
    Purchaseorder.amount_total
     where Paid = false), so is is adjusted.
The customer logic re-evaluates the credit limit check - if not passed, the entire transaction is rolled back, and an exception is returned to the client.
Logic Re-Execution
Chaining means that 
CA Live API Creator
 can execute your logic more than once on the same row multiple times within a transaction. Consider a transaction comprised of a purchase order with multiple Line Items. The purchase order logic is clearly executed on insertion. Now consider that each Line Item would adjust the Purchase Order's amount_total. This re-executes the purchase order logic, now as an update. Your logic can determine 
nestLevel
 and 
initialVerb
 by way of the 
LogicContext
 object.
For more information about the LogicContext object, see The logicContext Object.
Reactive Programming vs Conventional Procedural Programming
The following are key observations about some fundamental characteristics that distinguish reactive programming from conventional procedural (imperative) programming:
  • No Control flow.
     
    CA Live API Creator
     invokes the rules and only in reaction to actual changes. You do not order their execution. Rules are bound to the data, not a specific use case, so they apply to all in-coming transactions. In other words, the logic automatically processes the following transactions:
    • Order inserted - balance increased
    • Order deleted - balance decreased (if not paid)
    • Order unshipped - balance decreased
    • Order shipped - balance decreased
    • Order amountTotal changed - balance adjusted
    • Order reassigned to different customer - balance increased for new customer, decreased for old
    • OrderDetail inserted - obtain price, adjust Order and Customer (and check credit)
    • OrderDetail Deleted - reduce Order and customer totals
    • OrderDetail Quantity increased - adjust Order and Customer (and check credit)
    • OrderDetail Product Changed - obtain price, adjust Order and Customer (and check credit)
    • OrderDetail Quantity and Product Changed - obtain price, adjust Order and Customer (and check credit)
    • Customer CreditLimit changed - check credit
    This results in a meaningful improvement in quality. Reactive programming eliminates of an entire class of programming error (for example, balance checked when adding an order, but overlooked on unshipping an order).
  • Elimination of Boilerplate code.
     Reactive programming automates detection, change propagation, and persistence handling (SQL commands). The logic is executable:
    • ORM creation.
       Code is saved in the JavaScript object model.
    • Change detection.
       Most of the alternative code is determining when to propagate updates by detecting changes. This is eliminated in the declarative-reactive approach.
    • SQL (caching).
       SQL handling is tedious. Rules automate the SQL, including the underlying services for caching.
Simple Example: Check Credit
In the example, a solution of Check Credit is devised. Building on the previous two rules:
Validation: return row.CreditLimit >= row.Balance
Derive Customer.Balance as Sum(Orders.AmountTotal where ShippedDate === null)
Derive Orders.AmountTotal as Sum(OrderDetails.Amount)
Derive OrderDetails.Amount as row.Price * row.Quantity // JavaScript Expression
Derive OrderDetails.Price as copy(Product.Price)
This represents the complete, executable solution, that includes:
  • Ordering.
     You can alter the previous rules in any order because they are automatically ordered per dependency management.
  • Re-use.
     
    CA Live API Creator
     applies the rules to all incoming transactions, automatically invoking the previous (relevant) logic.
  • Automatic Persistence.
     
    CA Live API Creator
     processes incoming transactions by providing the SQL. Adjusting a quantity automatically reads/adjusts the Orders and Customer rows. It does so efficiently (a one-row update, not an expensive select sum query).
Common Logic Patterns
This simple "
Balance
 < 
CreditLimit
" example illustrates one of the most common logic patterns, validating a rollup/constraint-derived result. Other examples of the pattern include:
  • Rollup employee salaries to department, constrain to budget.
  • Rollup departments, constrain to budget.
  • Rollup Student Course Credit, constrain to max for student, max for course.
  • Compute Product Price from the sum of the Component Parts (nested).
  • Compute Event 
    GiftsAmount
     from sum of 
    EventGifts
     .
A similar pattern is Existence Checks: validation rules on [qualified] counts, such as an Order must have items and Department must have employees.
For more information about the common logic patterns, including validate a sum (rollup) and existence checks, see Learning Rules.
Business Perspective: Agility, Transparency, and Quality
Declarative logic is more expressive than imperative code. The previous five lines of logic equate to over 200 lines of triggers, or 500 lines of Java. It is also far more readable, in fact understandable, to business users. In an industry where we walk over hot coals for a 30% gain, this is a 40X improvement in expression factor. You can deliver update business logic 10X faster using rules. Removing boilerplate code and automatic re-use drives this compression factor.