Routes & Controllers
Define API routes with LogisBase route macros, choose the right middleware group, and build resource controllers backed by HasApiControllerBehavior.
Routes & Controllers
Routes for an extension live in server/src/routes.php (loaded by your service provider via loadRoutesFrom). Route definitions follow Laravel conventions — LogisBase adds three macros that take care of the boilerplate.
The Routes File
<?php
use Illuminate\Support\Facades\Route;
Route::prefix(config('my-extension.api.routing.prefix', 'my-extension'))
->namespace('MyOrg\MyExtension\Http\Controllers')
->group(function ($router) {
// Public webhook callbacks — no auth
$router->post('webhooks/inbound', 'WebhookController@inbound');
// Internal console — session-authenticated
$router->group(['middleware' => ['logisbase.protected']], function ($router) {
$router->logisbaseRoutes('widgets');
$router->logisbaseRoutes('reports', function ($router, $controller) {
$router->get('summary', $controller('summary'));
$router->post('export', $controller('export'));
});
});
// Public API — API-key authenticated
$router->group(['prefix' => 'v1', 'middleware' => ['logisbase.api']], function ($router) {
$router->logisbaseRestRoutes('widgets');
});
});Real example: pallet/server/src/routes.php.
Route Macros
logisbase/core-api defines three route macros via Route expansion:
logisbaseRestRoutes($name, $controller = null, $options = [], $callback = null)
Registers the seven REST routes for a resource:
| Verb | Path | Action |
|---|---|---|
GET | /widgets | index |
POST | /widgets | store |
GET | /widgets/{id} | show |
PUT/PATCH | /widgets/{id} | update |
DELETE | /widgets/{id} | destroy |
POST | /widgets/bulk-delete | bulkDelete (LogisBase extra) |
GET | /widgets/export | export (LogisBase extra) |
The controller defaults to WidgetController (singular-studly + Controller) when omitted.
$router->logisbaseRestRoutes('widgets'); // → WidgetController
$router->logisbaseRestRoutes('widgets', 'CustomWidgetController');logisbaseRoutes($name, $registerFn = null, $options = [], $controller = null)
Same as logisbaseRestRoutes but lets you nest extra routes under the same prefix and controller:
$router->logisbaseRoutes('widgets', function ($router, $controller) {
$router->get('archived', $controller('archived'));
$router->post('{id}/duplicate', $controller('duplicate'));
});
// Registers: /widgets/archived, /widgets/{id}/duplicate, plus the standard REST routesThe $controller callback returns 'WidgetController@actionName' strings.
logisbaseAuthRoutes($authControllerClass = null, $registerFn = null, $registerProtectedFn = null)
Registers the canonical auth route bundle (/auth/login, /auth/sign-up, /auth/reset-password, etc.). Use it when your extension provides an alternative authentication surface (e.g. customer portal, partner API).
Middleware Groups
Pick a group based on who calls the route:
| Group | Auth | When to use |
|---|---|---|
logisbase.protected | Sanctum + session | Internal console — your engine UI calling its own backend |
logisbase.api | API key (basic auth) | Public REST API consumed by external integrations |
| (none) | Public | Webhooks, magic-link callbacks, anonymous endpoints |
Both groups include throttling, request logging, and route binding. logisbase.protected additionally runs SetupLogisBaseSession, the AuthorizationGuard, and presence tracking — defined in CoreServiceProvider::$middleware.
Controllers
Three base classes ship with core-api:
LogisBase\Http\Controllers\Controller
Plain Laravel controller with AuthorizesRequests, DispatchesJobs, ValidatesRequests. Use this for ad-hoc endpoints that don't follow the REST resource pattern.
LogisBase\Http\Controllers\LogisBaseController
Abstract base that adds HasApiControllerBehavior — wires up the model and the JSON resource transformer:
namespace MyOrg\MyExtension\Http\Controllers;
use LogisBase\Http\Controllers\LogisBaseController;
class WidgetController extends LogisBaseController
{
public string $namespace = '\\MyOrg\\MyExtension';
}The $namespace property tells the trait where to find your Models/Widget and Http/Resources/Widget classes — set it once and index/show/store/update/destroy work automatically.
Extending LogisBaseController directly
For a fully wired resource controller you usually don't write any actions yourself. Override hooks for custom behavior:
namespace MyOrg\MyExtension\Http\Controllers;
use LogisBase\Http\Controllers\LogisBaseController;
use Illuminate\Http\Request;
class WidgetController extends LogisBaseController
{
public string $namespace = '\\MyOrg\\MyExtension';
public $resource = 'widget';
public $createRequest = \MyOrg\MyExtension\Http\Requests\WidgetRequest::class;
public $updateRequest = \MyOrg\MyExtension\Http\Requests\WidgetRequest::class;
public function onBeforeCreate(Request $request, array &$input)
{
$input['company_uuid'] = session('company');
}
public function onAfterUpdate($model, Request $request)
{
// dispatch a sync job, send a notification, etc.
}
}Real example: ledger/server/src/Http/Controllers/Internal/v1/InvoiceController.php.
Form Requests
For validation, use Laravel form-request classes. LogisBase ships a LogisBase\Http\Requests\LogisBaseRequest base that adds session-aware authorization:
namespace MyOrg\MyExtension\Http\Requests;
use LogisBase\Http\Requests\LogisBaseRequest;
class WidgetRequest extends LogisBaseRequest
{
public function authorize(): bool
{
return $this->session()->has('user');
}
public function rules(): array
{
return [
'name' => 'required|string|max:120',
'description' => 'nullable|string',
'metadata' => 'array',
];
}
}Reference these from your controller's $createRequest / $updateRequest properties.
Accessing the Authenticated User
Inside a logisbase.protected route, $request->user() returns the authenticated LogisBase\Models\User. The active company is on the session:
$user = $request->user();
$companyId = session('company'); // string UUIDFor API-key-authenticated routes (logisbase.api), the auth context is the API credential — $request->user() resolves through Sanctum to the credential's owner user, and the company is set from the credential.
Route Resource Helpers — REST Registrar
logisbaseRestRoutes uses a custom LogisBase\Routing\RESTRegistrar rather than Laravel's built-in ResourceRegistrar. The registrar normalizes ID parameters (always {id}), ensures dasherized URI segments, and wires the bulk operations.
If you need a non-standard verb shape, drop down to plain Route::get / Route::post and skip the macro.
Source
| File | Description |
|---|---|
src/Expansions/Route.php | logisbaseRoutes, logisbaseRestRoutes, logisbaseAuthRoutes |
src/Routing/RESTRegistrar.php | REST route generator |
src/Http/Controllers/LogisBaseController.php | Abstract resource controller base |
src/Traits/HasApiControllerBehavior.php | Trait that wires up the action methods |
ledger/server/src/Http/Controllers/Internal/v1/InvoiceController.php | Reference resource controller |
pallet/server/src/routes.php | Reference routes file |