162 lines
6.4 KiB
Markdown
162 lines
6.4 KiB
Markdown
# Phred Technical Specifications
|
|
|
|
[← Back to README](./README.md) | [MILESTONES.md](./MILESTONES.md)
|
|
|
|
## Table of Contents
|
|
- [1. Core Framework](#1-core-framework)
|
|
- [1.1 API Formats and Content Negotiation](#1-1-api-formats-and-content-negotiation)
|
|
- [1.2 Pluggability Model (M5)](#1-2-pluggability-model-m5)
|
|
- [1.3 URL Extension Negotiation](#1-3-url-extension-negotiation)
|
|
- [1.4 Dependencies](#1-4-dependencies)
|
|
- [2. MVC Components](#2-mvc-components)
|
|
- [2.1 Controllers](#2-1-controllers)
|
|
- [2.2 Views (M6)](#2-2-views-m6)
|
|
- [2.3 Services](#2-3-services)
|
|
- [3. Modular Architecture (M7)](#3-modular-architecture-m7)
|
|
- [3.1 Module Layout (ORM-Agnostic)](#3-1-module-layout-orm-agnostic)
|
|
- [3.2 Modular Separation](#3-2-modular-separation)
|
|
- [4. Infrastructure](#4-infrastructure)
|
|
- [4.1 Service Providers (M5)](#4-1-service-providers-m5)
|
|
- [4.2 Configuration and Environment](#4-2-configuration-and-environment)
|
|
- [4.3 Command Discovery](#4-3-command-discovery)
|
|
- [5. Technical Examples](#5-technical-examples)
|
|
- [5.1 Configuration Access](#5-1-configuration-access)
|
|
- [5.2 API Negotiation](#5-2-api-negotiation)
|
|
- [5.3 Route Group Inclusion](#5-3-route-group-inclusion)
|
|
|
|
This document outlines the technical specifications and architectural standards of the Phred framework.
|
|
|
|
## 1. Core Framework
|
|
|
|
### 1.1 API Formats and Content Negotiation
|
|
Phred supports two primary API formats:
|
|
* **Pragmatic REST (default)**: Plain JSON responses using RFC 7807 for error handling.
|
|
* **JSON:API**: Compliant with the JSON:API specification for documents and error objects.
|
|
|
|
Negotiation can be set globally via `.env`:
|
|
* `API_FORMAT=rest`
|
|
* `API_FORMAT=jsonapi`
|
|
|
|
Clients can override the format per request using the `Accept` header:
|
|
* `Accept: application/vnd.api+json` forces JSON:API.
|
|
* `Accept: application/xml` or `text/xml` (M12+).
|
|
|
|
### 1.2 Pluggability Model (M5)
|
|
The framework is fully pluggable. Core components depend on Phred contracts and PSRs; concrete implementations are provided by Service Providers.
|
|
* Providers implement `Phred\Support\Contracts\ServiceProviderInterface`.
|
|
* Lifecycle methods: `register(ContainerBuilder)` and `boot(Container)`.
|
|
* Loading order: Core → App → Modules (defined in `config/providers.php`).
|
|
|
|
**Primary Contracts:**
|
|
* `Template\Contracts\RendererInterface`
|
|
* `Orm\Contracts\ConnectionInterface`
|
|
* `Flags\Contracts\FeatureFlagClientInterface`
|
|
* `Testing\Contracts\TestRunnerInterface`
|
|
|
|
### 1.3 URL Extension Negotiation
|
|
Optional middleware that hints content negotiation based on URL suffix.
|
|
* Enabled via `URL_EXTENSION_NEGOTIATION=true` (default).
|
|
* Whitelist via `URL_EXTENSION_WHITELIST` (default: "json|xml|php|none").
|
|
* **Mappings:**
|
|
* `.json` → `application/json`
|
|
* `.xml` → `application/xml`
|
|
* `.php` or none → `text/html` (View convention)
|
|
|
|
### 1.4 Dependencies
|
|
Phred leverages several industry-standard packages:
|
|
* **Dependency Injection**: `php-di/php-di`
|
|
* **Static Analysis**: `phpstan/phpstan`
|
|
* **Code Style**: `friendsofphp/php-cs-fixer`
|
|
* **Logging**: `monolog/monolog`
|
|
* **Environment**: `vlucas/phpdotenv`
|
|
* **HTTP Client**: `guzzlehttp/guzzle`
|
|
* **CORS**: `middlewares/cors`
|
|
* **Authentication**: `lcobucci/jwt`
|
|
* **Feature Flags**: `getphred/flagpole`
|
|
* **ORM**: `getphred/pairity`
|
|
* **Template Engine**: `getphred/eyrie`
|
|
* **Router**: `nikic/fast-route`
|
|
* **PSR-7/15**: `relay/relay`, `nyholm/psr7`
|
|
|
|
## 2. MVC Components
|
|
|
|
### 2.1 Controllers
|
|
* **Invokable**: Controllers are "Actions" with a single entry point: `public function __invoke(Request $request)`.
|
|
* **Response Factories**: Injected via `Phred\Http\Contracts\ApiResponseFactoryInterface`.
|
|
* **Base Classes (M6)**:
|
|
* `Phred\Mvc\APIController`: For API-only endpoints.
|
|
* `Phred\Mvc\ViewController`: For HTML/Template endpoints.
|
|
|
|
### 2.2 Views (M6)
|
|
* Classes dedicated to data preparation before rendering.
|
|
* Extend `Phred\Mvc\View`.
|
|
* Methods:
|
|
* `transformData(array $data)`: Manipulate data before it hits the template.
|
|
* `defaultTemplate()`: Define the default template for the view.
|
|
* **Conventions**: Controllers call `renderView($view, $data, ?$templateOverride)`. If no override is provided, the View decides the template.
|
|
|
|
### 2.3 Services
|
|
* Business logic should reside in Service classes to keep controllers lean and models ORM-neutral.
|
|
|
|
## 3. Modular Architecture (M7)
|
|
|
|
Phred follows a Django-style modular structure where all user code lives inside modules.
|
|
|
|
### 3.1 Module Layout (ORM-Agnostic)
|
|
* `modules/<Module>/Controllers/`
|
|
* `modules/<Module>/Views/`
|
|
* `modules/<Module>/Templates/`
|
|
* `modules/<Module>/Services/`
|
|
* `modules/<Module>/Models/` (Domain models, pure PHP)
|
|
* `modules/<Module>/Repositories/` (Interfaces consumed by services)
|
|
* `modules/<Module>/Persistence/Pairity/` (Driver-specific implementations)
|
|
* `modules/<Module>/Persistence/Eloquent/` (Driver-specific implementations)
|
|
* `modules/<Module>/Database/Migrations/` (Canonical migrations)
|
|
* `modules/<Module>/Routes/web.php` and `api.php`
|
|
* `modules/<Module>/Providers/*ServiceProvider.php`
|
|
|
|
### 3.2 Modular Separation
|
|
Modules encapsulate their own:
|
|
* Models, Controllers, Views, Services, Migrations, Providers, Routes, Templates, and Tests.
|
|
|
|
## 4. Infrastructure
|
|
|
|
### 4.1 Service Providers (M5)
|
|
Providers are the glue of the framework.
|
|
* **Configuration**: `config/providers.php`
|
|
* **Route Registration**: Use `RouteRegistry::add(static function($collector, $router) { ... })`.
|
|
|
|
### 4.2 Configuration and Environment
|
|
* **Dotenv**: Loads `.env` from the project root.
|
|
* **Config Facade**: `Phred\Support\Config::get(<key>, <default>)`.
|
|
* **Precedence**: Environment variables > Config files (`config/*.php`) > Defaults.
|
|
* **Notation**: Supports both `UPPER_SNAKE` and `dot.notation`.
|
|
|
|
### 4.3 Command Discovery
|
|
* **Core Commands**: Discovered from `src/commands`.
|
|
* **User Commands**: Discovered from `console/commands`.
|
|
* Custom commands must return an instance of `Phred\Console\Command`.
|
|
|
|
## 5. Technical Examples
|
|
|
|
### 5.1 Configuration Access
|
|
```php
|
|
use Phred\Support\Config;
|
|
|
|
$env = Config::get('APP_ENV', 'local'); // environment check
|
|
$tz = Config::get('app.timezone', 'UTC'); // dotted notation from config/app.php
|
|
```
|
|
|
|
### 5.2 API Negotiation
|
|
The chosen format is stored on the request as `phred.api_format` and used by the `ApiResponseFactoryInterface` to determine the response shape.
|
|
|
|
### 5.3 Route Group Inclusion
|
|
```php
|
|
use Phred\Http\Routing\RouteGroups;
|
|
use Phred\Http\Router;
|
|
|
|
RouteGroups::include($router, '/prefix', function (Router $router) {
|
|
require __DIR__ . '/../path/to/routes.php';
|
|
});
|
|
```
|