Tree-Ware Architecture
Accelerate your software development!
Data-First
The data corresponding to features must be defined first
Model
The runtime data is called Model
It is (primarily) a tree structure
Meta-Model
The definition for the Model is called Meta-Model
Many data types are supported
Packages, Entities, Fields, Enumerations, Primitives, Aliases
Compositions (nested entities) make it a tree
Associations (references to other entities) make it a directed-graph
Various constraints can be declared in the meta-model
Aux Data
Auxiliary data can be attached to any node in the model tree
Used for cross-cutting aspects
Examples: errors, access-control definitions, DB mappings
Model Operator
Operates on one or more models
Codec: encode/decode JSON, Protobuf, SQL, etc
Intersection: determine what is common between 2 or more models
Union: determine the combination of 2 or more models
Difference: determine the difference between 2 models
Operators can be composed to create versatile expressions
System Architecture
There is a pipeline from the UI to the DB and beyond
Models flow through this pipeline in both directions
Most pipeline stages implement cross-cutting aspects
Custom business-logic is also a stage in the pipeline
Each cross-cutting stage is implemented as an operator
The pipeline is in essence an expression composed of operators
Architecture Benefits
The pipeline can be run on a single machine or distributed across multiple machines
The pipeline can support new features
without glue logic for cross-cutting aspects
New cross-cutting aspects can be inserted
as pipeline stages
without modifying existing features
Tree-Ware Design Pattern
Use models for feature-data
Use aux data for cross-cutting aspects
Use model operators to implement cross-cutting aspects
API
Get-requests are model trees specifying the parts of the model to be returned
Get-responses are model trees corresponding to the parts requested
Set-requests are model trees containing the nodes to be created/updated/deleted
Set-request models are validated against the meta-model
Fan-out: a request can be split into smaller trees and load-balanced to different servers
Fan-in: responses from the fan-out can be combined into a single response
Stream: responses from the fan-out can be streamed back to the client as they arrive
Both set-requests and get-requests are via HTTPS POST and JSON
RBAC
An RBAC role is a model that only contains nodes that are accessible
Aux data on these nodes specify the required permissions
An intersection operator intersects API requests/responses with the RBAC model
Only the common parts (the intersection result) are permitted to the next stage in the pipeline
Feature-Flags
Extremely fine-grained feature-flags at the individual field level
Aux data indicates readiness: in-progress, developed, tested, released, etc.
A filter operator can filter a model based on readiness
DB
The model is mapped automatically to appropriate databases
Configuration is mapped to an SQL database
State/metrics is mapped to a metrics database
Schema for the databases is taken care of by tree-ware
Code for writing to and reading from the databases is taken care of by tree-ware
API & DB Migration
Meta-model evolution is validated to ensure changes are backward-compatible
The difference operator is used on the new version and the previously released version
API and DB migrations are generated based on the differences computed by the operator
Code Generation
Most of tree-ware is data-driven, but a few things are generated
OpenAPI (Swagger) specification
Typesafe model classes for use in business-logic
Liquibase DB schemas and DB migration scripts
Supported Languages
Kotlin
Java
TypeScript
JavaScript
Native (Android/iOS)
Foundations
Functional Programming
Abstract Algebra
Recap: Tree-Ware Design Pattern
Use models for feature-data
Use aux data for cross-cutting aspects
Use model operators to implement cross-cutting aspects
Given a model tree of ONLY the config
How do we generate a UI for it?
How do we customize the components shown for certain fields?
Given a model tree of config AND state
How do we get a model tree of:
only the config?
How do we get a model tree of:
only the released config?
How do we get a model tree of:
only the released config the user has access to?
How many times do we have to walk the input model tree?