Bamboo v0.3 Middleware & Module Preparation¶
This document captures the design notes for the middleware pipeline and module system that will land in the v0.3 release. It is intended to guide feature work before the implementation solidifies so teams can agree on naming, execution order, and container responsibilities.
Middleware pipeline architecture¶
Execution order¶
- Global stack – middleware defined in
etc/middleware.php
under theglobal
key runs for every HTTP request. These entries are resolved out of the container, allowing dependencies to be injected through constructor arguments. - Grouped layers – route definitions will reference named groups. Each group is resolved from the configuration file and merged onto the global stack in the order the groups are attached to the route. This keeps common policies (e.g., authentication, throttling) reusable without repeating class names per route.
- Route-specific middleware – ad-hoc middleware declared directly on a route are appended last so teams can override behaviors on a single endpoint without mutating global state.
- Termination hooks – middleware implementing a
terminate()
method will be collected during request execution and invoked after the response is sent so they can perform cleanup or async dispatching.
Grouping strategy¶
etc/middleware.php
will return a keyed array of middleware identifiers. The top-level keys areglobal
,groups
, andaliases
.- Global middleware lists the always-on stack.
- Groups are keyed by group name and contain ordered middleware class strings or alias references. Groups may be nested by referencing other group names, enabling composition (e.g.,
web
can includesession
andcsrf
groups). - Aliases map short handles to class strings so routing declarations stay readable and avoid hard-coding fully-qualified class names.
Container integration¶
- The HTTP kernel will pull middleware definitions from the resolved configuration (
Bamboo\Core\Config
). - Each middleware entry is resolved through the service container to honour constructor dependencies.
- The kernel will cache the expanded stack for each route to avoid rebuilding the same array on every request. Cache invalidation happens when the route cache is cleared or when configuration files change.
Module contract¶
Modules expose extension points for the framework. The proposed Bamboo\Module\ModuleInterface
formalizes how a module registers its services and middleware contributions.
namespace Bamboo\Module;
use Bamboo\Core\Application;
interface ModuleInterface
{
/**
* Register bindings or configuration into the container.
*/
public function register(Application $app): void;
/**
* Perform post-registration boot logic once all modules are loaded.
*/
public function boot(Application $app): void;
/**
* Optionally contribute middleware aliases or stacks.
*
* @return array<string, array<int, string>|string>
*/
public function middleware(): array;
}
Additional optional contracts (such as provides()
for deferred loading) can be introduced in later iterations, but the above set keeps the initial API small and focused on container registration.
Module registration flow¶
- Modules are declared in
etc/modules.php
as an ordered list of class names implementingModuleInterface
. - During bootstrap the application resolves the array, iterates through each module, and calls
register()
so services, configuration, and bindings are available before the rest of the framework boots. - After all modules have registered, the bootstrapper calls
boot()
on each module in registration order. This ensures modules can safely interact with services from other modules. - Middleware contributions returned by
middleware()
are merged into the configuration structure loaded frometc/middleware.php
, allowing modules to publish additional aliases or group entries. - Future tooling (e.g.,
bin/bamboo modules.list
) can introspect the configuration and report which modules are active and what middleware they expose.
Configuration entry points¶
etc/middleware.php
– placeholder returning an empty array today. Teams will populate theglobal
,groups
, andaliases
keys described above as middleware lands in the codebase.etc/modules.php
– placeholder returning an empty array. Populate it with module class names in the order they should be registered with the application container.
Link this document in the README so contributors know where the roadmap lives and where to wire upcoming configuration.