hostkurd / flocms-api
Optional modern API runtime for Flo Framework: explicit routing, middleware, JSON errors, CORS, authentication contracts, and rate limiting.
v1.0.0
2026-07-25 08:31 UTC
Requires
- php: ^8.1
- hostkurd/flocms-core: ^2.0
- psr/log: ^1.1 || ^2.0 || ^3.0
Requires (Dev)
- phpunit/phpunit: ^10.5 || ^11.0
This package is auto-updated.
Last update: 2026-07-25 08:36:50 UTC
README
hostkurd/flocms-api is the optional API runtime for Flo Framework. It depends
on hostkurd/flocms-core and provides explicit, method-aware routing instead of
the legacy api_<action> convention.
Features
- routes constrained by HTTP method, with named parameters and automatic 405 responses;
- route groups, names, middleware, and module ownership;
- a middleware pipeline with CORS, JSON-body validation, security headers, authentication, and rate limiting;
- consistent JSON envelopes and production-safe exception rendering;
- request IDs on successful and failed responses;
- dependency-injected controllers and route handlers;
- route loading from the application's
api/directory and enabled module manifests; - trusted-proxy-aware client IP resolution;
- non-terminating
Responseobjects, making controllers testable.
Minimal setup
use FloCMS\Api\Kernel; use FloCMS\Api\Router; use FloCMS\Api\Middleware\CorsMiddleware; use FloCMS\Api\Middleware\ExceptionMiddleware; use FloCMS\Api\Middleware\JsonBodyMiddleware; use FloCMS\Core\Http\Request; use FloCMS\Core\Modules\ModuleSystem; $router = new Router(); $router->group('/v1', function (Router $router): void { $router->get('/health', fn () => ['status' => 'ok'])->name('health'); }); $kernel = new Kernel( router: $router, container: ModuleSystem::container(), modules: ModuleSystem::manager(), debug: false, ); $kernel->middleware([ new CorsMiddleware(['https://www.example.com'], allowCredentials: true), new ExceptionMiddleware(debug: false), new JsonBodyMiddleware(), ]); $kernel->handle(Request::fromGlobals())->send();
Place application route registration in api/routes.php. A route file returns
a closure:
<?php use FloCMS\Api\Router; use App\Api\NewsController; return static function (Router $router): void { $router->get('/v1/news', [NewsController::class, 'index']) ->name('news.index') ->module('news'); };
Module route files are declared in module.php:
'routes' => ['api' => 'routes/api.php'],
The route loader marks every route from that file with its owning module. Requests to a disabled or outdated module receive a 404 without constructing the controller.