Skip to content

Architectural Overview

Architectural Overview

Docker Containers

As shown below, there are typically 2-3 "machines" in operation: * Your local host (in grey), where the Customizable Project files (ApiLogicProject) are stored, and your Dev Tools (IDE etc) operate

  • The ApiLogicServer Docker container (blue), which contains:
  • The ApiLogicServer, with CLI (Command Language Interface) commands:
    • create to create projects on your local host
    • run to execute projects, utilizing the various runtimes (Flask, SQLAlchemy, SAFRS API, Logic, Flask App Builder)
  • A Python environment to support execution, and development using your IDE
  • Neither API nor logic execution creates / uses additional files or database data; your database access is via standard SQLAlchemy models

    • The exception to this is Flask App Builder, which creates additional database tables for security authorization
  • The database (purple) can run as a separate Docker container, in your local host, or (for the demo) within the ApiLogicServer docker container

Pip Install - ApiLogicServer in local Python environment

Alternative option: pip install

You can also run ApiLogicServer without Docker. The familiar pip install ApiLogicServer creates the ApiLogicServer in your venv instead of the Docker container. The contents are identical - the ApiLogicServer create and run components.

We recommend, however, that you take a good look at Docker: * It avoids a sometimes-tricky Python install * It isolates your projects into containers * It is quite likely the eventual deployment architecture, so you're already in step with that

ApiLogicServer Key Components

Component Provides
SQLAlchemy Python-friendly ORM (analogous to Hiberate, JPA)
Logic Bank Multi-Table Derivation and Constraint Rules
Python Events (e.g., send mail, message)
Extensible with Python
SAFRS JSON:API and swagger, based on SQLAlchemy
SAFRS-React-Admin Executable React Admin UI, using SAFRS

Project Structure

When you have created your project, you will find the following project directory in ~/dev/servers on your (grey) local host (here opened in VS Code):

Your docker container (blue) files include Python, Python libraries, and API Logic Server. The Python project above utilizes IDE remote-container support (visible at the lower left in the preceding diagram), which utilizes the docker container (not local host) version of Python.

Your docker container looks like this:

IDE Friendly

The project structure above can be loaded into any IDE for code editing, deubgging, etc. For more information on using IDEs, see here.

Tool-friendly - file-based

All project elements are files - no database or binary objects. So, you can store objects in source control systems like git, diff/merge them, etc.

Internals - How It Works

Project Creation

The ApiLogicServer CLI create (or create-and-run) command creates the project structure shown below - for more information, see here.

 

API Execution: api_logic_server_run.py

Execution begins in api_logic_server_run.py. Your customizations are done to the files noted in the callouts below.

api_logic_server_run.py (a file created in your ApiLogicProject) sets up a Flask app, the database, logic and api:

  1. Database Setup: It importsapi/expose_api_models which imports database/models.py, which then imports database/customize_models.py for your model extensions. api_logic_server_run.py then sets up flask, and opens the database with db = safrs.DB

  2. Logic Setup: It then calls LogicBank.activate, passing declare_logic which loads your declared rules into Logic Bank.

  3. API Setup: It next invokes api/expose_api_models. This calls safrs to create the end points and the swagger information, based on the created database/models.py (the models used by the SQLAlchemy ORM). It finally calls api/customize.py where you can add your own services. The sample includes a trivial Hello World, as well as add_order.

Logic Execution

SAFRS API listens for API calls, e.g., from the Admin App. When updates are issued:

  1. Invokes SQLAlchemy updates: SAFRS calls SQLAlchemy, passing a set of rows comprising a database transaction

  2. before_flush: SQLAlchemy provides a before_flush event, where all the update rows are assembled and passed to Logic Bank (no relation to retail!).

  3. Logic Execution: Logic Bank reviews the rows, and based on what has change, prunes rules for unchanged data, and executes / optimizes relevant logic in an appropriate order.

Declarative Logic is critical

Logic addresses multi-table derivations, constraints, and actions such as sending messages or emails. These can constitute nearly half the effort in transactional systems.

Admin App Execution: ui/admin/admin.yaml

http://localhost:5656/ redirects to ui/admin/index.html which loads the react-admin single-page app into your browser.

It then loads your ui/admin/admin.yaml, and responds to the various clicks by invoking the API (and hence the update logic), or the swagger at http://localhost:5656/api.

Key Observations: Extensible Declarative Automation

While the most striking element of ApiLogicServer is automation - a running UI and API from a database - there are some important aspects, described below.

Customizable, Declarative Models

Observe that the key files for defining API, UI and Logic are not procedural code. They are declarative: specifications of what you want to happen, not how it's implemented:

  • Logic looks more like a specification than code

  • UI looks like a list of Objects and Attributes to display

  • API looks like a list of Objects

This is important because they are orders of magnitude shorter, and therefore far easier to understand, and to customize.

For example, consider the UI, defined by ui/admin/admin.yaml. This is in lieu of hundreds of lines of very complex HTML and JavaScript.

Extensible

ApiLogicServer makes provisions for you to add standard Python code for aspects of your project that are automated - custom end points, extensions to the data model, logic (rules plus Python).

And, of course, the API means you are unblocked for creating custom UIs and integrations.

Includes Logic

As noted above, multi-table constraints and derivations can constitute nearly half the effort in transactional systems.

Unlike most systems that address such logic with "your code goes here", ApiLogicServer provides declarative spreadsheet-like rules, extensible with Python, as described here. Rules are 40X more concise than code.

Rule execution is via a transaction logic engine, a complementary technology to traditional RETE engines. The transaction logic engine is specifically designed to optimize integrity and performance for transactional logic, which is not possible in RETE engines. See here for more information on their operation.

Technology Adoption Considerations

Standards-based

Development and runtime architectures are what programmers expect: * As noted above, the Key Project Components are standard Python packages for APIs, data access. * Projects developed in standard IDEs, and deployed in standard containers.

Near-Zero Learning Curve - no frameworks, etc

ApiLogicServer has a near-zero learning curve. You do not need to know Python, SQLAlchemy, React, or JSONapi_logic_serverPIs to get started. You have a running project in moments, customizable without requiring deep understanding of any of these frameworks. Making extensions, of course, begins to require more technical background.

Allow a few days for learning logic

Logic represents the starkest different between procedural code and declarative rules. It requires a few days to get the hang of it. We recommend you explore this documentation.

Business Agility

ApiLogicServer automation creates a running project nearly instantly, but it also is designed to help you adapt to business changes more rapidly:

Technology Agility - an Application Virtual Machine

Models are, somewhat by their very nature, rather technology independent. Instead of React, the UI specification could be implemented on Angular. Instead of interpreted, the logic could be code-generated onto any language. And so forth.

You can think of the Key Project Components as an Application Virtual Machine that executes ApiLogicProjects. As new underlying technology becomes available, new AVMs could be developed that migrate the declarative elements of your UI, API and Logic - without coding change. Because, they are models, not code.

This provides an unprecedented preservation of your application investment over underlying technology change.

Automation Reduces Risk

Automation not only gets results fast and simplifies adapting to change, it also reduces risk.

Coding Risk

The most troublesome bugs are silent failures - no stacktrace, but the wrong answer.

Automation address this by designing out whole classes of error:

Architectural Risk

Technology complexity makes it get hard to get projects that even work, much less work right. Projects commonly suffer from a wide variety of architectural flaws:

  • business logic is not shared, but repeated in each UI controller... and each integration
  • pagination may not be provided for all screens

And so forth. These cause project failures, far too often.

But automation can help - since your declarative models only stipulate what, the system bears the responsibility for the how -- and getting it right. Each of the architectural items above are automated by the system.

Requirements Risk

Requirements risk can represent an even greater challenge. The reality that users may only realize the real requirements when they actually use running screens with real data. The problem, of course, is that these are often available after considerable time and effort.

That's why working software now is so important - users get screens right away. These can identify data model errors ("hey... customers have more than one address") or business logic requirements ("hey.... we need to check the credit limit").