Routing
FluentCRM Core IntermediateFluentCRM's router is available via the fluentcrm_loaded action. All routes you register are served under /wp-json/fluent-crm/v2/.
Registering Routes
Hook into fluentcrm_loaded to access the $app->router:
add_action('fluentcrm_loaded', function ($app) {
$app->router->get('/my-endpoint', 'MyPlugin\Controllers\MyController@index');
});This registers a GET endpoint at /wp-json/fluent-crm/v2/my-endpoint.
HTTP Methods
The router supports all standard HTTP verbs:
$router->get($uri, $callback);
$router->post($uri, $callback);
$router->put($uri, $callback);
$router->patch($uri, $callback);
$router->delete($uri, $callback);
$router->any($uri, $callback); // responds to all HTTP methodsTIP
FluentCRM's JavaScript REST client sends PUT, PATCH, and DELETE as POST requests with an X-HTTP-Method-Override header. The framework handles this automatically.
Route Callbacks
Callbacks can be a Controller@method string or a closure:
// Controller string (recommended)
$router->get('/items', 'MyPlugin\Controllers\ItemController@index');
// Closure
$router->get('/ping', function () {
return ['status' => 'ok'];
});Route Groups
Group routes that share a prefix, policy, or namespace:
add_action('fluentcrm_loaded', function ($app) {
$app->router
->prefix('my-plugin')
->namespace('MyPlugin\Controllers')
->withPolicy('MyPlugin\Policies\MyPolicy')
->group(function ($router) {
$router->get('/', 'ItemController@index'); // GET /my-plugin/
$router->get('/items', 'ItemController@list'); // GET /my-plugin/items
$router->post('/items', 'ItemController@create'); // POST /my-plugin/items
$router->put('/items/{id}', 'ItemController@update'); // PUT /my-plugin/items/{id}
$router->delete('/items/{id}', 'ItemController@delete'); // DELETE /my-plugin/items/{id}
});
});Group Methods
| Method | Description |
|---|---|
prefix($prefix) | Prepends a URL prefix to all routes in the group |
namespace($ns) | Sets the controller namespace so you can use short class names |
withPolicy($class) | Applies a policy class for authorization (see Policies) |
group($callback) | Defines the route group; receives $router as argument |
All group methods are optional and chainable. You can register routes without a group:
$app->router->post('/my-endpoint', 'MyPlugin\Controllers\MyController@create');Route Parameters
Define dynamic segments using {param} syntax:
$router->get('/contacts/{id}', 'ContactController@show');Parameters are passed as arguments to the controller method:
public function show($id)
{
$contact = Subscriber::findOrFail($id);
return $this->sendSuccess(['contact' => $contact]);
}Parameter Constraints
Chain constraint methods to validate parameter formats:
| Method | Accepts |
|---|---|
int($param) | Integers only |
alpha($param) | Alphabetic characters only |
alphaNum($param) | Alphanumeric characters |
alphaNumDash($param) | Alphanumeric, dashes, and underscores |
where($param, $regex) | Custom regex pattern |
// Single constraint
$router->get('/contacts/{id}', 'ContactController@show')->int('id');
// Multiple constraints
$router->get('/contacts/{id}/{slug}', 'ContactController@show')
->int('id')
->alpha('slug');
// Custom regex
$router->get('/reports/{type}', 'ReportController@show')
->where('type', '[a-z_]+');Without Groups
Routes registered without prefix() or group() are available directly under the FluentCRM base URL:
add_action('fluentcrm_loaded', function ($app) {
$app->router->get('/health-check', function () {
return ['status' => 'ok', 'timestamp' => current_time('mysql')];
});
});
// Accessible at: /wp-json/fluent-crm/v2/health-checkNested Groups
You can nest groups for more complex URL structures:
$app->router
->prefix('my-plugin')
->withPolicy('MyPlugin\Policies\MyPolicy')
->group(function ($router) {
$router->get('/', 'MyPlugin\Controllers\DashboardController@index');
$router->prefix('reports')->group(function ($router) {
$router->get('/', 'MyPlugin\Controllers\ReportController@index');
$router->get('/{id}', 'MyPlugin\Controllers\ReportController@show')->int('id');
});
});
// Routes:
// GET /my-plugin/
// GET /my-plugin/reports/
// GET /my-plugin/reports/{id}Source: vendor/wpfluent/framework/src/WPFluent/Http/Router.php, vendor/wpfluent/framework/src/WPFluent/Http/Route.php