Core Concepts
Routes
Routes in Kipchak are defined using PHP files in the routes/ directory. Each route file registers endpoints with the Slim application instance and maps them to controller methods.
Basic Route Structure
Routes are defined using the $app variable, which is an instance of Slim\App. Each route file follows this basic pattern:
<?php
use Api\Controllers;
/**
* @var \Slim\App $app
*/
$app->get('/info',
[
Controllers\Info::class,
'get'
]
);
This defines a GET endpoint at /info that calls the get method of the Info controller.
HTTP Methods
Kipchak supports all standard HTTP methods through Slim's routing:
$app->get()- Handle GET requests$app->post()- Handle POST requests$app->put()- Handle PUT requests$app->patch()- Handle PATCH requests$app->delete()- Handle DELETE requests$app->options()- Handle OPTIONS requests
Route Groups
Use route groups to organize related endpoints and apply shared URL prefixes. This is particularly useful for API versioning:
<?php
use Api\Controllers;
use Slim\Routing\RouteCollectorProxy;
$app->group('/v1', function(RouteCollectorProxy $group) {
$group->get('/cache',
[
Controllers\v1\Cache::class,
'get'
]
);
$group->get('/sultans',
[
Controllers\v1\Sultans::class,
'get'
]
);
});
All routes defined within the group will be prefixed with /v1, resulting in endpoints like /v1/cache and /v1/sultans.
Applying Middleware to Routes
Middleware can be applied to individual routes or route groups using the add() method. This allows you to add authentication, rate limiting, or other request processing logic to specific endpoints.
Route-Specific Middleware
Apply middleware to a single route group:
<?php
use Api\Controllers;
use Kipchak\Middleware\Auth\JWKS\Handlers\AuthJWKS;
use Slim\Routing\RouteCollectorProxy;
$app->group('/v1', function(RouteCollectorProxy $group) {
$group->get('/authJWKS',
[
Controllers\v1\Authenticated::class,
'getJWKS'
]
);
})->add(new AuthJWKS($app->getContainer(), ['email']));
In this example, the AuthJWKS middleware is applied only to routes within this specific group. The middleware receives the application container and configuration parameters (like required claims).
Multiple Middleware Examples
Different route groups can use different middleware:
<?php
use Api\Controllers;
use Kipchak\Middleware\Auth\JWKS\Handlers\AuthJWKS;
use Kipchak\Middleware\Auth\Key\Handlers\ApiKey;
use Slim\Routing\RouteCollectorProxy;
// JWKS authentication
$app->group('/v1', function(RouteCollectorProxy $group) {
$group->get('/authJWKS',
[
Controllers\v1\Authenticated::class,
'getJWKS'
]
);
})->add(new AuthJWKS($app->getContainer(), ['email']));
// API Key authentication
$app->group('/v1', function(RouteCollectorProxy $group) {
$group->get('/authKey',
[
Controllers\v1\Authenticated::class,
'getKey'
]
);
})->add(new ApiKey($app->getContainer()));
Controller Mapping
Routes map to controller class methods using an array syntax:
[
Controllers\v1\Cache::class, // Controller class
'get' // Method name
]
The controller method receives three parameters:
ServerRequestInterface $request- The HTTP request objectResponseInterface $response- The HTTP response objectarray $args- Route parameters (e.g., from URL segments)
Example controller:
<?php
namespace Api\Controllers;
use Kipchak\Core\Components\Controllers;
use Kipchak\Core\Components\Http;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class Info extends Controllers\Base
{
public function get(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
{
return Http\Response::json($response,
[
'status' => 'ok'
],
200
);
}
}
6. OpenAPI (Swagger) Documentation
Kipchak automates documentation. While the route file handles the "how" of the request, the Controller Attributes handle the "what." The framework scans your controllers to generate the openapi.json.
Example Controller Attribute:
#[OA\Get(
path: '/v1/users',
summary: 'Retrieve all users',
responses: [
new OA\Response(response: 200, description: 'Success')
]
)]
public function __invoke(...) {
// Logic execution
}
See the Controllers section for more details.
Route Organization
In the starter project, routes are organized by:
- Root routes (
routes/*.php) - Top-level endpoints like/infoand/status - Versioned routes (
routes/v1/*.php) - API version-specific endpoints grouped under/v1
This structure makes it easy to:
- Add new API versions without breaking existing endpoints
- Organize routes by feature or resource type
- Apply version-specific middleware or logic
Best Practices SummaryPracticeDescriptionThin RoutesRoute files should contain zero logic; only mappings.Explicit NamingName your route groups by their version (e.g., /v1).Class CallbacksAlways use Controller::class to allow for IDE auto-completion.
Best Practices
- Use route groups for versioning and shared prefixes
- Apply middleware at the group level when multiple routes need the same protection
- Keep route files focused - one file per resource or feature area
- Use meaningful controller namespaces that mirror your route structure (e.g.,
Api\Controllers\v1) - Document route parameters in comments for clarity
- Version Everything - Always keep Routes, Controllers, and DTOs in versioned directories