Maravel Framework 10.65 Brings Segregated Relation Definition & Maravel Micro-Framework 10.32.35 With Built-in CruFd Freemium MaravelQL
Maravel-Framework version 10.65.0 is out.
Now you can define your relations like this, in one place in your model:
// model
protected function segregatedRelationsDefinitionMap(): array
{
return [
'relName' => fn(): HasOne => $this->hasOne(Model::class, 'model_id', 'id'),
// Reuse the segregatedrelation inside another segregated relation:
'relNameScoped' => fn(): HasOne => $this->relName()->where('col', '=', 'text'),
'relNameScoped2' => fn(): HasOne => $this->callSegregatedRelation('relName')->where('col', '=', 'text'),
// Reuse the method relation:
'relNameAsMethod' => $this->relNameAsMethod(...),
'relNameAsMethod' => fn(): HasOne => $this->relNameAsMethod(),
// AVOID THIS BECAUSE IT IS NOT Closure and it will not work:
'relNameAsMethod' => [$this, 'relNameAsMethod'],
// AVOID THIS
'relNameAsMethod' => fn(): HasOne => [$this, 'relNameAsMethod'](),
// DO NOT USE IT LIKE THIS!:
'relNameAsMethod' => fn(): HasOne => $this->relNameAsMethod(...)(), // executes the relation inside the map.
];
}And get the whole list by calling segregatedRelationList:
/**
* Get the list of all currently identified relationship keys.
*
* This list includes:
* 1. Explicitly defined relations from
* @see segregatedRelationsDefinitionMap()
* 2. Implicit method-based relations that have been "promoted" to the global
* static map via @see resolveSegregatedRelationClosure()
*
* @param bool $discoverMethods If true, performs a one-time SLOW REFLECTION scan to identify and
* promote all typed relationship methods to the global map.
*
* @note This list is usage-dependent when $discoverMethods is false. If true, the static
* map is force-populated for the remainder of the request lifecycle.
* THE FASTEST WAY for execution is to refactor all method relations by moving them into that map or
* manually promote all method relations to segregated relations via:
* @see segregatedRelationsDefinitionMap()
* return [
* 'relNameAsMethod' => $this->relNameAsMethod(...)
* ]
*
* @return string[]
*/
final public function segregatedRelationList(bool $discoverMethods = false): array
{
if ($discoverMethods) {
$this->promoteMethodRelationsToSegregatedRelations();
}
return \array_keys($this->thisSegregatedRelationDefinitionMap());
}A small increase in execution speed will be introduced with this change because of how isRelation method was refactored.
The documentation was updated.
Version 10.52.35 of Maravel Micro-Framework is out with built-in cruFd (Create, Read, Update, Filter and Delete).
Forget about implementing filters for each of your resource. MaravelQL handles that for you.
It requires the latest Maravel-Framework 10.65 and the laravel-crud-wizard-free lib suite composed of:
Built for Speed: Zero-Overhead Booting
To maintain the fast boot speeds that Maravel is known for (62% more RPS than Lumen 10 on “Hello World”), the CrudProvider is NOT registered in the classic, heavy way.
Instead, its internals are registered via a new laravel_crud_wizard.php config and explicit bindings in App\Application::registerExplicitBindingsMap. Furthermore, the generator’s provider is strictly registered in \App\Application::prepareForConsoleCommand only when running in a composer --dev environment.
Routing & Generation Template
The routes/web.php file now contains a pre-built template for registering your REST endpoints, along with instructions on how to generate the CruFd files based directly on your existing database tables.
<?php
/** @var \App\Router $router */
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all the routes for an application.
| It is a breeze. Simply tell Lumen the URIs it should respond to
| and give it the Closure to call when that URI is requested.
|
*/
$router->get('/', [
'as' => 'version',
'uses' => 'VersionController@version',
]);
/*
| Uncomment in bootstrap/app.php:
|
| $app->withFacades();
| $app->withEloquent();
|
| and use this command to generate the crud files for the below routes (uncomment $app->withEloquent:
| php artisan make:api-resource
| {resourceName} {--decorated} {--table=} {--connection=} {--composed} {--connectionAsModelFolder}
|
| Make sure you have the table in DB before running the command, if you want the columns to be included in the model.
*/
//foreach (
// \MacropaySolutions\LaravelCrudWizard\Helpers\ResourceHelper::getResourceNameToControllerFQNMap(
// \Support\DbCrudMap::MODEL_FQN_TO_CONTROLLER_MAP
// ) as $resource => $controllerFqn
//) {
// $controllerFqnExploded = \explode('\\', $controllerFqn);
// $controller = \end($controllerFqnExploded);
// //$router->get('/' . $resource . '/{identifier}/{relation}', [
// // 'as' => $resource . '.listRelated',
// // 'uses' => $controller . '@listRelation',
// //]); // paid version only
// $router->get('/' . $resource, [
// 'as' => $resource . '.list',
// 'uses' => $controller . '@list',
// ]);
// //$router->post('/' . $resource . '/{identifier}/{relation}/l/i/s/t', [
// // 'as' => $resource . '.post_listRelated',
// // 'uses' => $controller . '@listRelation',
// //]); // paid version only
// $router->post('/' . $resource . '/l/i/s/t', [
// 'as' => $resource . '.post_list',
// 'uses' => $controller . '@list',
// ]);
// $router->post('/' . $resource, [
// 'as' => $resource . '.create',
// 'uses' => $controller . '@create',
// ]);
// $router->put('/' . $resource . '/{identifier}', [
// 'as' => $resource . '.update',
// 'uses' => $controller . '@update',
// ]);
// $router->get('/' . $resource . '/{identifier}', [
// 'as' => $resource . '.get',
// 'uses' => $controller . '@get',
// ]);
// $router->delete('/' . $resource . '/{identifier}', [
// 'as' => $resource . '.delete',
// 'uses' => $controller . '@delete',
// ]);
//
// $router->get('/' . $resource . '/{identifier}/{relation}/{relatedIdentifier}', [
// 'as' => $resource . '.getRelated',
// 'uses' => $controller . '@getRelated',
// ]);
// $router->put('/' . $resource . '/{identifier}/{relation}/{relatedIdentifier}', [
// 'as' => $resource . '.updateRelated',
// 'uses' => $controller . '@updateRelated',
// ]);
// $router->delete('/' . $resource . '/{identifier}/{relation}/{relatedIdentifier}', [
// 'as' => $resource . '.deleteRelated',
// 'uses' => $controller . '@deleteRelated',
// ]);
//}
/*
| for decorated routes add to each of the above routes one of:
| 'middleware' => \App\Http\Middleware\ModelExampleMiddleware::class . ':list'
| 'middleware' => \App\Http\Middleware\Decorators\{PluralModelName}Middleware::class . ':get'
| 'middleware' => \App\Http\Middleware\Decorators\{PluralModelName}Middleware::class . ':getRelated'
| 'middleware' => \App\Http\Middleware\Decorators\{PluralModelName}Middleware::class . ':update'
| 'middleware' => \App\Http\Middleware\Decorators\{PluralModelName}Middleware::class . ':updateRelated'
| 'middleware' => \App\Http\Middleware\Decorators\{PluralModelName}Middleware::class . ':create'
| 'middleware' => \App\Http\Middleware\Decorators\{PluralModelName}Middleware::class . ':delete'
| 'middleware' => \App\Http\Middleware\Decorators\{PluralModelName}Middleware::class . ':deleteRelated'
*/Note that for security concerns, the list via POST routes are appended with /l/i/s/t for cases when the query parameters would contain sensitive data. In the future if the QUERY verb gets implemented, it can replace the list via GET and custom POST.
As you may notice, NO cruFd route is auto-registered. You decide “what”, “when” and “how”.
Next Steps & Microservice Communication
If you want to seamlessly call this project’s API from another PHP service, you can use the dedicated client: laravel-crud-wizard-client-free.
For more details on advanced routing by domain, aliases, middleware, caching, groups, and sessions, refer to the official Maravel docs.
AI Friendly
A .cursorrules file was added to instruct AI agents how to generate the required files for cruFd.
