Skip to content

Commit 00e6a67

Browse files
authored
Merge pull request #108 from Howriq/issue-99
Issue #99: injectable input filters
2 parents 46fa633 + 21f479d commit 00e6a67

File tree

4 files changed

+73
-2
lines changed

4 files changed

+73
-2
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Injectable input filters
2+
3+
In the current version of 6.0, Dotkernel API has an Injectable Input Filter system into the constructors of our handlers.
4+
5+
When building APIs or backend applications in PHP, especially within frameworks that support dependency injection, input validation is a critical concern.
6+
Many developers instinctively instantiate input filters or validators inside their handlers or controllers.
7+
However, injecting input filters is a cleaner, more testable, and flexible approach.
8+
9+
The **previous** version that contained inline instantiation:
10+
11+
```php
12+
public function handle(ServerRequestInterface $request): ResponseInterface
13+
{
14+
$inputFilter = (new CreateAdminInputFilter())->setData((array) $request->getParsedBody());
15+
if (! $inputFilter->isValid()) {
16+
throw (new BadRequestException())->setMessages($inputFilter->getMessages());
17+
}
18+
19+
$admin = $this->adminService->createAdmin($inputFilter->getValues());
20+
21+
return $this->createdResponse($request, $admin);
22+
}
23+
```
24+
25+
While simple, this ties your handler directly to a concrete class. It’s harder to reuse logic across contexts and mock or replace the filter during testing.
26+
27+
Our **current** approach uses constructor injection:
28+
29+
```php
30+
class PostAdminResourceHandler extends AbstractHandler
31+
{
32+
#[Inject(
33+
AdminServiceInterface::class,
34+
CreateAdminInputFilter::class,
35+
)]
36+
public function __construct(
37+
protected AdminServiceInterface $adminService,
38+
protected CreateAdminInputFilter $inputFilter,
39+
) {
40+
}
41+
42+
/**
43+
* @throws BadRequestException
44+
* @throws ConflictException
45+
* @throws NotFoundException
46+
*/
47+
public function handle(ServerRequestInterface $request): ResponseInterface
48+
{
49+
$this->inputFilter->setData((array) $request->getParsedBody());
50+
if (! $this->inputFilter->isValid()) {
51+
throw (new BadRequestException())->setMessages($this->inputFilter->getMessages());
52+
}
53+
54+
$admin = $this->adminService->createAdmin((array) $this->inputFilter->getValues());
55+
56+
return $this->createdResponse($request, $admin);
57+
}
58+
}
59+
```
60+
61+
This new approach makes it trivial to mock the filters during tests:
62+
63+
```php
64+
$mockFilter = $this->createMock(CreateAdminInputFilter::class);
65+
$mockFilter->method('setData')->willReturnSelf();
66+
$mockFilter->method('isValid')->willReturn(true);
67+
68+
$handler = new PostAdminResourceHandler($adminService, $mockFilter);
69+
$response = $handler->handle($request);
70+
```
71+
72+
You're no longer tied to the real filter logic in your handler tests.

docs/book/v6/introduction/file-structure.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ This folder contains all application-related config files:
3131
* `development.config.php.dist` - Activates debug mode; gets symlinked as `development.config.php` when enabling development mode
3232
* `migrations.php` - Configuration for database migration, like migration file location and table to save the migration log
3333
* `pipeline.php` - Contains a list of middlewares, in the order of their execution
34-
* `twig-cs-fixer.php` - Configuration file for Twig code style checker/fixer
3534

3635
### `config/autoload` folder
3736

docs/book/v6/introduction/packages.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
* `mezzio/mezzio-fastroute` - FastRoute integration for Mezzio
2424
* `mezzio/mezzio-hal` - Hypertext Application Language implementation for PHP and PSR-15
2525
* `mezzio/mezzio-problem-details` - Problem Details for PSR-15 HTTP APIs addressing the RFC 7807 standard
26-
* `mezzio/mezzio-twigrenderer` - Twig integration for Mezzio
2726
* `ramsey/uuid-doctrine` - Use ramsey/uuid as a Doctrine field type
2827
* `roave/psr-container-doctrine` - Doctrine Factories for PSR-11 Containers
2928
* `symfony/filesystem` - Provides basic utilities for the filesystem

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ nav:
4242
- "New Handler Structure": v6/extended-features/handler-structure.md
4343
- "Route Grouping": v6/extended-features/route-grouping.md
4444
- "Problem Details": v6/extended-features/problem-details.md
45+
- "Injectable Input Filters": v6/extended-features/injectable-input-filters.md
4546
- Commands:
4647
- "Create admin account": v6/commands/create-admin-account.md
4748
- "Generate database migrations": v6/commands/generate-database-migrations.md

0 commit comments

Comments
 (0)