DEV Community

Astra Techno
Astra Techno

Posted on

Beyond MVC: Redefining Backend Development with DataForge

In the world of backend frameworks, the MVC (Model-View-Controller) architecture has become the de facto standard for organizing application layers. Tools like Laravel's Eloquent ORM provide an excellent structure for most use cases, but as projects grow in complexity, developers often face challenges:

  1. How do you manage modular and reusable SQL logic without duplicating code?

  2. How do you efficiently adapt queries to return different result formats like lists, single rows, or single columns?

  3. How do you build advanced inter-entity relationships and lazy-load attributes for optimal performance?

  4. How do you design APIs that are both powerful and easy to scale?

These challenges led to the creation of DataForge, a Laravel-based framework that goes beyond MVC. Unlike traditional frameworks, DataForge introduces a product-first approach to backend development, addressing real-world needs like modularity, scalability, and maintainability.


Why DataForge Stands Out

1. Modular SQL Class Architecture

Eloquent simplifies database interactions but often requires repetitive code for different query formats (e.g., fetching lists vs. single rows).

DataForge Solution: SQL classes in DataForge allow developers to write reusable query logic in one place while providing modular select types to handle multiple use cases effortlessly.

Example:

php

$query = new Query('ProductList');
$query->select('list', 'p.id, p.name, p.price, c.name AS category'); 
$query->select('item', 'p.id, p.name, p.description, p.price, c.name AS category');
$query->select('options', 'p.id, p.name'); 
$query->select('total', 'COUNT(p.id) AS totalCount'); 
$query->filterOptional('p.category_id = {category_id}'); 
$query->filterOptional('p.name LIKE {%keyword%}'); 
$query->order('{sort}', '{order}');
Enter fullscreen mode Exit fullscreen mode

With this structure, you can reuse the same query logic to fetch:

  • A list of products:

$products = Sql('Product:list', ['select' => 'list'])->fetchRowList();

  • Details for a single product:

$product = Sql('Product:list', ['select' => 'item', 'id' => 123])->fetchRow();

  • A total count:

$count = Sql('Product:list', ['select' => 'total'])->fetchColumn();


2. Advanced Entity Features

Eloquent models often mix data access with business logic, leading to less maintainable code. DataForge’s Entity class enhances modularity by cleanly separating these concerns while introducing advanced features:

  • Lazy Loading: Entity attributes are only loaded when accessed, improving performance by avoiding unnecessary queries.
  $product = DataForge::getProduct(123); 
  echo $product->Price; // Triggers the `getPrice()` method only when accessed.
Enter fullscreen mode Exit fullscreen mode
  • Inter-Entity Connectivity: Build seamless relationships between entities, making it easier to fetch related data.
  $product = DataForge::getProduct(123); 

  $category = $product->Category; // Directly fetches the related Category entity.
Enter fullscreen mode Exit fullscreen mode

Example: Product Entity

class Product extends Entity
{
    function init($id)
    {
        return \Sql('Product:list', ['id' => $id, 'select' => 'entity'])->fetchRow();
    }

    function getCategory()
    {
        return DataForge::getCategory($this->category_id);
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Versatile API Endpoints

DataForge provides 7 powerful API endpoints, offering developers a structured, scalable way to interact with their backend systems:

  • /api/list: Fetch paginated lists of records.

  • /api/all: Fetch all matched records without pagination.

  • /api/item: Retrieve a single record.

  • /api/field: Fetch a single column value.

  • /api/entity: Work directly with entities, including lazy-loaded attributes and inter-entity relationships.

  • /api/Task: Handle complex workflows, combining SQL and Entity operations.

  • /api/GuestTask: Provide secure, limited guest access to specific workflows.

Example: Fetching paginated product lists

/api/list/Product:list?keyword=test&pageNo=1&limit=10&sort=price&order=asc
Enter fullscreen mode Exit fullscreen mode

Response:

json

{
  "total": 150,
  "items": [
    {"id": 1, "name": "Laptop", "price": 1000.00, "category": "Electronics"},
    {"id": 2, "name": "Headphones", "price": 50.00, "category": "Accessories"},
    {"id": 3, "name": "Smartphone", "price": 800.00, "category": "Electronics"},
    {"id": 4, "name": "Watch", "price": 200.00, "category": "Accessories"},
    {"id": 5, "name": "T-Shirt", "price": 25.00, "category": "Clothing"},
    {"id": 6, "name": "Jeans", "price": 70.00, "category": "Clothing"},
    {"id": 7, "name": "Shoes", "price": 120.00, "category": "Shoes"},
    {"id": 8, "name": "Book", "price": 15.00, "category": "Books"},
    {"id": 9, "name": "Game Console", "price": 300.00, "category": "Electronics"},
    {"id": 10, "name": "Sunglasses", "price": 50.00, "category": "Accessories"}
  ]
}
Enter fullscreen mode Exit fullscreen mode

Example: Fetching product lists

/api/all/Product:list?&limit=5&select=options
Enter fullscreen mode Exit fullscreen mode

Response:

json

[
    {"id": 1, "name": "Laptop"},
    {"id": 2, "name": "Headphones"},
    {"id": 3, "name": "Smartphone"},
    {"id": 4, "name": "Watch"},
    {"id": 5, "name": "T-Shirt"},
]
Enter fullscreen mode Exit fullscreen mode

Example: Fetching single record

/api/item/Product:list?id=7
Enter fullscreen mode Exit fullscreen mode

Response:

json

{"id": 7, "name": "Shoes", "description":"Beautiful kids shoes" "price": 120.00, "category": "Shoes"}
Enter fullscreen mode Exit fullscreen mode

Example: Fetching single column

/api/field/Product:list?select=total
Enter fullscreen mode Exit fullscreen mode

Response:

json

150
Enter fullscreen mode Exit fullscreen mode

By combining modular SQL classes and these endpoints, developers can create robust APIs with minimal effort while maintaining flexibility and scalability.


4. SQL-Based Workflows

Traditional frameworks often require different methods to fetch lists, single rows, or aggregated data.

DataForge Solution: By defining modular select types in SQL classes, developers can dynamically adjust queries to return the desired data format without rewriting logic.


How DataForge Enhances Laravel

By integrating DataForge into your Laravel projects, you can:

  • Streamline Query Logic: Write modular SQL queries once and reuse them dynamically.

  • Enhance Entity Relationships: Build advanced inter-entity relationships and lazy-loaded attributes.

  • Adapt Easily: Fetch data in multiple formats (list, row, column) without duplicating logic.

  • Design Powerful APIs: Use pre-built endpoints to simplify API development.

  • Ensure Performance and Security: Features like filterOptional and filterAnyOneRequired ensure precise filtering and safe query execution.


Learn More and Get Started

DataForge is a complete backend development toolkit, not just another framework. It’s designed to help developers build structured, scalable products effortlessly.

We’d love to hear your feedback! How do you think DataForge compares with your current tools? Let’s start a discussion.


Call to Action

  • How do you currently manage SQL queries, API endpoints, and entity relationships in your projects?

  • What challenges do you face with traditional ORM tools like Eloquent?

Let’s collaborate to redefine backend development.

Top comments (0)