AI-Driven Microservice Automation
Use ChatGPT to build a MySQL database model, and add API Logic Server to automate the creation of SQLAlchemy model, react-admin UI, and OpenAPI (Swagger).
Join the DZone community and get the full member experience.
Join For FreeI have been using a new open-source platform, API Logic Server (an open-source project on GitHub) to deliver API microservices for a client. I wanted to build a complete mobile banking API from start to finish based on the old TPC benchmark. This includes declarative business logic (a.k.a. spreadsheet-like rules), security, react-admin UI, and an Open API (Swagger) documentation.
API Logic Server (ALS) creates executable projects that you can extend in your IDE. It is an open-source Python platform based on SQLAlchemy 2.0, Flask, safrs-JSON API, react-admin, and LogicBank (a declarative spreadsheet-like rules engine).
ChatGPT-SQL Model
I started by asking ChatGPT to "generate a banking DDL based on the old TPC benchmark for MySQL". Here is the DDL that was generated:
While ChatGPT gave me a usable DDL, I then asked ChatGPT to "add columns for deposits, withdrawals, and image to Transaction" to allow the declarative rules to do the heavy lifting.
Transaction
- Deposit DECIMAL(15,2)
- Withdrawal DECIMAL(15,2)
- Image (checks and withdrawal slips) TEXT
Authentication
- Customer UseName VARCHAR(64)
- Customer Password (hash) VARCHAR(64)
API Logic Server (ALS)
This is a full-featured open-source Python platform (like Django) to create a complete runtime API and a react-admin back-office UI solution. The command line feature of ALS made the creation of a running server with a multi-page react-admin U and an Open API a snap.
The command line feature will read the SQL "banking" schema, and create a customizable project with all the wiring needed for SQLAlchemy and a full Restful JSON:API. ALS uses a command line approach to connect to the database and create all the running components:
ApiLogicServer create --project_name=tpc --db_url=mysql+pymysql://root:p@localhost:3306/banking
This creates a project you can open in your IDE to run and customize.
Rules
Declarative rules are spreadsheet-like expressions that automate backend multi-table derivations and constraints. Rules automatically execute as part of your API, making it a service. They dramatically reduce the amount of code you'd expect to write manually.
Rules are entered in your IDE. They are extensible with Python and are debugged with the IDE debugger.
Rules provide automatic re-use for our various TPC use cases - handling deposits and withdrawals, maintaining account balances, preventing overdrafts, and processing balance transfers. The magic is the LogicBank (an open-source spreadsheet-like engine on GitHub) that handles the ordering and execution at runtime and integrates directly with SQLAlchemy.
We start the process by writing our logic in a business user-friendly way.
- Derive Account balance is the sum of Transaction.TotalAmount
- Constraint: Account.AcctBalance cannot be less than zero
- Constraint: Transaction.Deposits and Transaction. Withdrawals must be greater than zero
- Formula - Transaction.TotalAmount is Deposit less withdrawal
- Customers can only transfer between their own accounts
Adding Rules
I am using VSCode. The command-line generated code is broken up into folders like database, api, logic, security, devops, etc. Under logic/declare_logic.py, we convert our design rules into actual declarative rules.
Code completion makes this a breeze. Python plus your IDE provides a Domain Specific Language for business logic.
Observe that rules are simply a formalization of our design above - an executable design.
Rule.sum(derive=models.Account.AcctBalance,
as_sum_of=models.Transaction.TotalAmount)
Rule.constraint(validate=models.Account,
as_condition=lambda row: row.AcctBalance >= 0,
error_msg="Account balance {row.AcctBalance} cannot be less than zero")
Rule.formula(derive=models.Transaction.TotalAmount,
as_expression=lambda row: row.Deposit - row.Withdrawal)
Automated React-Admin UI
ALS created a react-admin back office multi-table application for all the tables in the model. This allowed me to add a customer, checking and savings account, sample deposit transactions, test rules (e.g. sums, constraints, formula, etc.), and transfer funds.
OpenAPI (Swagger)
ALS will also generate OpenAPI (Swagger) documentation. This is using the safrs JSON-API, which enables clients to specify child tables and columns to return (a self-service API, much like GraphQL). This API will allow the front-end developer the ability to show the customer information, all their accounts, and a list of transactions (deposits and withdrawals) in a single API request. Another nice feature is each row returns a checksum which is used to support optimistic locking.
Transfer Funds
The heart of the TPC benchmark was moving funds between 2 accounts in a single transaction. In this example, we let the rules do the formulas, derivations. validations, and constraints, but we need an API to POST the JSON. One approach is using the api/custom_api.py to build a Python class to transfer funds from one account to another.
Another approach is to ask ChatGPT to "generate the transfer funds SQLAlchemy code" - so I added a new Transfer table and a commit event rule to implement the change to do the same work. Rules automatically adjust the firing order (formula, sums, validations, and then the commit row event).
The code below is entered in your IDE, providing code completion, debugging, etc.
def fn_transfer_funds(row=models.Transfer, old_row=models.Transfer, logic_row=LogicRow):
if logic_row.isInsert():
fromAcctId = row.FromAccountID
toAcctId = row.ToAccountID
amount = row.Amount
from_trans = models.Transaction()
from_trans.TransactionID = nextTransId()
from_trans.AccountID = fromAcctId
from_trans.Withdrawl = amount
from_trans.TransactionType = "Transfer From"
from_trans.TransactionDate = date.today()
session.add(from_trans)
to_trans = models.Transaction()
to_trans.TransactionID = nextTransId()
to_trans.AccountID = toAcctId
to_trans.Deposit = amount
to_trans.TransactionType = "Transfer To"
to_trans.TransactionDate = date.today()
session.add(to_trans)
print("Funds transferred successfully!")
Rule.commit_row_event(on_class=models.Transfer, calling=fn_transfer_funds
Security (Authentication/Authorization)
Since this is a multi-tenant model, the declarative security model needs roles and filters that authorize different role players to specific CRUD tasks. The role-based access control requires a separate data model for login, roles, and user roles.
We also will need an authentication process to validate users to log in to the mobile banking system. ALS asks that you initialize the security model using the command line tool (ApiLogicServer add-auth) which creates all the necessary components.
DefaultRolePermission(to_role=Roles.customer,
can_read=True, can_update=True, can_insert=True, can_dellete=False)
Grant( on_entity = models.Customer,
to_role = Roles.customer,
can_delete=False,
filter = lambda : models.Customer.CustomerID == Security.current_user().CustomerID)
Docker Container
The devops/docker folder has Shell scripts to build and deploy a running Docker image that can be deployed to the cloud in a few clicks. Just modify the docker-compose properties for your database and security settings.
Summary
I was impressed with API Logic Server's ability to create all the running API components from a single command line request. Using ChatGPT to get started and even iterate over the dev lifecycle was seamless.
The front-end developers can begin writing the login (auth) and use the API calls from the Open API (Swagger) report while the final logic and security are being instrumented. Business users can run the screens, and collaborate to ensure the real requirements are identified and met.
While I am new to the Python language, this felt more like a DSL (domain-specific language) with code completion and a well-organized code space. The ALS documentation provides great help and tutorials to understand how to deliver your own logic and API.
Published at DZone with permission of Tyler Band. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments