Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,16 @@ 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:
Since version 6.0, Dotkernel API is organized into two distinct layers: Core and App.

### Core Layer
| 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/ |

The **Core** is the backbone of your application—system-level infrastructure that handles fundamental concerns:
## Architecture

- Authentication & Authorization: OAuth2-based authentication with RBAC (Role-Based Access Control)
- Database Setup: Doctrine ORM configuration, entity definitions, and repositories
- Common Services: Mail service, error reporting, caching
- Shared Entities: Admin/User entities, roles, permissions

Location: `src/Core/src/`

You typically don't modify Core unless you're updating system behavior or adding shared infrastructure features.

### App Layer

The **App** is where you build your project-specific features—the "business logic" of your application:

- Routes: Endpoint definitions specific to your use case
- Handlers: PSR-15 request handlers (like controllers, but single-action focused)
- Custom Services: Business logic and data processing
- Input Filters: Request validation rules
- Custom Middleware: Application-specific middleware
- Error Reporting: Frontend error collection endpoints

Location: `src/App/src/`

You spend most development time here, implementing your API's features and business logic.

## Headless CMS Architecture

Dotkernel API is built toward a Headless Platform 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.

```quote
Expand Down Expand Up @@ -71,7 +48,7 @@ Out of the box, it is a modular monolith that can be split into modules and micr
└───────────────────────────────────┘
```

## Modular Design
## Modular Monolith Architecture

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

Expand Down Expand Up @@ -114,60 +91,13 @@ Here's how a typical request flows through Dotkernel API:

## Key Components

### Handlers (PSR-15)

Single-action request handlers instead of multi-action controllers:

```quote
src/User/src/Handler/
├─ GetUserCollectionHandler.php (GET /user)
├─ GetUserResourceHandler.php (GET /user/{id})
├─ PostUserResourceHandler.php (POST /user)
├─ PatchUserResourceHandler.php (PATCH /user/{id})
└─ DeleteUserResourceHandler.php (DELETE /user/{id})
```

Benefits: Separation of concerns, easier testing, clearer intent.

### Services

The Business logic layer sits between the handlers and repositories:

```quote
Handler → Service → Repository → Database
```

Services handle:

- Business rules validation
- Data transformation
- Cross-cutting concerns (caching, logging)

### Repositories

Data access layer using Doctrine ORM:

- Query building
- Entity persistence
- Database abstraction

### Input Filters

Request validation using Laminas InputFilter:

```quote
Request → InputFilter → Validation → Handler
```

### Entities

Doctrine ORM entities representing database tables:

```php
#[ORM\Entity]
#[ORM\Table(name: 'user')]
class User { ... }
```
| 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

Expand All @@ -177,11 +107,11 @@ config/
├─ 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)
├─ 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
Expand Down Expand Up @@ -250,25 +180,24 @@ Services are automatically resolved and injected by AttributedServiceFactory.

## Standards & PSRs

Dotkernel API adheres to PHP standards for interoperability:
Core PSRs

- **PSR-7**: HTTP Message Interfaces (Requests/Responses)
- **PSR-11**: Container Interface (Dependency Injection)
- **PSR-15**: HTTP Handlers and Middleware (Request processing)

Supporting PSRs, installed by dependencies:

- **PSR-3**: Logger Interface (Requests/Responses)
- **PSR-4**: Autoloading (File organization)
- **PSR-6**: Caching Interface
- **PSR-13**: Link Definition Interfaces
- **PSR-14**: Event Dispatcher
- **PSR-17**: HTTP Factories
- **PSR-18**: HTTP Client
- **PSR-20**: Clock

This ensures your code can integrate with other PSR-compliant libraries.
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](https://www.php-fig.org/psr/psr-7) | [php-fig/http-message](https://github.com/php-fig/http-message) | Core | HTTP Message Interfaces (Requests/Responses) |
| [PSR-11](https://www.php-fig.org/psr/psr-11) | [php-fig/container](https://github.com/php-fig/container) | Core | Container Interface (Dependency Injection) |
| [PSR-15](https://www.php-fig.org/psr/psr-15) | [php-fig/http-server-handler](https://github.com/php-fig/http-server-handler), [php-fig/http-server-middleware](https://github.com/php-fig/http-server-middleware) | Core | HTTP Handlers and Middleware (Request processing) |
| [PSR-3](https://www.php-fig.org/psr/psr-3) | [php-fig/log](https://github.com/php-fig/log) | Supporting | Logger Interface (Requests/Responses) |
| [PSR-4](https://www.php-fig.org/psr/psr-4) | [php-fig/log](https://github.com/php-fig/log) | Supporting | Autoloading (File organization) |
| [PSR-6](https://www.php-fig.org/psr/psr-6) | [php-fig/cache](https://github.com/php-fig/cache) | Supporting | Caching Interface |
| [PSR-13](https://www.php-fig.org/psr/psr-13) | [php-fig/link](https://github.com/php-fig/link) | Supporting | Link Definition Interfaces |
| [PSR-14](https://www.php-fig.org/psr/psr-14) | [php-fig/event-dispatcher](https://github.com/php-fig/event-dispatcher) | Supporting | Event Dispatcher |
| [PSR-17](https://www.php-fig.org/psr/psr-17) | [php-fig/http-factory](https://github.com/php-fig/http-factory) | Supporting | HTTP Factories |
| [PSR-18](https://www.php-fig.org/psr/psr-18) | [php-fig/http-client](https://github.com/php-fig/http-client) | Supporting | HTTP Client |
| [PSR-20](https://www.php-fig.org/psr/psr-20) | [php-fig/clock](https://github.com/php-fig/clock) | Supporting | Clock |

> Supporting PSRs are installed by dependencies.

## Security Layers

Expand Down
6 changes: 3 additions & 3 deletions docs/book/v7/extended-features/core-and-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ Since version 6.0, the project is split into two main parts: **App** and **Core*
When you start a new project, there are chances that the requirements are not defined well.
Because of that, your platform needs to be flexible and allow growth in the long term.

Our purpose is to reach a **Headless CMS** architecture for easier scalability.
Our purpose is to reach a **Headless Platform** architecture for easier scalability.

> Headless CMS is a backend-only content management system that acts primarily as a content repository.
> Compared to traditional CMS platforms (e.g., WordPress) that tightly couple the front end and back end, a headless CMS decouples the content management from the presentation layer.
> The Headless Platform is a backend system that provides data and functionality via an API, completely decoupled from any frontend presentation layer.
> Unlike monolithic platforms like WordPress that bundle the backend and frontend together, a Headless Platform separates content delivery from the presentation layer.
> The content is delivered through APIs allowing any frontend to fetch and display it, which also enables working in parallel on the backend and potentially multiple frontends.

## What is "App" and what is "Core"?
Expand Down
5 changes: 2 additions & 3 deletions docs/book/v7/introduction/file-structure.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# File structure

Dotkernel API follows the [PSR-4](https://www.php-fig.org/psr/psr-4/) standards.

It is a good practice to standardize the file structure of projects.
The Dotkernel API file structure follows the [PSR-4](https://www.php-fig.org/psr/psr-4/) standards.
Standardizing the file structure of your project is considered good practice because it makes it easier to find and navigate the code.

When using Dotkernel API, the following structure is installed by default:

Expand Down
13 changes: 9 additions & 4 deletions docs/book/v7/introduction/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ For our API payloads (a value object for describing the API resource, its relati

## CORS

By using `MezzioCorsMiddlewareCorsMiddleware`, the CORS preflight will be recognized and the middleware will start to detect the proper CORS configuration.
By using `Mezzio\Cors\Middleware\CorsMiddleware`, the CORS preflight will be recognized and the middleware will start to detect the proper CORS configuration.
The Router is used to detect every allowed request method by executing a route match with all possible request methods.
Therefore, for every preflight request, there is at least one Router request.

Expand All @@ -67,7 +67,7 @@ We use [mezzio/mezzio-authentication-oauth2](https://github.com/mezzio/mezzio-au

It is not unlikely for an API to send emails depending on the use case.
Here is another area where Dotkernel API shines.
Using `DotMailServiceMailService` provided by [dotkernel/dot-mail](https://github.com/dotkernel/dot-mail) you can send custom email templates.
Using `Dot\Mail\Service\MailService` provided by [dotkernel/dot-mail](https://github.com/dotkernel/dot-mail) you can send custom email templates.

## Configuration

Expand Down Expand Up @@ -119,7 +119,7 @@ vendor/bin/phpunit --testsuite=FunctionalTests --testdox --colors=always

## Common Pitfalls

> [!IMPORTANT]
> !IMPORTANT
> Remember:

- Change default OAuth2 client credentials in production.
Expand All @@ -130,4 +130,9 @@ vendor/bin/phpunit --testsuite=FunctionalTests --testdox --colors=always
## Next Steps

Ready to get started?
Jump to the [Installation Guide](https://docs.dotkernel.org/api-documentation/v7/installation/getting-started/) to set up your first Dotkernel API application.

- Jump to the [Installation Guide](https://docs.dotkernel.org/api-documentation/v7/installation/getting-started/) to set up your first Dotkernel API application.
- Learn the [Upgrade Procedure](https://docs.dotkernel.org/api-documentation/v7/upgrading/upgrading/) between different versions of Dotkernel API.
- Check out the [Architecture at a Glance](https://docs.dotkernel.org/api-documentation/v7/architecture-at-a-glance/).
- Review the [Core Features](https://docs.dotkernel.org/api-documentation/v7/core-features/authentication/).
- Run through the [Tutorials](https://docs.dotkernel.org/api-documentation/v7/tutorials/cors/) for step-by-step instructions on how to use Dotkernel API.
2 changes: 0 additions & 2 deletions docs/book/v7/introduction/server-requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ Windows is supported for development via WSL2.
### Production

- Linux (AlmaLinux, Debian)
- BSD (FreeBSD)
- macOS (Intel or Apple Silicon)

### Development

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
| OSS Lifecycle | Archived | ![OSS Lifecycle](https://img.shields.io/osslifecycle?style=flat&label=&file_url=https%3A%2F%2Fgithub.com%2Fdotkernel%2Fapi%2Fblob%2F7.0%2FOSSMETADATA) |
| Style | REST, RPC | REST |
| Versioning | Yes | [Deprecations](https://docs.dotkernel.org/api-documentation/v7/tutorials/api-evolution/) |
| Documentation | Swagger (Automated) | OpenAPI (Swagger) / Postman (Manual) |
| Documentation | Swagger (Automated) | OpenAPI (Swagger) / Bruno (Manual) |
| Content-Negotiation | Custom | Custom |
| License | BSD-3 | MIT |
| Default DB Layer | laminas-db | doctrine-orm |
Expand Down
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ nav:
- Home: index.md
- v7:
- Introduction: v7/introduction/introduction.md
- "Architecture at a Glance": v7/architecture-at-a-glance.md
- Overview:
- "Server Requirements": v7/introduction/server-requirements.md
- "File Structure": v7/introduction/file-structure.md
- "Architecture at a Glance": v7/introduction/architecture-at-a-glance.md
- "Packages": v7/introduction/packages.md
- "PSRs": v7/introduction/psr.md
- Installation:
Expand Down