# this-rs Framework Architecture
## π Overview
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β USER APPLICATION β
β β
β ββββββββββββ ββββββββββββ ββββββββββββ β
β β User β β Company β β Car β ... Entities β
β ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ β
β β β β β
β βββββββββββββββ΄βββββββββββββββ β
β β β
βββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β THIS-RS FRAMEWORK β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β CORE MODULE (Generic) β β
β β β β
β β ββββββββββββ ββββββββββββ ββββββββββββ β β
β β β Entity β β Link β β Field β β β
β β β Traits β β System β β System β β β
β β ββββββββββββ ββββββββββββ ββββββββββββ β β
β β β β
β β ββββββββββββ ββββββββββββ ββββββββββββ β β
β β β Service β βPluralize β β Module β β β
β β β Traits β β System β β System β β β
β β ββββββββββββ ββββββββββββ ββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β βββββββββββββββββββββΌββββββββββββββββββββ β
β βΌ βΌ βΌ β
β βββββββββββ βββββββββββββββ βββββββββββ β
β β LINKS β β CONFIG β βENTITIES β β
β β MODULE ββββββββ€ MODULE βββββββΊβ MODULE β β
β β β β β β β β
β β Service β β YAML Loader β β Macros β β
β βRegistry β β Parser β β β β
β βββββββββββ βββββββββββββββ βββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββ
β STORAGE LAYER β
β β
β ββββββββββββββ β
β β In-Memory β β
β ββββββββββββββ β
β ββββββββββββββ β
β β DynamoDB β β
β ββββββββββββββ β
ββββββββββββββββββββ
```
## ποΈ Detailed Modules
### 1. Core Module (Generic)
The heart of the framework, completely agnostic of concrete entity types.
```
src/core/
βββ entity.rs β Fundamental traits
β βββ Entity : Base trait (id, type, timestamps, status)
β βββ Data : Inherits Entity, adds name + indexed fields
β βββ Link : Inherits Entity, adds source_id + target_id
β
βββ link.rs β Polymorphic link system
β βββ LinkEntity : Concrete link implementation
β βββ LinkDefinition : Link type configuration
β
βββ field.rs β Types and validation
β βββ FieldValue : Polymorphic value (String, Int, UUID, etc.)
β βββ FieldFormat : Validators (Email, URL, Phone, Custom)
β
βββ service.rs β Service traits
β βββ DataService<T> : CRUD for entities
β βββ LinkService : CRUD for links
β
βββ module.rs β Module system
β βββ Module : Groups entities + config
β βββ EntityFetcher : Fetch entities for link enrichment
β βββ EntityCreator : Create entities dynamically
β
βββ pluralize.rs β Pluralization
β βββ Pluralizer : company β companies
β
βββ auth.rs β Authorization
β βββ AuthProvider : Auth policy provider
β βββ AuthContext : User auth context
β
βββ extractors.rs β HTTP extractors (Axum)
βββ LinkExtractor : Extract link info from URL
βββ DirectLinkExtractor: Extract specific link from URL
```
**Key Principle**: No reference to concrete types (User, Car, etc.) in core.
## π― Entity Hierarchy
The framework provides a 3-level entity hierarchy:
```
βββββββββββββββββββββββββββββββββββββββββββ
β Entity (Base) β
β - id: Uuid (auto-generated) β
β - type: String (auto-set) β
β - created_at: DateTime<Utc> β
β - updated_at: DateTime<Utc> β
β - deleted_at: Option<DateTime<Utc>> β
β - status: String β
βββββββββββββββββββ¬ββββββββββββββββββββββββ
β
ββββββββββ΄βββββββββ
β β
βΌ βΌ
βββββββββββββββββββ βββββββββββββββββββ
β Data Entity β β Link Entity β
β (Inherits) β β (Inherits) β
β β β β
β + name: String β β + source_id β
β + custom fieldsβ β + target_id β
β β β + link_type β
βββββββββββββββββββ βββββββββββββββββββ
```
### Entity (Base Trait)
All entities inherit these fields:
```rust
pub trait Entity {
fn id(&self) -> Uuid;
fn entity_type(&self) -> &str;
fn created_at(&self) -> DateTime<Utc>;
fn updated_at(&self) -> DateTime<Utc>;
fn deleted_at(&self) -> Option<DateTime<Utc>>;
fn status(&self) -> &str;
// Utility methods
fn is_deleted(&self) -> bool;
fn is_active(&self) -> bool;
}
```
### Data (Inherits Entity)
Data entities represent domain objects:
```rust
pub trait Data: Entity {
fn name(&self) -> &str;
fn indexed_fields(&self) -> Vec<&str>;
fn field_value(&self, field_name: &str) -> Option<FieldValue>;
}
```
### Link (Inherits Entity)
Link entities represent relationships:
```rust
pub trait Link: Entity {
fn source_id(&self) -> Uuid;
fn target_id(&self) -> Uuid;
fn link_type(&self) -> &str;
}
```
## π§ Macro System
The framework provides powerful macros to eliminate boilerplate:
### `impl_data_entity!`
Generates a complete Data entity:
```rust
impl_data_entity!(Order, "order", ["name", "number"], {
number: String,
amount: f64,
customer_name: Option<String>,
notes: Option<String>,
});
```
**Generates**:
```rust
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Order {
// Base Entity fields (auto-injected)
pub id: Uuid,
pub entity_type: String,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub deleted_at: Option<DateTime<Utc>>,
pub status: String,
// Data field (auto-injected)
pub name: String,
// Custom fields
pub number: String,
pub amount: f64,
pub customer_name: Option<String>,
pub notes: Option<String>,
}
impl Entity for Order { /* auto-implemented */ }
impl Data for Order { /* auto-implemented */ }
impl Order {
pub fn new(...) -> Self { /* auto-generated constructor */ }
pub fn soft_delete(&mut self) { /* soft delete support */ }
pub fn touch(&mut self) { /* update timestamp */ }
pub fn set_status(&mut self, status: String) { /* status update */ }
pub fn restore(&mut self) { /* restore from soft delete */ }
}
```
### `impl_link_entity!`
Generates a custom Link entity:
```rust
impl_link_entity!(CustomLink, "custom_link", {
metadata_field: String,
});
```
### Field Injection Macros
- `entity_fields!()` - Inject base Entity fields
- `data_fields!()` - Inject Entity + name fields
- `link_fields!()` - Inject Entity + link fields
## π Links Module (Agnostic)
Manages relationships between entities without knowing their types.
```
src/links/
βββ handlers.rs β HTTP handlers (Axum)
β βββ list_links : GET /{entity}/{id}/{route_name}
β βββ get_link : GET /links/{link_id}
β βββ get_link_by_route : GET /{source}/{sid}/{route}/{tid}
β βββ create_link : POST /{source}/{sid}/{route}/{tid}
β βββ create_linked_entity: POST /{source}/{sid}/{route}
β βββ update_link : PUT /{source}/{sid}/{route}/{tid}
β βββ delete_link : DELETE /{source}/{sid}/{route}/{tid}
β
βββ registry.rs β Route resolution
β βββ LinkRouteRegistry : URL β LinkDefinition
β
βββ service.rs β Link service implementation
βββ (moved to storage/)
```
### Generated Routes
From YAML configuration:
```yaml
links:
- link_type: owner
source_type: user
target_type: car
forward_route_name: cars-owned
reverse_route_name: owner
```
**Auto-generated routes**:
```
GET /users/{id}/cars-owned β List cars owned by user
POST /users/{id}/cars-owned β Create new car + link
GET /users/{id}/cars-owned/{car_id} β Get specific link
POST /users/{id}/cars-owned/{car_id} β Link existing car
PUT /users/{id}/cars-owned/{car_id} β Update link metadata
DELETE /users/{id}/cars-owned/{car_id} β Delete link
GET /cars/{id}/owner β Get owner of car (reverse)
```
## π¨ Module System
Modules group related entities and provide services:
```rust
pub trait Module: Send + Sync {
fn name(&self) -> &str;
fn entity_types(&self) -> Vec<&str>;
fn links_config(&self) -> Result<LinksConfig>;
fn register_entities(&self, registry: &mut EntityRegistry);
fn get_entity_fetcher(&self, entity_type: &str) -> Option<Arc<dyn EntityFetcher>>;
fn get_entity_creator(&self, entity_type: &str) -> Option<Arc<dyn EntityCreator>>;
}
```
### EntityFetcher
Dynamically fetches entities for link enrichment:
```rust
#[async_trait]
pub trait EntityFetcher: Send + Sync {
async fn fetch_as_json(&self, entity_id: &Uuid) -> Result<serde_json::Value>;
}
```
**Implementation example**:
```rust
#[async_trait]
impl EntityFetcher for OrderStore {
async fn fetch_as_json(&self, entity_id: &Uuid) -> Result<serde_json::Value> {
let order = self.get(entity_id)
.ok_or_else(|| anyhow::anyhow!("Order not found"))?;
Ok(serde_json::to_value(order)?)
}
}
```
### EntityCreator
Dynamically creates entities with automatic linking:
```rust
#[async_trait]
pub trait EntityCreator: Send + Sync {
async fn create_from_json(&self, entity_data: serde_json::Value) -> Result<serde_json::Value>;
}
```
**Implementation example**:
```rust
#[async_trait]
impl EntityCreator for OrderStore {
async fn create_from_json(&self, entity_data: serde_json::Value) -> Result<serde_json::Value> {
let order = Order::new(
entity_data["number"].as_str().unwrap_or("").to_string(),
entity_data["status"].as_str().unwrap_or("active").to_string(),
// ... other fields
);
self.add(order.clone());
Ok(serde_json::to_value(order)?)
}
}
```
## π Data Flow
### Creating a Link Between Existing Entities
```
1. HTTP Request
POST /users/{user_id}/cars-owned/{car_id}
Body: { "metadata": { "purchase_date": "2024-01-15" } }
2. Axum Handler (create_link)
β DirectLinkExtractor parses URL
β Extracts: source_id, target_id, link_type
3. LinkService.create()
β Creates LinkEntity
β link_type: "owner"
β source_id: user_id (UUID)
β target_id: car_id (UUID)
4. Storage Layer
β Insert LinkEntity
5. Response
β LinkEntity { id, link_type, source_id, target_id, ... }
```
### Creating New Entity + Link Automatically
```
1. HTTP Request
POST /users/{user_id}/cars-owned
Body: {
"entity": { "name": "Tesla Model 3", "brand": "Tesla", ... },
"metadata": { "purchase_date": "2024-01-15" }
}
2. Axum Handler (create_linked_entity)
β LinkExtractor parses URL
β Extracts: source_id, entity_type, route_name
3. Get EntityCreator from Module
β module.get_entity_creator("car")
4. EntityCreator.create_from_json()
β Creates new Car entity
β Stores in database
β Returns created entity with ID
5. LinkService.create()
β Creates link: user_id β car_id
6. Response
β {
"entity": { /* created car */ },
"link": { /* created link */ }
}
```
### Querying Links (Auto-Enriched)
```
1. HTTP Request
GET /users/{user_id}/cars-owned
2. LinkRouteRegistry.resolve_route()
β "user" + "cars-owned"
β β LinkDefinition { link_type: "owner", ... }
β β Direction: Forward
3. LinkService.find_by_source()
β source_id: user_id
β source_type: "user"
β link_type: Some("owner")
β target_type: Some("car")
4. Enrich Links (enrich_links_with_entities)
β For each link:
β - Get EntityFetcher for "car"
β - Fetch full car entity by target_id
β - Embed in link response
5. Response
β {
"links": [
{
"id": "link-123",
"source_id": "user-uuid",
"target_id": "car-uuid",
"target": { /* FULL car entity */ },
"metadata": { /* link metadata */ }
}
]
}
```
**Key**: No N+1 queries! Entities are fetched efficiently.
## π¦ Config Module
Loads and parses YAML configuration:
```
src/config/
βββ mod.rs
βββ LinksConfig : Complete configuration
βββ EntityConfig : Entity configuration
```
**YAML structure**:
```yaml
entities:
- singular: order
plural: orders
- singular: invoice
plural: invoices
links:
- link_type: has_invoice
source_type: order
target_type: invoice
forward_route_name: invoices
reverse_route_name: order
description: "Order has invoices"
auth:
create:
policy: AllowOwner
roles: ["admin", "user"]
```
## ποΈ Storage Layer
```
src/storage/
βββ in_memory.rs β In-memory implementation
β βββ InMemoryLinkService
β
βββ dynamodb.rs β DynamoDB implementation
βββ DynamoDbDataService<T>
βββ DynamoDbLinkService
```
Both implement the same traits:
- `DataService<T>` for entity CRUD
- `LinkService` for link CRUD
## ποΈ Server Architecture
### ServerBuilder
Fluent API for building HTTP servers:
```rust
let app = ServerBuilder::new()
.with_link_service(InMemoryLinkService::new())
.register_module(billing_module)?
.register_module(catalog_module)?
.build()?;
```
**What it does**:
1. Collects all modules
2. Merges YAML configurations
3. Registers all entity descriptors
4. Builds entity CRUD routes
5. Builds generic link routes
6. Collects EntityFetchers
7. Collects EntityCreators
8. Creates AppState
9. Returns complete Axum Router
### EntityRegistry
Collects and builds entity routes:
```rust
pub struct EntityRegistry {
descriptors: Vec<Box<dyn EntityDescriptor>>,
}
impl EntityRegistry {
pub fn register(&mut self, descriptor: Box<dyn EntityDescriptor>);
pub fn build_routes(&self) -> Router;
}
```
## π Key Design Patterns
### 1. Type Erasure
Core framework never knows concrete types:
```rust
// β
Framework uses trait objects
Arc<dyn EntityFetcher>
Arc<dyn EntityCreator>
Arc<dyn DataService<T>>
// β Framework never does this
Arc<OrderStore>
Arc<UserService>
```
### 2. Dynamic Dispatch
Entities are fetched/created dynamically at runtime:
```rust
let fetcher = module.get_entity_fetcher("order")?;
let entity = fetcher.fetch_as_json(&order_id).await?;
```
### 3. Macro-Driven Code Generation
Eliminate boilerplate with compile-time generation:
```rust
// Input: 4 lines
impl_data_entity!(Order, "order", ["name"], {
amount: f64,
});
// Output: 100+ lines of generated code
```
### 4. Configuration-Driven Behavior
Routes and validation defined in YAML:
```yaml
links:
- link_type: owner
source_type: user
target_type: car
forward_route_name: cars-owned
```
### 5. Dependency Injection
Modules provide services through trait methods:
```rust
impl Module for BillingModule {
fn get_entity_fetcher(&self, entity_type: &str) -> Option<Arc<dyn EntityFetcher>> {
match entity_type {
"order" => Some(Arc::new(self.store.orders.clone())),
_ => None,
}
}
}
```
## π Benefits
### For Framework Users
β
**Zero Boilerplate**: Define entities in 4 lines
β
**Auto-Generated Routes**: No manual routing code
β
**Type Safety**: Full Rust compile-time checks
β
**Consistent Patterns**: Same structure everywhere
β
**Link Enrichment**: No N+1 query problems
### For Framework Developers
β
**Extensibility**: Easy to add new storage backends
β
**Testability**: Trait-based design allows mocking
β
**Modularity**: Clear separation of concerns
β
**Maintainability**: Generic core never changes
## π Next Steps
- [Server Builder Implementation](SERVER_BUILDER_IMPLEMENTATION.md)
- [Routing Explanation](ROUTING_EXPLANATION.md)
- [Link Authorization](LINK_AUTH_IMPLEMENTATION.md)
- [Getting Started Guide](../guides/GETTING_STARTED.md)
---
**The architecture is designed for maximum productivity with zero compromise on type safety.** ππ¦β¨