Architecture at a Glance

Dotkernel API follows a modular, middleware-based architecture designed for scalability and maintainability. Understanding the core structure is essential before diving into development.

The Core vs App Split (Since v6.0)

Since version 6.0, Dotkernel API is organized into two distinct layers: Core and App.

Layer Purpose Items Location
Core The backbone of your application, the system-level infrastructure that handles fundamental concerns Authentication & Authorization, Database, Common Services, Shared Entities src/Core/src/
App The project-specific features, "business logic" of your application Routes, Handlers, Custom Services, Input Filters, Custom Middleware, Error Reporting src/App/src/

Architecture

Dotkernel API is built toward a Headless Platform architecture. Out of the box, it is a modular monolith that can be split into modules and microservices.

┌──────────────────────────────────────────────────────────┐
│                    Multiple Frontends                    │
│        (Web, Mobile, Desktop, Voice, etc.)               │
└────────────┬────────────────────────────┬────────────────┘
             │                            │
             └────────────┬───────────────┘
                          │ (REST/JSON APIs)
┌─────────────────────────▼──────────────────────────────┐
│           Dotkernel API (Headless Backend)             │
│  ┌──────────────────────────────────────────────────┐  │
│  │ Core Layer (Infrastructure)                      │  │
│  │ • Authentication (OAuth2)                        │  │
│  │ • Authorization (RBAC)                           │  │
│  │ • Database (Doctrine ORM)                        │  │
│  │ • Middleware Pipeline                            │  │
│  └──────────────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────────────┐  │
│  │ App Layer (Business Logic)                       │  │
│  │ • Endpoints & Routes                             │  │
│  │ • Handlers & Services                            │  │
│  │ • Custom Logic                                   │  │
│  └──────────────────────────────────────────────────┘  │
└─────────────────────────────────────┬──────────────────┘
                                      │
                    ┌─────────────────▼─────────────────┐
                    │   Database                        │
                    │ (MariaDB / PostgreSQL)            │
                    └───────────────────────────────────┘

Modular Monolith Architecture

Applications are organized into modules, each handling a specific domain.

Built-in Modules:

  • Admin: Admin account management (superuser/admin roles)
  • User: Regular user management (user/guest roles)
  • Security: OAuth2 token generation and refresh
  • App: Error reporting and general endpoints
  • Core: Shared infrastructure and base classes

Custom Modules: You can create your own modules (e.g., Book, Product, Article) following the same pattern.

Request Flow

Here's how a typical request flows through Dotkernel API:

1. HTTP Request
   ↓
2. Middleware Pipeline (config/pipeline.php)
   ├─ CorsMiddleware (handle CORS)
   ├─ AuthenticationMiddleware (identify user)
   ├─ AuthorizationMiddleware (check permissions)
   ├─ ContentNegotiationMiddleware (validate Accept/Content-Type)
   └─ RouteMiddleware (match route)
   ↓
3. Handler (PSR-15 RequestHandler)
   ├─ Receive ServerRequestInterface
   ├─ Execute business logic
   └─ Return ResponseInterface
   ↓
4. Response Middleware (if any)
   ├─ ProblemDetailsMiddleware (handle exceptions)
   ├─ DeprecationMiddleware (add deprecation headers)
   └─ Response Header Middleware (set custom headers)
   ↓
5. HTTP Response

Key Components

Component Purpose Example Notes
Handlers (PSR-15) Process incoming HTTP requests, coordinate application logic/services, and return the HTTP response GetUserResourceHandler.php, PostUserResourceHandler.php Some of the benefits are: separation of concerns, easier testing, clearer intent
Services Contains the business logic layer that sits between the handlers and repositories Business rules validation, Data transformation, Cross-cutting concerns Execution flow: Handler → Service → Repository → Database
Repositories Data access layer using Doctrine ORM Query building, Entity persistence, Database abstraction The only component that interacts with the database
Input Filters Filter and validate requests using Laminas InputFilter Login form, contact us form, $_GET and $_POST values, CLI arguments Execution flow: Request → InputFilter → Validation → Handler
Entities Represent database tables using Doctrine ORM class User { ... } Ensure consistency between database and application data

Configuration Organization

config/
├─ config.php                     (Main entry point)
├─ pipeline.php                   (Middleware stack)
├─ container.php                  (Dependency injection)
└─ autoload/
    ├─ dependencies.global.php        (Service definitions)
    ├─ authorization.global.php       (RBAC rules)
    ├─ content-negotiation.global.php (Accept/Content-Type)
    ├─ doctrine.global.php            (ORM configuration)
    └─ local.php                      (Environment-specific, ignored by VCS, private config)

Dependency Injection

Dotkernel API uses constructor injection with attributes:

use Dot\DependencyInjection\Attribute\Inject;

class UserHandler
{
    #[Inject(
        UserService::class,
        "config"
    )]
    public function __construct(
        protected UserService $userService,
        protected array $config
    ) {}
}

Services are automatically resolved and injected by AttributedServiceFactory.

Data Flow Architecture

┌─────────────────────────────────────────┐
│    Incoming HTTP Request (PSR-7)        │
└────────────┬────────────────────────────┘
             │
             ▼
┌─────────────────────────────────────────┐
│    Middleware Pipeline                  │
│  (Auth, Validation, Negotiation)        │
└────────────┬────────────────────────────┘
             │
             ▼
┌─────────────────────────────────────────┐
│    Handler (Business Logic)             │
│  • Extract request data                 │
│  • Validate with InputFilter            │
│  • Call Service layer                   │
└────────────┬────────────────────────────┘
             │
             ▼
┌─────────────────────────────────────────┐
│    Service Layer (Domain Logic)         │
│  • Business rules                       │
│  • Data transformation                  │
│  • Call Repository layer                │
└────────────┬────────────────────────────┘
             │
             ▼
┌─────────────────────────────────────────┐
│    Repository Layer (Data Access)       │
│  • Doctrine queries                     │
│  • Entity persistence                   │
└────────────┬────────────────────────────┘
             │
             ▼
┌─────────────────────────────────────────┐
│    Database (MariaDB / PostgreSQL)      │
└─────────────────────────────────────────┘

Standards & PSRs

Dotkernel API adheres to PHP standards for interoperability. They ensure that your code can integrate with other PSR-compliant libraries.

PSR and Specifications Git Implementation Level Description
PSR-7 http-message Core HTTP Message Interfaces (Requests/Responses)
PSR-11 container Core Container Interface (Dependency Injection)
PSR-15 http-server-handler, http-server-middleware Core HTTP Handlers and Middleware (Request processing)
PSR-3 log Supporting Logger Interface (Requests/Responses)
PSR-4 Supporting Autoloading (File organization)
PSR-6 cache Supporting Caching Interface
PSR-13 Git link Supporting Link Definition Interfaces
PSR-14 event-dispatcher Supporting Event Dispatcher
PSR-17 http-factory Supporting HTTP Factories
PSR-18 http-client Supporting HTTP Client
PSR-20 clock Supporting Clock

Supporting PSRs are installed by dependencies.

Security Layers

┌─────────────────────────────┐
│  1. Authentication          │
│  (OAuth2 tokens)            │
├─────────────────────────────┤
│  2. Authorization           │
│  (RBAC permissions)         │
├─────────────────────────────┤
│  3. Input Validation        │
│  (InputFilter)              │
├─────────────────────────────┤
│  4. Content Negotiation     │
│  (Accept/Content-Type)      │
└─────────────────────────────┘

When to Use Each Layer

Layer Purpose Example
Core System infrastructure Authentication, database setup
App Project features User CRUD operations, custom logic
Handler Request/response mapping Extract user ID, call service
Service Business rules Validate user data, calculate totals
Repository Data queries Find users, save entity