This document provides a comprehensive overview of the Micro‑framework REST v2.0. It covers all features, core classes, functions, and a step‑by‑step Getting Started guide with practical examples. It also demonstrates middleware usage, route parameters, query parameters, regex placeholders, and how to organize your code with use
and include
statements.
- Fluent API for route definitions with middleware chaining.
- Onion‑style middleware engine supporting both callables and classes.
- **Attributes **`` on controller methods with optional scanner.
- Advanced placeholders:
{param}
or{param:regex}
(e.g.{id:\d+}
). - Automatic CORS preflight and reflected CORS configuration.
- Default security headers:
X-Content-Type-Options
,Referrer-Policy
,X-Frame-Options
. - JWT helper for token generation and validation.
- Centralized error handler with customizable display of stack traces.
- No external dependencies: pure PHP 8.1, strict types, GPL‑3.0.
- Download or clone this framework into your project directory.
- Ensure PHP 8.1 or later is installed and
strict_types
is enabled. - Include the main file in your
index.php
(or front controller):
<?php
declare(strict_types=1);
use App\Config;
use App\RestApi;
require __DIR__ . '/path/to/rest-api.php';
Before using the framework, you may want to route all requests under /api
to the api.php
front controller. In your Apache configuration or .htaccess
, enable the rewrite engine and add:
RewriteEngine On
RewriteRule ^/?api/(.*)$ api.php?u=$1 [QSA,L]
Create an index.php
with:
<?php
declare(strict_types=1);
use App\Config;
use App\RestApi;
require __DIR__ . '/lib/RestApi.php';
// 1. Initialize configuration (enable CORS, error display...)
$config = new Config(
displayErrors: true,
enableCors: true,
corsOrigins: ['https://yourdomain.com'],
);
// 2. Instantiate the API
$api = new RestApi($config);
// 3. Define routes
$api->get('ping', fn($req, $p) => ['pong' => true]);
// 4. Run the API
$api->run();
Now a GET /ping
request will return:
{ "pong": true }
new Config(
bool $displayErrors = false,
bool $enableCors = false,
array $corsOrigins = ['*'],
array $corsMethods = ['GET','POST','PUT','PATCH','DELETE','OPTIONS','HEAD'],
array $corsHeaders = ['Content-Type','Authorization'],
bool $corsAllowCredentials = false,
);
Controls error output and CORS behavior.
- Constructor:
Response(int $status = 200, array $headers = [], mixed $body = null)
- send(): emits status, headers, and JSON‑encodes the body.
- withHeaders(array $headers): returns a new instance merging headers.
return (new Response(201, [], ['id' => $newId]))
->withHeaders(['X-Rate-Limit' => '100']);
Provides request data:
- Properties:
$method
,$uri
,$rawBody
,$attributes
- json(): parse JSON payload, throws
BadRequestException
if malformed. - getHeader(string $name)
- query(): returns all query string parameters.
- queryParam(string $key, mixed $default = null)
$data = $req->json();
$page = (int) $req->queryParam('page', 1);
HttpException
(base)BadRequestException
(400)UnauthorizedException
(401)ValidationException
(extends 400, carrieserrors
array)NotFoundException
(404)MethodNotAllowedException
(405)
Throw these in handlers to send appropriate status codes.
$errors = Validator::validate($data, [
'name' => 'required|string',
'age' => 'int',
]);
if ($errors) {
throw new ValidationException($errors);
}
$token = Jwt::generate(['sub' => 123, 'exp' => time() + 3600], 'secret-key');
$isValid = Jwt::validate($token, 'secret-key');
- Interface: implement
MiddlewareInterface::__invoke(Request $request, array $params, callable $next)
. - Chaining: call
$api->get(...)->middleware(AuthMiddleware::class, fn()=>...)
.
class AuthMiddleware implements MiddlewareInterface {
public function __invoke($req, $params, $next) {
$token = $req->getHeader('Authorization');
if (!Jwt::validate($token, 'secret')) {
throw new UnauthorizedException('Invalid token');
}
return $next($req, $params);
}
}
- add($method, $pattern, $handler): returns a
Route
for chaining. - match($method, $uri): returns
[Route, params]
or throwsNotFoundException
.
Placeholders in $pattern
:
- Simple:
{id}
matches any segment. - Regex:
{id:\d+}
matches only digits.
Automatically catches exceptions, formats JSON error responses, includes CORS headers.
Shortcut methods to define routes:
$api->get('/users', $handler);
$api->post('/users', $handler);
// put, patch, delete, head, options
- debugRoutes(): list all registered routes.
- run(): handles CORS preflight, routing, middleware pipeline, and sending the response.
- registerControllers($namespace, $path): auto‑scan PHP files for
#[Route]
attributes.
use App\RestApi;
use App\MiddlewareInterface;
use App\UnauthorizedException;
class LoggerMiddleware implements MiddlewareInterface {
public function __invoke($req, $params, $next) {
error_log($req->method . ' ' . $req->uri);
return $next($req, $params);
}
}
$api = new RestApi();
$api->get('secure/data', fn($r,$p) => ['data'=>42])
->middleware(LoggerMiddleware::class, AuthMiddleware::class);
$api->get('search', function($req,$p) {
$term = $req->queryParam('term', '');
$limit = (int) $req->queryParam('limit', 10);
return ['results' => searchDatabase($term, $limit)];
});
$api->get('items/{item_id:\\d+}', function($req, $p) {
// $p['item_id'] is guaranteed numeric
return getItemById((int)$p['item_id']);
});
<?php
declare(strict_types=1);
use App\Config;
use App\RestApi;
require __DIR__ . '/lib/RestApi.php';
$config = new Config(enableCors: true);
$api = new RestApi($config);
// Split routes into separate files
include __DIR__ . '/routes/ping.php';
include __DIR__ . '/routes/users.php';
$api->run();
In routes/users.php
:
use App\RestApi;
use App\Response;
/** @var RestApi $api */
$api->get('users', function($req, $p) {
return ['users' => ['Alice','Bob']];
});
project/
├── lib/
│ └── RestApi.php # framework core
├── routes/
│ ├── ping.php
│ └── users.php
└── public/
└── index.php # front controller
This documentation covers all features, core classes, and provides practical examples to get you started quickly. Enjoy building RESTful APIs with this lightweight micro‑framework!