Skip to content

Latest commit

 

History

History
171 lines (142 loc) · 5.19 KB

File metadata and controls

171 lines (142 loc) · 5.19 KB

ShiftPHP - API-only modular monolith

ShiftPHP is moving toward an API-only modular monolith. View templates, compiled view storage, page assets and MVC rendering are out of scope for this line.

Completed

  • API-only runtime direction.
  • Route parameters with {name} placeholders.
  • Controller actions returning response objects.
  • Shift\Response\Response, JsonResponse and ResponseEmitter.
  • JSON response helpers on the base controller.
  • Request helpers for query, post, input, raw body, JSON and route params.
  • JSON errors for 400, 404 and 500.
  • 405 Method Not Allowed with an Allow header.
  • Lightweight API core tests through composer test.
  • route:list CLI command.
  • PHP 8 attributes for controller routing.
  • PHP 8 attributes for response metadata and parameter binding.
  • Modular monolith support through application/modules/*/Module.php.
  • Module-owned controllers, routes, services and commands.
  • Middleware pipeline.
  • Controller autowiring through the container.
  • Validation helpers and typed request DTOs.
  • CORS middleware.
  • Authentication and authorization middleware contracts.
  • Module configuration loading.
  • Module lifecycle hooks, for example boot() after service registration.
  • Framework source moved to src/ for package split preparation.
  • CLI create generators for modules and module-owned classes with file-based stubs.
  • .env loading for application configuration.
  • Native PDO database configuration, lazy connection, and basic query API.
  • Fluent query builder and attribute-driven database models.
  • CLI diagnostics for tests, runtime info, environment, database, and modules.
  • CLI help listing and command-specific usage.
  • Centralized CLI command registry shared by the dispatcher and help command.
  • CLI command metadata through attributes, aliases, and grouped help.
  • shift doctor project diagnostics.
  • Database migrations with create, migrate, status, and rollback commands.
  • Module discovery cache for production.
  • Structured exception logging with JSON file logger and service container override.
  • Request id lifecycle with generated X-Request-Id response headers and log context.
  • Developer documentation organized into a Laravel-like guide.
  • CLI quality gate with shift lint and shift qa.
  • OpenAPI JSON generation from registered module routes with shift openapi.
  • OpenAPI documentation attributes, validation, and live Swagger-like viewer.
  • Removal of view storage and example page assets from runtime.
  • Removal of legacy application/controllers and application/routes.php.
  • Domain-oriented framework namespaces:
    • Shift\Response
    • Shift\Routing\Router
    • Shift\Routing\Attributes
    • Shift\Service
    • Shift\Modules
  • GitHub API workflow with PHP 8.3 checks.
  • PR version label validation.
  • Release workflow using PR summary as release notes.
  • Split API core tests into runner, support, fixtures, and feature files.

Modular Monolith Direction

Each module can own:

  • controllers,
  • routes,
  • services,
  • commands.

Module layout:

application/modules/{ModuleName}/
├── Module.php
├── Controllers/
├── Services/
└── Commands/

Module.php is the module boundary. It registers services into the container, routes into the router, and command mappings into the CLI.

Runtime Flow

Request
  -> App
  -> Middleware pipeline
  -> Router
  -> Controller action
  -> Response
  -> ResponseEmitter

Routes

Routes live inside modules:

class Module extends AbstractModule
{
    public function registerRoutes(Router $router): void
    {
        (new AttributeRouteLoader())->load($router, [
            HealthController::class,
        ]);
    }
}

Supported methods:

  • GET
  • POST
  • PUT
  • PATCH
  • DELETE

Controllers

Controllers receive the current Request and ServiceContainer through the constructor. Actions should return Response or JsonResponse.

class HealthController extends \Shift\Controller
{
    #[Get('/api/{argument}')]
    public function api(#[PathParam] string $argument, #[QueryParam('include')] ?string $include = null): JsonResponse
    {
        return $this->json([
            'argument' => $argument,
            'include' => $include,
        ]);
    }

    #[Post('/created')]
    #[Status(201)]
    public function created(#[Body('name')] string $name): array
    {
        return ['name' => $name];
    }
}

Action arguments are resolved from route parameter names. An action can also type-hint Shift\Request.

Error Format

Errors are emitted as JSON:

{
  "error": {
    "message": "Endpoint not found",
    "status": 404
  }
}

Internal errors return a generic 500 message unless display_errors is enabled.

Removed From Runtime

  • legacy Engine/View
  • legacy view namespace
  • legacy Engine/Utils/Storage.php
  • legacy Engine/Error/StorageError.php
  • example CSS and JS page assets
  • View\\ composer namespace
  • application/controllers
  • application/routes.php

Next

  • Deeper static analysis for framework contracts and type safety.