PHPackages                             marcosbrendon/apiforge - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. marcosbrendon/apiforge

ActiveLibrary[API Development](/categories/api)

marcosbrendon/apiforge
======================

Forge powerful APIs with advanced filtering, pagination, and field selection for Laravel applications

02PHPCI failing

Since Oct 1Pushed 7mo agoCompare

[ Source](https://github.com/MarcosBrendonDePaula/ApiForge)[ Packagist](https://packagist.org/packages/marcosbrendon/apiforge)[ RSS](/packages/marcosbrendon-apiforge/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

ApiForge
========

[](#apiforge)

[![Latest Version on Packagist](https://camo.githubusercontent.com/353028be683c469b384960f0fd0f8c3043aab91b79e8637ad5d2e7f9d00b9ec8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d6172636f736272656e646f6e2f617069666f7267652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/marcosbrendon/apiforge)[![Total Downloads](https://camo.githubusercontent.com/18304a7cc418c6a9fd6fb51dbdba75cb9bf646faf77a35fe86ab2609d657c061/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d6172636f736272656e646f6e2f617069666f7267652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/marcosbrendon/apiforge)[![GitHub Tests Action Status](https://camo.githubusercontent.com/a6910d22335371f63cfcbb2353d791225a9481fad0fc2a91fbfb44277c9cd651/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f4d6172636f734272656e646f6e44655061756c612f417069466f7267652f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/MarcosBrendonDePaula/ApiForge/actions)[![PHP Version Require](https://camo.githubusercontent.com/f0f06d62fc739b57c1a2eb4a0932bf6962f555c95a102ed31ca02638d5157f10/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6d6172636f736272656e646f6e2f617069666f7267653f7374796c653d666c61742d737175617265)](https://packagist.org/packages/marcosbrendon/apiforge)[![Laravel Version](https://camo.githubusercontent.com/857f6af5e53d03ec19456daf55f588f0684324a59e546887c8bae277c0ee3d64/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d3130253242253230253743253230313125324225323025374325323031322532422d7265643f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c)](https://laravel.com)[![GitHub License](https://camo.githubusercontent.com/8c1689046cf7927f033aa3541bc616ab4ba285b4da55cd2d891b1227a52ea71a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f4d6172636f734272656e646f6e44655061756c612f417069466f7267653f7374796c653d666c61742d737175617265)](https://github.com/MarcosBrendonDePaula/ApiForge/blob/main/LICENSE.md)

**Forge powerful APIs with advanced filtering, pagination, and field selection capabilities for Laravel applications.** Build sophisticated APIs with minimal configuration and maximum performance.

✨ Features
----------

[](#-features)

- 🔍 **Advanced Filtering** - 15+ operators (eq, like, gte, between, in, etc.)
- 📄 **Smart Pagination** - Automatic pagination with metadata
- 🎯 **Field Selection** - Optimize queries by selecting only needed fields
- 🔗 **Relationship Support** - Filter and select fields from relationships
- ✨ **Virtual Fields** - Computed fields that can be filtered, sorted, and selected
- 🪝 **Model Hooks** - Lifecycle callbacks for CRUD operations (beforeStore, afterStore, etc.)
- 🛡️ **Security First** - Built-in SQL injection protection and validation
- 📊 **Auto Documentation** - Generate filter metadata and examples automatically
- ⚡ **Performance Focused** - Query optimization and caching support
- 🎨 **Developer Friendly** - Simple configuration, extensive customization

🚀 Quick Start
-------------

[](#-quick-start)

### Installation

[](#installation)

```
composer require marcosbrendon/apiforge
```

### Basic Usage

[](#basic-usage)

1. **Add the trait to your controller:**

```
use MarcosBrendon\\ApiForge\\Traits\\HasAdvancedFilters;

class UserController extends Controller
{
    use HasAdvancedFilters;

    protected function getModelClass(): string
    {
        return User::class;
    }

    public function index(Request $request)
    {
        return $this->indexWithFilters($request);
    }
}
```

2. **Configure your filters:**

```
protected function setupFilterConfiguration(): void
{
    $this->configureFilters([
        'name' => [
            'type' => 'string',
            'operators' => ['eq', 'like', 'ne'],
            'searchable' => true,
            'sortable' => true
        ],
        'email' => [
            'type' => 'string',
            'operators' => ['eq', 'like'],
            'searchable' => true
        ],
        'created_at' => [
            'type' => 'datetime',
            'operators' => ['gte', 'lte', 'between'],
            'sortable' => true
        ]
    ]);
}
```

3. **Configure virtual fields and hooks:**

```
protected function setupFilterConfiguration(): void
{
    // Configure regular filters
    $this->configureFilters([
        'name' => ['type' => 'string', 'operators' => ['eq', 'like']],
        'email' => ['type' => 'string', 'operators' => ['eq', 'like']]
    ]);

    // Configure virtual fields
    $this->configureVirtualFields([
        'full_name' => [
            'type' => 'string',
            'callback' => fn($user) => trim($user->first_name . ' ' . $user->last_name),
            'dependencies' => ['first_name', 'last_name'],
            'operators' => ['eq', 'like'],
            'searchable' => true,
            'sortable' => true
        ]
    ]);

    // Configure model hooks
    $this->configureModelHooks([
        'beforeStore' => [
            'generateSlug' => fn($model) => $model->slug = Str::slug($model->title)
        ],
        'afterStore' => [
            'sendNotification' => fn($model) => NotificationService::send($model)
        ]
    ]);
}
```

4. **Use the API:**

```
# Basic filtering
GET /api/users?name=John&email=*@gmail.com

# Virtual field filtering
GET /api/users?full_name=John*&fields=id,full_name

# Field selection
GET /api/users?fields=id,name,email

# Pagination
GET /api/users?page=2&per_page=20

# Advanced filtering
GET /api/users?name=John*&created_at=>=2024-01-01&sort_by=name

# Relationship filtering
GET /api/users?fields=id,name,company.name&company.active=true
```

📖 Documentation
---------------

[](#-documentation)

### Available Operators

[](#available-operators)

OperatorDescriptionExample`eq`Equals`name=John``ne`Not equals`name=!=John``like`Contains (use `*` as wildcard)`name=John*``not_like`Does not contain`name=!*John``gt`Greater than`age=>18``gte`Greater than or equal`age=>=18``lt`Less than`age=configureFilters([
    'status' => [
        'type' => 'enum',
        'values' => ['active', 'inactive', 'pending'],
        'operators' => ['eq', 'in'],
        'description' => 'User account status',
        'example' => [
            'eq' => 'status=active',
            'in' => 'status=active,pending'
        ]
    ],
    'created_at' => [
        'type' => 'datetime',
        'operators' => ['gte', 'lte', 'between'],
        'format' => 'Y-m-d H:i:s',
        'sortable' => true,
        'description' => 'User registration date'
    ]
]);
```

### Middleware Configuration

[](#middleware-configuration)

Add the middleware to automatically validate and sanitize requests:

```
// In your route group
Route::group(['middleware' => ['api', 'apiforge']], function () {
    Route::get('/users', [UserController::class, 'index']);
});
```

### Auto-Documentation

[](#auto-documentation)

Get filter metadata and examples automatically:

```
# Get available filters and configuration
GET /api/users/metadata

# Get usage examples
GET /api/users/examples
```

🌟 Virtual Fields
----------------

[](#-virtual-fields)

Virtual fields are computed fields that don't exist in your database but can be filtered, sorted, and selected like regular fields. They're calculated on-demand using custom callback functions.

### Basic Virtual Field

[](#basic-virtual-field)

```
protected function setupFilterConfiguration(): void
{
    $this->configureVirtualFields([
        'display_name' => [
            'type' => 'string',
            'callback' => function($user) {
                return $user->name ?: $user->email;
            },
            'dependencies' => ['name', 'email'],
            'operators' => ['eq', 'like'],
            'searchable' => true,
            'sortable' => true
        ]
    ]);
}
```

### Relationship-Based Virtual Fields

[](#relationship-based-virtual-fields)

```
'order_count' => [
    'type' => 'integer',
    'callback' => function($user) {
        return $user->orders_count ?? $user->orders->count();
    },
    'relationships' => ['orders'],
    'operators' => ['eq', 'gt', 'gte', 'lt', 'lte'],
    'cacheable' => true,
    'cache_ttl' => 1800
],

'total_spent' => [
    'type' => 'float',
    'callback' => function($user) {
        return $user->orders->sum('total');
    },
    'relationships' => ['orders'],
    'operators' => ['eq', 'gt', 'gte', 'lt', 'lte', 'between'],
    'cacheable' => true,
    'cache_ttl' => 3600
]
```

### Complex Business Logic Virtual Fields

[](#complex-business-logic-virtual-fields)

```
'customer_tier' => [
    'type' => 'enum',
    'values' => ['bronze', 'silver', 'gold', 'platinum'],
    'callback' => function($user) {
        $totalSpent = $user->orders->sum('total');
        if ($totalSpent >= 10000) return 'platinum';
        if ($totalSpent >= 5000) return 'gold';
        if ($totalSpent >= 1000) return 'silver';
        return 'bronze';
    },
    'relationships' => ['orders'],
    'operators' => ['eq', 'in', 'ne'],
    'cacheable' => true,
    'cache_ttl' => 3600
],

'age' => [
    'type' => 'integer',
    'callback' => function($user) {
        return $user->birth_date ?
            Carbon::parse($user->birth_date)->age : null;
    },
    'dependencies' => ['birth_date'],
    'operators' => ['eq', 'gt', 'gte', 'lt', 'lte', 'between'],
    'nullable' => true
]
```

### Virtual Field Configuration Options

[](#virtual-field-configuration-options)

OptionTypeDescription`type`stringField type (string, integer, float, boolean, enum, datetime)`callback`callableFunction to compute the field value`dependencies`arrayDatabase fields required for computation`relationships`arrayEloquent relationships to eager load`operators`arrayAllowed filter operators`cacheable`booleanEnable caching for computed values`cache_ttl`integerCache time-to-live in seconds`nullable`booleanAllow null values`default_value`mixedDefault value when computation fails`searchable`booleanInclude in search operations`sortable`booleanAllow sorting by this field### Using Virtual Fields in API Calls

[](#using-virtual-fields-in-api-calls)

```
# Filter by virtual fields
GET /api/users?customer_tier=gold&age=>=25

# Sort by virtual fields
GET /api/users?sort_by=total_spent&sort_direction=desc

# Select virtual fields
GET /api/users?fields=id,name,customer_tier,total_spent

# Combine with regular fields
GET /api/users?name=John*&customer_tier=gold,platinum&fields=id,name,total_spent
```

🪝 Model Hooks
-------------

[](#-model-hooks)

Model hooks provide lifecycle callbacks that execute custom logic during CRUD operations. They're perfect for audit logging, notifications, data validation, and business rule enforcement.

### Available Hook Types

[](#available-hook-types)

- `beforeStore` - Before creating a new record
- `afterStore` - After successfully creating a record
- `beforeUpdate` - Before updating an existing record
- `afterUpdate` - After successfully updating a record
- `beforeDelete` - Before deleting a record (can prevent deletion)
- `afterDelete` - After successfully deleting a record

### Basic Hook Configuration

[](#basic-hook-configuration)

```
protected function setupFilterConfiguration(): void
{
    $this->configureModelHooks([
        'beforeStore' => [
            'generateSlug' => function($model, $context) {
                if (empty($model->slug) && !empty($model->title)) {
                    $model->slug = Str::slug($model->title);
                }
            },
            'validateBusinessRules' => function($model, $context) {
                if ($model->type === 'premium' && !$model->user->isPremium()) {
                    throw new ValidationException('User must be premium');
                }
            }
        ],

        'afterStore' => [
            'sendNotification' => function($model, $context) {
                NotificationService::send($model->user, 'ItemCreated', $model);
            },
            'updateCache' => function($model, $context) {
                Cache::forget("user_items_{$model->user_id}");
            }
        ]
    ]);
}
```

### Advanced Hook Features

[](#advanced-hook-features)

#### Priority-Based Execution

[](#priority-based-execution)

```
'afterStore' => [
    'criticalNotification' => [
        'callback' => function($model, $context) {
            // Critical notification logic
        },
        'priority' => 1  // Higher priority (executes first)
    ],
    'regularNotification' => [
        'callback' => function($model, $context) {
            // Regular notification logic
        },
        'priority' => 10  // Lower priority (executes later)
    ]
]
```

#### Conditional Hook Execution

[](#conditional-hook-execution)

```
'beforeStore' => [
    'validatePremiumFeatures' => [
        'callback' => function($model, $context) {
            // Validation logic for premium features
        },
        'conditions' => [
            'field' => 'type',
            'operator' => 'eq',
            'value' => 'premium'
        ]
    ]
]
```

#### Hooks That Can Prevent Operations

[](#hooks-that-can-prevent-operations)

```
'beforeDelete' => [
    'checkPermissions' => [
        'callback' => function($model, $context) {
            if (!auth()->user()->canDelete($model)) {
                throw new UnauthorizedException('Cannot delete this resource');
            }
            return true; // Allow deletion
        },
        'stopOnFailure' => true
    ],
    'checkDependencies' => function($model, $context) {
        if ($model->orders()->exists()) {
            throw new ValidationException('Cannot delete user with existing orders');
        }
        return true;
    }
]
```

### Hook Context

[](#hook-context)

Hooks receive a context object with useful information:

```
'afterUpdate' => [
    'trackChanges' => function($model, $context) {
        // Access request data
        $request = $context->request;

        // Access the operation type
        $operation = $context->operation; // 'store', 'update', 'delete'

        // Access additional data
        $changes = $context->get('changes', []);

        // Log the changes
        AuditLog::create([
            'model_type' => get_class($model),
            'model_id' => $model->id,
            'changes' => $model->getDirty(),
            'user_id' => auth()->id(),
            'ip_address' => $request->ip()
        ]);
    }
]
```

### Common Hook Patterns

[](#common-hook-patterns)

#### Audit Logging

[](#audit-logging)

```
'beforeUpdate' => [
    'auditChanges' => function($model, $context) {
        $changes = $model->getDirty();
        if (!empty($changes)) {
            AuditLog::create([
                'model_type' => get_class($model),
                'model_id' => $model->id,
                'changes' => $changes,
                'user_id' => auth()->id()
            ]);
        }
    }
]
```

#### Automatic Timestamps and User Tracking

[](#automatic-timestamps-and-user-tracking)

```
'beforeStore' => [
    'setCreatedBy' => fn($model) => $model->created_by = auth()->id()
],
'beforeUpdate' => [
    'setUpdatedBy' => fn($model) => $model->updated_by = auth()->id()
]
```

#### Cache Management

[](#cache-management)

```
'afterStore' => [
    'clearCache' => fn($model) => Cache::tags(['users'])->flush()
],
'afterUpdate' => [
    'updateCache' => function($model, $context) {
        Cache::forget("user_{$model->id}");
        Cache::put("user_{$model->id}", $model, 3600);
    }
]
```

#### File Cleanup

[](#file-cleanup)

```
'afterDelete' => [
    'cleanupFiles' => function($model, $context) {
        if ($model->avatar) {
            Storage::delete($model->avatar);
        }
        if ($model->documents) {
            foreach ($model->documents as $doc) {
                Storage::delete($doc->path);
            }
        }
    }
]
```

🔧 Advanced Configuration
------------------------

[](#-advanced-configuration)

### Custom Base Controller

[](#custom-base-controller)

Extend the base controller for common functionality:

```
use MarcosBrendon\\ApiForge\\Http\\Controllers\\BaseApiController;

class ApiController extends BaseApiController
{
    protected function getDefaultPerPage(): int
    {
        return 25;
    }

    protected function getMaxPerPage(): int
    {
        return 500;
    }
}
```

### Custom Field Selection

[](#custom-field-selection)

Configure field selection with aliases and validation:

```
protected function configureFieldSelection(): void
{
    $this->fieldSelection([
        'selectable_fields' => ['id', 'name', 'email', 'company.name'],
        'required_fields' => ['id'],
        'blocked_fields' => ['password', 'remember_token'],
        'default_fields' => ['id', 'name', 'email'],
        'field_aliases' => [
            'user_id' => 'id',
            'user_name' => 'name',
            'company_name' => 'company.name'
        ],
        'max_fields' => 50
    ]);
}
```

### Caching

[](#caching)

Enable query caching for better performance:

```
public function index(Request $request)
{
    return $this->indexWithFilters($request, [
        'cache' => true,
        'cache_ttl' => 3600, // 1 hour
        'cache_tags' => ['users', 'api']
    ]);
}
```

### Virtual Fields and Hooks Configuration

[](#virtual-fields-and-hooks-configuration)

Configure advanced features in your controller:

```
protected function setupFilterConfiguration(): void
{
    // Regular filters
    $this->configureFilters([
        'name' => ['type' => 'string', 'operators' => ['eq', 'like']],
        'status' => ['type' => 'enum', 'values' => ['active', 'inactive']]
    ]);

    // Virtual fields with caching
    $this->configureVirtualFields([
        'full_name' => [
            'type' => 'string',
            'callback' => fn($user) => trim($user->first_name . ' ' . $user->last_name),
            'dependencies' => ['first_name', 'last_name'],
            'operators' => ['eq', 'like'],
            'cacheable' => true,
            'cache_ttl' => 3600
        ],
        'customer_tier' => [
            'type' => 'enum',
            'values' => ['bronze', 'silver', 'gold', 'platinum'],
            'callback' => [$this, 'calculateCustomerTier'],
            'relationships' => ['orders'],
            'cacheable' => true,
            'cache_ttl' => 1800
        ]
    ]);

    // Model hooks with priorities
    $this->configureModelHooks([
        'beforeStore' => [
            'validateData' => [
                'callback' => [$this, 'validateBusinessRules'],
                'priority' => 1
            ],
            'generateSlug' => [
                'callback' => fn($model) => $model->slug = Str::slug($model->title),
                'priority' => 5
            ]
        ],
        'afterStore' => [
            'sendNotification' => fn($model) => NotificationService::send($model),
            'updateCache' => fn($model) => Cache::forget("users_list")
        ]
    ]);
}

private function calculateCustomerTier($user)
{
    $totalSpent = $user->orders->sum('total');
    if ($totalSpent >= 10000) return 'platinum';
    if ($totalSpent >= 5000) return 'gold';
    if ($totalSpent >= 1000) return 'silver';
    return 'bronze';
}

private function validateBusinessRules($model, $context)
{
    if ($model->type === 'premium' && !$model->user->isPremium()) {
        throw new ValidationException('User must be premium for this type');
    }
}
```

⚡ Performance Optimization
--------------------------

[](#-performance-optimization)

### Virtual Fields Performance

[](#virtual-fields-performance)

Virtual fields include several performance optimization features:

#### 1. Caching

[](#1-caching)

```
'expensive_calculation' => [
    'type' => 'float',
    'callback' => function($model) {
        // Expensive computation
        return $this->performComplexCalculation($model);
    },
    'cacheable' => true,
    'cache_ttl' => 3600, // Cache for 1 hour
    'relationships' => ['orders', 'payments']
]
```

#### 2. Dependency Optimization

[](#2-dependency-optimization)

```
'user_summary' => [
    'type' => 'string',
    'callback' => function($model) {
        return "{$model->name} ({$model->email}) - {$model->orders_count} orders";
    },
    'dependencies' => ['name', 'email'], // Only load these fields
    'relationships' => ['orders'] // Eager load with count
]
```

#### 3. Batch Processing

[](#3-batch-processing)

Virtual fields are automatically computed in batches for better performance:

```
// This will compute virtual fields for all users in a single batch
GET /api/users?fields=id,name,customer_tier&per_page=100
```

#### 4. Lazy Loading

[](#4-lazy-loading)

Virtual fields are only computed when requested:

```
// Virtual fields not computed (not requested)
GET /api/users?fields=id,name,email

// Virtual fields computed only for selected fields
GET /api/users?fields=id,name,customer_tier,total_spent
```

### Performance Configuration

[](#performance-configuration)

Configure performance limits in your config file:

```
// config/apiforge.php
'virtual_fields' => [
    'cache' => [
        'enabled' => true,
        'default_ttl' => 3600,
        'driver' => 'redis' // or 'database', 'file'
    ],
    'performance' => [
        'memory_limit' => '256M',
        'time_limit' => 30, // seconds
        'batch_size' => 100,
        'max_virtual_fields' => 20
    ]
]
```

### Hook Performance

[](#hook-performance)

Model hooks are designed for minimal performance impact:

#### 1. Conditional Execution

[](#1-conditional-execution)

```
'expensiveHook' => [
    'callback' => function($model, $context) {
        // Only run for specific conditions
        $this->performExpensiveOperation($model);
    },
    'conditions' => [
        'field' => 'type',
        'operator' => 'eq',
        'value' => 'premium'
    ]
]
```

#### 2. Async Processing

[](#2-async-processing)

```
'afterStore' => [
    'sendEmail' => function($model, $context) {
        // Queue for background processing
        SendWelcomeEmail::dispatch($model)->delay(now()->addMinutes(5));
    }
]
```

### General Performance Tips

[](#general-performance-tips)

1. **Use field selection** to reduce data transfer:

    ```
    GET /api/users?fields=id,name,email,customer_tier
    ```
2. **Enable caching** for expensive virtual fields:

    ```
    'cacheable' => true,
    'cache_ttl' => 3600
    ```
3. **Optimize database queries** with proper indexing:

    ```
    // Add indexes for fields used in virtual field dependencies
    Schema::table('users', function (Blueprint $table) {
        $table->index(['first_name', 'last_name']);
        $table->index('birth_date');
    });
    ```
4. **Use relationship counting** instead of loading full relationships:

    ```
    'order_count' => [
        'callback' => function($user) {
            return $user->orders_count ?? $user->orders()->count();
        }
    ]
    ```
5. **Configure appropriate pagination**:

    ```
    'pagination' => [
        'default_per_page' => 15,
        'max_per_page' => 100,
    ]
    ```

🧪 Testing
---------

[](#-testing)

```
composer test
```

🚀 Production Ready
------------------

[](#-production-ready)

ApiForge is production-ready with:

- ✅ **11 comprehensive tests** covering all features
- ✅ **Security** - Built-in SQL injection protection
- ✅ **Performance** - Query optimization and caching
- ✅ **Compatibility** - PHP 8.1+ and Laravel 10/11/12+
- ✅ **CI/CD** - Automated testing with GitHub Actions
- ✅ **Documentation** - Complete API documentation

### Performance Tips

[](#performance-tips)

1. **Enable caching** for better performance:

    ```
    // config/apiforge.php
    'cache' => [
        'enabled' => true,
        'ttl' => 3600,
    ],
    ```
2. **Use field selection** to reduce data transfer:

    ```
    GET /api/users?fields=id,name,email
    ```
3. **Configure appropriate pagination**:

    ```
    'pagination' => [
        'default_per_page' => 15,
        'max_per_page' => 100,
    ],
    ```

📝 Changelog
-----------

[](#-changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

🤝 Contributing
--------------

[](#-contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

🔒 Security Vulnerabilities
--------------------------

[](#-security-vulnerabilities)

Please review [our security policy](https://github.com/MarcosBrendonDePaula/ApiForge/security/policy) on how to report security vulnerabilities.

📄 License
---------

[](#-license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

🙏 Credits
---------

[](#-credits)

- [Marcos Brendon](https://github.com/MarcosBrendonDePaula)
- [All Contributors](https://github.com/MarcosBrendonDePaula/ApiForge/contributors)

💡 Why This Package?
-------------------

[](#-why-this-package)

This package was born from the need to create sophisticated APIs with advanced filtering capabilities while maintaining clean, maintainable code. It combines the power of Laravel's Eloquent ORM with a flexible, configuration-driven approach to API development.

### Key Differentiators:

[](#key-differentiators)

- **More operators** than similar packages (15+ vs 5-8)
- **Virtual fields** - Computed fields that can be filtered and sorted like database fields
- **Model hooks** - Comprehensive lifecycle callbacks for CRUD operations
- **Built-in security** with automatic validation and sanitization
- **Auto-documentation** generates API docs automatically
- **Performance focused** with query optimization, caching, and batch processing
- **Developer experience** with simple configuration and extensive examples
- **Production ready** with comprehensive testing and error handling

### Advanced Features:

[](#advanced-features)

- **Virtual Fields**: Create computed fields like `full_name`, `age`, `customer_tier` that can be filtered, sorted, and selected
- **Model Hooks**: Execute custom logic during CRUD operations with `beforeStore`, `afterStore`, `beforeUpdate`, `afterUpdate`, `beforeDelete`, `afterDelete`
- **Performance Optimization**: Built-in caching, batch processing, and query optimization for virtual fields
- **Business Logic Integration**: Perfect for audit logging, notifications, data validation, and complex business rules
- **Seamless Integration**: Virtual fields and hooks work with all existing ApiForge features

---

Made with ❤️ by [Marcos Brendon](https://github.com/MarcosBrendonDePaula)

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance45

Moderate activity, may be stable

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity13

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/f970b4eac4e48ec8ba8f91d34ae390fb71ca1c06fa3abf1a39eee2508c062878?d=identicon)[MarcosBrendonDePaula](/maintainers/MarcosBrendonDePaula)

---

Top Contributors

[![MarcosBrendonDePaula](https://avatars.githubusercontent.com/u/46361998?v=4)](https://github.com/MarcosBrendonDePaula "MarcosBrendonDePaula (21 commits)")

### Embed Badge

![Health badge](/badges/marcosbrendon-apiforge/health.svg)

```
[![Health](https://phpackages.com/badges/marcosbrendon-apiforge/health.svg)](https://phpackages.com/packages/marcosbrendon-apiforge)
```

###  Alternatives

[stripe/stripe-php

Stripe PHP Library

4.0k143.3M475](/packages/stripe-stripe-php)[twilio/sdk

A PHP wrapper for Twilio's API

1.6k92.9M270](/packages/twilio-sdk)[knplabs/github-api

GitHub API v3 client

2.2k15.8M187](/packages/knplabs-github-api)[facebook/php-business-sdk

PHP SDK for Facebook Business

90121.9M34](/packages/facebook-php-business-sdk)[meilisearch/meilisearch-php

PHP wrapper for the Meilisearch API

73813.7M114](/packages/meilisearch-meilisearch-php)[google/gax

Google API Core for PHP

263103.1M452](/packages/google-gax)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
